0

我对 WM_PAINT 有疑问。基本上我希望在用户 WM_COMMAND 之后调用 WM_PAINT,但由于某种原因,它无论如何都会在主函数中调用。

 case WM_PAINT:
    {
     createFont();
     PAINTSTRUCT ps;
     HBRUSH hbruzh = CreateSolidBrush(RGB(0,0,0));
     HDC hdz = BeginPaint(hWnd,&ps);
     string s = "Memory Address";

     SelectBrush(hdz,hbruzh);
     SelectFont(hdz,hf);
     TextOut(hdz,0,0,s.c_str(),s.length());
     EndPaint(hWnd,&ps);

     DeleteObject(hbruzh);
     DeleteObject(hdz);

     break;
    }




int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
               LPSTR lpCmdLine, int nCmdShow)
{
    HWND hWnd;
    WNDCLASSEX wc;
    ZeroMemory(&wc, sizeof(WNDCLASSEX));
 hThisInstance = hInstance;
 LoadLibrary("Riched20.dll");

 wc.cbSize = sizeof(WNDCLASSEX);
 wc.style = CS_HREDRAW | CS_VREDRAW;
 wc.lpfnWndProc = WindowProc;
 wc.hInstance = hInstance;
 wc.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU);
 if(!(wc.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_MYICON)))) {
  HRESULT res = GetLastError();

 }
 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
 wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
 wc.lpszClassName = TEXT("Testcpp");
 RegisterClassEx(&wc);

 hWnd = CreateWindowEx(NULL, 
       wc.lpszClassName,
       TEXT("uTest"),
       WS_OVERLAPPEDWINDOW,
       300,
       200,
       450,
       300,
       NULL,
       NULL,
       hInstance,
       NULL);
 ShowWindow(hWnd,nCmdShow);

 MSG msg;
 while (GetMessage(&msg, NULL,0,0)) {
  TranslateMessage(&msg);
  DispatchMessage(&msg);

 }


 return msg.wParam;
}

根据 MSDN,WM_PAINT 仅在 UpdateWindow() 或 ReDrawWindow() 之后,或者当您将其作为消息 SendMessage 时才会自动调用。然而,我什么都不做。我基本上只想在用户交互之后调用 WM_PAINT,而不是之前......有什么办法可以解决这个问题吗?这是什么原因造成的?(我想这是一些奇怪的副作用,我找不到 >.< 的文档)

4

3 回答 3

6

每当您的窗口需要重绘时,都会调用 WM_PAINT。这就是它的用途。显示窗口、调整窗口大小、从最小化状态恢复窗口、在窗口被另一个窗口覆盖后将窗口置于最前面、最小化覆盖窗口的另一个应用程序......这些只是其中的一部分将发送一个 WM_PAINT。

我认为您正在尝试将 WM_PAINT 用于不适合的用途。

于 2010-12-22T21:18:26.703 回答
3

这是什么原因造成的?

我的猜测是,当用户从菜单中选择菜单项时,显示菜单的行为已经覆盖了客户端窗口的一部分。

因此,当菜单最终被删除时,会生成一条 *WM_PAINT* 消息以重新创建客户端窗口的缺失部分。

于 2010-12-23T02:18:33.697 回答
2

根据 MSDN,WM_PAINT 仅在 UpdateWindow() 或 ReDrawWindow() 之后,或者当您将其作为消息 SendMessage 时才会自动调用。

比这更复杂。WM_PAINT 几乎可以随时生成;例如,另见同步和异步绘图

我认为您无法阻止 WM_PAINT。你可以:

  • 强制立即 WM_PAINT(例如通过调用Update
  • 尝试将几种绘画组合/延迟为一种(例如,通过多次调用InvalidateRect

而不是阻止 WM_PAINT,您应该专注于避免/修复您在处理 WM_PAINT 时所说的任何“副作用”。

于 2010-12-22T21:28:31.633 回答