【问题标题】:GetDC vs BeginPaint performance considerationsGetDC 与 BeginPaint 性能注意事项
【发布时间】:2012-08-22 14:51:55
【问题描述】:

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 来清除更新区域,但将绘图委托给先前创建的对象。

【问题讨论】:

    标签: winapi gdi+ gdi wm-paint


    【解决方案1】:

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

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

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

    创建 HDC 非常便宜,需要时创建。更不用说 PAINTSTRUCT.hdc 了,您将在盘子上享用,随时可以使用。

    【讨论】:

      猜你喜欢
      • 2011-08-16
      • 2016-07-02
      • 2010-11-01
      • 1970-01-01
      • 2011-07-09
      • 2017-01-24
      • 1970-01-01
      • 2017-11-03
      • 1970-01-01
      相关资源
      最近更新 更多