所以我正在绘制位图,这是我的代码:
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);
更新了我的示例代码来表示这一点。
最佳答案
此代码片段的缺点(实际上您应该发布更多详细信息)是您在删除临时 DC 时仍然选择了全局位图句柄。您需要再次执行 SelectObject
以取消选择您的位图。
你通常这样做:
HGDIOBJ hPreviousBitmap = SelectObject(hdcMem, g_hBitmap);
// ...
SelectObject(hdcMem, hPreviousBitmap);
此外,错误检查永远不会有坏处。可能有一个 API 调用失败了,重要的是哪一个 API 调用能更清楚地说明问题。
关于c - 绘画后 WM_PAINT 不显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7638796/