WM_PAINT 绘制后不显示

发布于 2024-12-08 04:44:26 字数 1529 浏览 0 评论 0原文

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

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);
更新了我的示例代码来表示这一点。

So i'm painting a bitmap, heres my code:

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);

Sometimes, when I paint it with this code, the bitmap is not displayed. Although if i minimize/unminimize the window, the bitmap is displayed. I'm pretty sure there's no problems with my code so is there something else I should be doing?

EDIT:
Turns out it's not just bitmaps, if I draw text with TextOut sometimes it's not displayed until its minimized/unminimized. I don't think minimizing/unminimizing sends another WM_PAINT message, so I don't think that when i do that it's causing it to be repainted correctly.

Oh and the rest of the controls get painted normally, just the stuff inside WM_PAINT isn't painted.

UPDATE
Here's the code thats causing the problems, it works 98% of the time too.


// 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:
Another important detail could be, in my actual application, this code is inside a if statement that checks a global variable, and paints if its true. And this variable is set from a different thread, and after the variable is set I call InvalidateRect(hMainWnd, NULL, TRUE);
Updated my example code to represent this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

治碍 2024-12-15 04:44:26

此代码片段立即不好的地方(您实际上应该发布更多详细信息)是您删除了临时 DC,而全局位图句柄仍处于选中状态。您需要再次执行 SelectObject 来取消选择位图。

通常你会这样做:

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

另外,错误检查也没什么坏处。可能其中一个 API 调用失败,具体是哪一个 API 调用很重要,因为它可以更清楚地说明问题。

What is immediately not good with this code snippet (you actually should rather have posted more details) is that you delete temporary DC with your global bitmap handle still selected into it. You need to do SelectObject once again to unselect your bitmap.

You normally do it like this:

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

Also, error checking never hurts. Possibly one of the API calls fail and it's important which one exactly as it sheds more light on the issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文