处理WM_PAINT

时间:2014-12-16 10:20:23

标签: c winapi wm-paint

我在互联网上阅读了很多例子,但我仍然坚持下去。我正在尝试处理发送到我的应用程序的WM_PAINT消息。

在我的应用程序中,我总是在同一个DC中绘制,名为g_hDC。它完美地运作。收到WM_PAINT后,我只是尝试将g_hDC的内容绘制到BeginPaint返回的DC中。我猜g_hDC包含我绘制的最后一个位图。所以我只想恢复它。

case WM_PAINT:
 PAINTSTRUCT ps;

 int ret;
 HDC compatDC;
 HDC currentDC;
 HDC paintDC;
 HBITMAP compatBitmap;
 HGDIOBJ oldBitmap;

 paintDC   = BeginPaint(g_hWnd, &ps);

 currentDC = GetDC(g_hWnd);
 compatDC  = CreateCompatibleDC(paintDC);
 compatBitmap=CreateCompatibleBitmap(paintDC, CONFIG_WINDOW_WIDTH, CONFIG_WINDOW_HEIGHT);
 oldBitmap=SelectObject(compatDC, compatBitmap);

 ret = BitBlt(compatDC,
              ps.rcPaint.left,
              ps.rcPaint.top,
              ps.rcPaint.right - ps.rcPaint.left,
              ps.rcPaint.bottom - ps.rcPaint.top,
              currentDC,
              ps.rcPaint.left,
              ps.rcPaint.top,
              SRCCOPY);

 ret = BitBlt(paintDC,
              ps.rcPaint.left,
              ps.rcPaint.top,
              ps.rcPaint.right - ps.rcPaint.left,
              ps.rcPaint.bottom - ps.rcPaint.top,
              compatDC,
              ps.rcPaint.left,
              ps.rcPaint.top,
              SRCCOPY);

  DeleteObject(SelectObject(compatDC, oldBitmap));
  DeleteDC(compatDC);
 DeleteDC(currentDC);

 EndPaint(g_hWnd, &ps);

中断;

但它只画了一个白色的矩形......我尝试了很多可能性,没有任何作用。你能帮我吗?

2 个答案:

答案 0 :(得分:1)

有很多事情你做错了。

首先,您的保存g_hDC依赖于实现细节:您注意到指针是相同的,因此保存指针。由于与GDI部分优化相关的各种原因(例如,有DC cache),这可能在短期内起作用,但最终会停止工作 最方便的。或者,当你没有DC时,你可能会想要使用DC指针,并且会因为GDI对象线程亲和力而乱写其他东西(或者没有这样做)。

访问WM_PAINT之外的窗口的DC的正确方法是致电GetDC(hwnd)

CreateCompatibleDC()创建与hdc兼容的内存中DC。绘制到compatDC不足以吸引hdc;在绘制到hdc后,您需要退回到compatDC。对于您的情况,您需要进行两次BitBlt()次呼叫;第二个将从compatDC回到hdcSee this sample code for details.

当您将位图选入DC时,不能DeleteObject()位图。您的SelectObject(compatDC, oldBitmap)来电需要在 DeleteObject(compatBitmap)之前来。 (这就是i486在他的回答中试图得到的。)

(我确定这个答案在某些地方有误导或不完整;如果有,请告诉我。)

答案 1 :(得分:0)

使用此选项删除bitmat:DeleteObject( SelectObject(compatDC,oldBitmap) ); - 在prev行上没有DeleteBitmap。 SelectObject将当前(旧)选择作为返回值返回 - 然后将其删除。在您的情况下,您尝试删除仍然选择的位图。

PS:我没有看到CreateCompatibleDC - 你在哪里创建compatDC?在compatDC = CreateCompatibleDC( hdc );之前添加CreateCompatibleBitmap