双缓存窗口重绘问题。。。大侠们帮忙看一看吧。。。
c++ API窗口重绘问题,用了双缓冲,虽然不再闪频,但是很多新问题出现了。。。
第一是CPU占用很高,几乎到了70%-80%
第二就是文字、线条等等设置了颜色却无显示,一律为黑色。。。
源码如下。。。
#include <iostream>#include <Windows.h>#include <WinDef.h>//辅助绘制函数void Text (HDC &hdc, int x, int y, LPCWSTR ps_string, int color){ SetTextColor(hdc, color); TextOut (hdc, x, y, ps_string, lstrlen(ps_string)); SetTextColor(hdc, 0);}void Line (HDC &hdc, int xBeg, int yBeg, int xEnd, int yEnd, int color){ HPEN hPen; hPen = CreatePen(PS_SOLID, 0, color); SelectObject(hdc, hPen); MoveToEx (hdc, xBeg, yBeg, NULL); LineTo (hdc ,xEnd, yEnd); DeleteObject(hPen);}void FRect(HDC &hdc, RECT* re, HBRUSH hBrush){ SelectObject(hdc, hBrush); FillRect(hdc, re, hBrush);}class Mag{public: HWND hwnd; MSG msg; RECT winRect; HDC dc; //主DC HDC bgdc; //缓存DC HBRUSH bgbrush; HBITMAP bgimg; void flush(); //重绘函数 void Init(); //初始化函数 LRESULT keys(HWND &hwnd, UINT &msg, WPARAM &wparam, LPARAM &lparam); //消息处理函数};void Mag::Init(){ this->bgbrush = CreateSolidBrush(0xffffff); this->dc = GetDC(this->hwnd); this->bgdc = CreateCompatibleDC(this->dc); this->bgimg = CreateCompatibleBitmap(this->bgdc, this->width ,this->height); SelectObject(this->bgdc, this->bgbrush); SelectObject(this->bgdc, this->bgimg);}void Mag::flush(){ //在缓存DC上绘制 FRect(this->bgdc, &this->winRect, this->bgbrush); Line(this->bgdc, 0, 1, 100, 1, 0x595ade); //这里,绘制的颜色设定了非黑色,但实际绘制出来的还是黑色 Line(this->bgdc, 0, 10, 100, 10, 0x195ade); //这里也是 Text(this->bgdc, 10, 30, TEXT("测试文本"), RGB(120,50,160) ); //这里也是 //在主DC上绘制 BitBlt (this->mag->dc, 0, 0, this->mag->width, this->mag->height, this->mag->bgdc, 0, 0, SRCCOPY);}LRESULT Mag::keys(HWND &hwnd, UINT &msg, WPARAM &wparam, LPARAM &lparam){ switch (msg) { case WM_PAINT: this->flush(); return 0; case WM_CLOSE: DestroyWindow(hwnd); return 0; case WM_DESTROY: { PostQuitMessage (0); return 0; } default: return DefWindowProc (hwnd, msg, wparam, lparam); }}//创建Mag类Mag mag = Mag()//创建窗口//消息处理主函数LRESULT Mag::keys(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam){ return mag.body->keys(hwnd, msg, wparam, lparam);}int WINAPI WinMain(......){//省去一堆创建窗口的代码mag.Init(); //主动初始化ShowWindow (mag.hwnd, iCmdShow);UpdateWindow(mag.hwnd);while (GetMessage(&mag.msg, NULL, 0, 0) ) { TranslateMessage (&mag.msg); DispatchMessage (&mag.msg); UpdateWindow(mag.hwnd); }return mag.msg.wParam;}//源码结束
}
Init 函数中
this->bgimg = CreateCompatibleBitmap(this->bgdc, this->width ,this->height);
这一句CreateCompatibleBitmap的第一个参数应为 this->dc,不是bgdc。
另外你mag类中初始化创建的资源应在析构时释放 不知道是不是你代码省略了。。。。。。等等
最后你的 内存DC和兼容位图等恐怕得每次重画的时候重新创建
[解决办法]
验证了4楼的说法
this->bgimg = CreateCompatibleBitmap(this->dc, this->width ,this->height);
果然紫色字体可以显示了。
但 BeginPaint函数 不一定使用;
参考 VC绘制位图--BeginPaint()与GetDC()的区别和双缓冲 http://blog.csdn.net/liuxingbin/article/details/5635902