桌面滚动字幕纯WinSDK无窗体
不知道为啥,研究完网络编程后,我又对DC感兴趣了,昨天我又迷上了“VC实现滚动字幕”,于是昨晚就在网上找了很多类似的源码,但没有一个是我想要的,我试着直接获取整个桌面的DC,然后直接在这个DC句柄上操作,但是没有成功,一气之下关灯睡觉了。今天早上有课,下午没有,于是我就拿了整整一下午的时间来研究,誓要把它搞定。仔细分析了昨晚下的源码,原来高手们都不是直接在桌面DC上操作,而是先建内存DC,在内存DC上操作,然后再将其转换为内存位图,最后再用Bitblt将其Copy到桌面DC上,接下来就不停用TextOut改变文字位置,不停的Copy,这就达到了滚动的效果,这里我没有用Timer而是用了递归(说实话,Win32中的Timer我实在没搞懂,MFC还好说,直接WM_TIMER),不多说了,看代码吧!
BOOL Start(HDC hdc,HDC m_dcmemoryDC,char* szText,int len,LPSIZE s,int width1,LPRECT rect,HBRUSH m_hBrushBackground); //函数声明
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow) //程序入口
{
int width=GetSystemMetrics(0);
SIZE s;
RECT rect;
rect.bottom=40;
rect.left=0;
rect.right=width;
rect.top=0;
HDC hdc=GetDC(0);
char szText[]="诶吆~吉他谁教你的 啊啊~我生下来就会的啊你不知道啊? 中国风的歌曲已传不见";
int len=lstrlen(szText);
HDC m_dcMemoryDC = CreateCompatibleDC(hdc); //创建内存DC
HBITMAP m_hMemoryBitmap = CreateCompatibleBitmap(hdc,width,40); //创建内存Bitmap
SetTextColor( m_dcMemoryDC, RGB(0,255,0) );
SetBkColor( m_dcMemoryDC, RGB(255,0,0) );
SelectObject( m_dcMemoryDC, m_hMemoryBitmap );
HBRUSH m_hBrushBackground = CreateSolidBrush( RGB(255,0,0) );
HFONT m_hFont = CreateFont( 24,0,0,0,FW_BOLD,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH, "黑体" );
SelectObject( m_dcMemoryDC, m_hFont );
GetTextExtentPoint( m_dcMemoryDC, szText, len, &s ); //计算字符串占的像素
Start(hdc,m_dcMemoryDC,szText,len,&s,width,&rect,m_hBrushBackground);
return 0;
}
BOOL Start(HDC hdc,HDC m_dcMemoryDC,char* szText,int len,LPSIZE s,int width1,LPRECT rect,HBRUSH m_hBrushBackground)
{
static int i=0,width=width1,kuandu=width1+s->cx;
FillRect( m_dcMemoryDC,rect, m_hBrushBackground );
SetBkMode( m_dcMemoryDC, TRANSPARENT );
TextOut(m_dcMemoryDC,width-i,10,szText,len);
BitBlt( hdc, 0, 0, width, 40, m_dcMemoryDC, 0, 0, SRCCOPY );
i++;
if(i==kuandu)
{
width=GetSystemMetrics(0);
i=0;
}
//ReleaseDC(NULL,hdc);
//ReleaseDC(NULL,m_dcMemoryDC);//这里我本来想用ReleaseDC来释放内存的,但是不行啊
Sleep(10); //睡眠10毫秒
Start(hdc,m_dcMemoryDC,szText,len,s,width,rect,m_hBrushBackground); //递归
return TRUE;
}
这个程序不能直接结束(这也是我想要的),打开任务管理器,无意中发现它的内存占用在不停增大(下图),靠,内存泄漏!后来我试着用ReleaseDC来释放内存,但实现不了,还请高手出招啊!