【问题标题】:Processing WM_PAINT处理 WM_PAINT
【发布时间】:2015-02-14 15:01:27
【问题描述】:

我在互联网上阅读了很多例子,但我仍然卡住了。我正在尝试处理发送到我的应用程序的 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);

休息;

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

【问题讨论】:

  • c++ 标签不正确。将其更改为 Win32。
  • 您还没有在 compatBitmap 中绘制任何东西 - 您希望在 BitBlt 之后看到什么?假设必须有“噪声”,即随机图像。
  • 我删除了 c++ 标签。我只是在重叠窗口的位置看到一个白色矩形。
  • 我想你会看到没有 BitBlt 的相同的白色矩形 - 这是正常的背景擦除(白色)。
  • 你在任何时候都不会进入BeginPaint返回的DC。

标签: c winapi wm-paint


【解决方案1】:

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

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

【讨论】:

  • 感谢您的回复。我在第一篇文章中编辑了代码。它仍然不起作用。 (请注意,我现在将 BitBlt 转换为 compatDC 而不是 hdc)。问题是我不明白我在做什么。这对我来说不合逻辑。为什么我应该创建一个 compatibleDc 以便 BeginPaint 已经给了我一个 DC ??
  • DC-s 的想法很奇怪。我已经使用了多年,但仍然无法完全理解这个想法——但这就是工作的方法。 DC 是您绘制的对象 - 类似于虚拟显示器。可以是真实显示器,可以是内存虚拟显示器,可以是打印机表面。我不确定您的 g_hDC 是否包含有效位图并与 hdc/compatDC 兼容。如果你 BitBlt 从 g_hDC 到 compatDC,你将需要额外的 BitBlt 将图像从 compatDC 传输到 hdc(真实显示)。试试这个BitBlt(hdc,0,0,rect.right,rect.bottom,compatDC,0,0,SRCCOPY);
【解决方案2】:

你做错了很多事情。

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

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

CreateCompatibleDC() 创建一个与hdc 兼容的内存中 DC。画到compatDC不够画到hdc;拉到compatDC 后,您需要拉回hdc。对于您的情况,您需要拨打两个 BitBlt() 电话;第二个将从compatDC 回传到hdcSee this sample code for details.

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

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

【讨论】:

  • 感谢您的回答。我尝试了第二个 BitBlt,得到了相同的结果。一个白色的长方形。我还尝试了您提供的代码示例。结果相同。
  • 我用我目前正在测试的代码编辑了我的第一篇文章。我还有白色矩形。
猜你喜欢
  • 2011-11-03
  • 1970-01-01
  • 2013-11-13
  • 1970-01-01
  • 2016-03-28
  • 2016-01-15
  • 2020-02-18
  • 2018-11-10
  • 1970-01-01
相关资源
最近更新 更多