3

MSDN 和许多帖子都建议在 WM_PAINT 中使用 BeginPaint/EndPaint。我还看到很多地方表明如果在绘画中使用双缓冲,那么在 WM_CREATE 中初始化 DC 和内存分配并在 WM_PAINT 中重用这些句柄会更有意义。

例如,使用 BeginPaint,我通常会看到:

case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
MemDC = CreateCompatibleDC(hdc);
bmp = CreateCompatibleBitmap(hdc, width, height);
oldbmp = SelectObject(MemDC,bmp);
g = new Graphics(MemDC);

//do paint on bmp
//blt bmp back to hdc

EndPaint(hWnd, &ps);
DeleteObject(bmp);
g->ReleaseHDC(MemDC);
DeleteDC(MemDC);
delete g;

为了保存初始化和拆除,是否可以这样做:

case WM_CREATE:
hdc   = GetDC(hWnd);
//create memDC and graphics object references ...
case WM_DESTROY
//delete memDC and graphics object references...
case WM_PAINT
BeginPaint(hWnd, &ps);
//use previously create mem and graphics object to paint 
EndPaint(hWnd, &ps);

所以我们只使用 EndPaint 来清除更新区域,但将绘图委托给先前创建的对象。

4

1 回答 1

6

不,这是一个非常糟糕的做法。这首先是由于设备上下文具有错误的剪辑区域而出错,当用户调整窗口大小时,您无法正确绘制窗口。

第二个问题是更新区域裁剪不会生效,PAINTSTRUCT.rcPaint。当更新区域只是窗口的一部分时,防止 Windows 可能自动执行的任何可能的绘制优化。

第三个问题是您不必要地持有操作系统资源。所有 GDI 对象都分配在单个堆中,该堆由运行在同一桌面上的所有进程共享。

创建 HDC 非常便宜,需要时创建。更不用说 PAINTSTRUCT.hdc 了,你会得到一个盘子,随时可以使用。

于 2012-08-28T06:11:08.830 回答