【问题标题】:WM_PAINT doesn't show up after painting绘画后 WM_PAINT 不显示
【发布时间】:2011-10-03 18:00:46
【问题描述】:

所以我正在画一个位图,这是我的代码:

hdcMem = CreateCompatibleDC(hdc);

SelectObject(hdcMem, g_hBitmap);
GetObject(g_hBitmap, sizeof(bm), &bm);

BitBlt(hdc, 196 - (bm.bmWidth/2), 90, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);

DeleteDC(hdcMem);

有时,当我用这段代码绘制它时,位图不显示。尽管如果我最小化/取消最小化窗口,则会显示位图。我很确定我的代码没有问题,所以我还应该做些什么吗?

编辑
原来它不仅仅是位图,如果我用TextOut 绘制文本,有时它直到最小化/未最小化才会显示。我不认为最小化/取消最小化会发送另一个 WM_PAINT 消息,所以我不认为当我这样做时会导致它被正确重绘。

哦,其余控件正常绘制,只是 WM_PAINT 中的东西没有绘制。

更新
这是导致问题的代码,它在 98% 的时间里也能正常工作。


// This is a global variable
bool GlobalVar = false;

// This is a different thread started with _beginthread
void ThreadExample()
{
    GlobalVar = true;
    InvalidateRect(hMainWnd, NULL, TRUE);
    _endthread();
}

case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);

    if (GlobalVar == true)
    {
        SetBkMode(hdc, TRANSPARENT);
        SetTextColor(hdc, 0x0000ff);

        OrigFont = SelectObject(hdc, g_hLargeFont);

        GetTextExtentPoint32(hdc, ErrorMsg, lstrlen(ErrorMsg), &sz);
        TextOut(hdc, 196 - (sz.cx/2), 100, ErrorMsg, lstrlen(ErrorMsg));

        SelectObject(hdc, OrigFont);
    }

    EndPaint(hWnd, &ps);
    break;

EDIT2:
另一个重要的细节可能是,在我的实际应用程序中,此代码位于检查全局变量并绘制的 if 语句中如果它是真的。这个变量是从不同的线程设置的,设置变量后我调用InvalidateRect(hMainWnd, NULL, TRUE);
更新了我的示例代码来表示这一点。

【问题讨论】:

  • 请告诉我们这段代码在哪里。我希望它在 WM_PAINT 处理程序中,并且 hdc 来自 BeginPaint。
  • @DavidHeffernan 是的,它在 WM_PAINT 内部,并且 hdc 确实来自 BeginPAint。
  • 您的编辑没有帮助。最小的复制将。
  • 你忘了提到线程!
  • 哦,GlobalVar 缺乏同步也不好。

标签: c windows api bitmap paint


【解决方案1】:

此代码 sn-p 的缺点是(您实际上应该发布更多详细信息)是您删除临时 DC 时仍选择了全局位图句柄。您需要再次执行SelectObject 以取消选择您的位图。

你通常这样做:

HGDIOBJ hPreviousBitmap = SelectObject(hdcMem, g_hBitmap);
// ...
SelectObject(hdcMem, hPreviousBitmap);

此外,错误检查永远不会受到伤害。可能其中一个 API 调用失败了,重要的是哪个 API 调用更能说明问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多