我有以下代码,应该在用户调用项目 ID_FILE_32771
后绘制 picture2.bmp
。
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case ID_FILE_32771:
hdc = BeginPaint(hWnd, &ps);
LoadAndBlitBitmap2(__T("D://picture2.bmp"), hdc);
EndPaint(hWnd, &ps);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
LoadAndBlitBitmap(__T("D://picture.bmp"), hdc);
EndPaint(hWnd, &ps);
break;
问题是,什么都没有画。 hdc
未正确初始化。我做错了什么,我该如何解决?
最佳答案
BeginPaint
和 EndPaint
函数仅在您处理 WM_PAINT
消息。您在处理 WM_COMMAND
时的处理方式是错误的:
case ID_FILE_32771:
hdc = BeginPaint(hWnd, &ps); // WRONG, WRONG!
LoadAndBlitBitmap2(__T("D://picture2.bmp"), hdc);
EndPaint(hWnd, &ps); // ALSO WRONG!
break;
所有 绘画代码都需要在WM_PAINT
处理程序中。每当您的窗口需要绘制时,您将收到 WM_PAINT
消息,有时这是您无法控制的。因此,WM_PAINT
处理程序中需要有逻辑,根据应用程序的当前状态知道要绘制什么。
换句话说,您需要设置一个标志以响应对 ID_FILE_32771
的点击,以便您的程序知道它应该在重新绘制自身时调用 LoadAndBlitBitmap2
,而不是LoadAndBlitBitmap
(为什么它们不是相同的函数,您只需向其传递不同的文件名?)。
在 WM_PAINT
处理程序之外,您可以通过使窗口内容无效来触发绘制事件。最简单和最普遍适用的方法是调用 InvalidateRect
function .例如:
case ID_FILE_32771:
// Set a flag indicating that picture2 should be painted
// (or some other equivalent mechanism)
paintPicture2 = true;
// Signal that the window should be repainted.
InvalidateRect(hWnd, NULL, TRUE);
break;
调用 UpdateWindow
在 InvalidateRect
之后,您将强制立即 重绘,但这很少是必要的。或者,您可以跳过双功能舞蹈并调用更强大的 RedrawWindow
function直接。
无论哪种方式,您都将调用您的 WM_PAINT
消息处理程序,它将查询应用程序的当前状态并绘制适当的图片。
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// Paint the appropriate thing, depending on the app's current state
if (paintPicture2)
LoadAndBlitBitmap(__T("D://picture.bmp"), hdc);
else
LoadAndBlitBitmap(__T("D://picture.bmp"), hdc);
EndPaint(hWnd, &ps);
break;
关于c - 绘画代码在我的 WM_COMMAND 消息处理程序中无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23855888/