如果使用WM_PAINT样式创建 Window,则永远不会传递WS_POPUP消息

WM_PAINT message is never delivered if Window is created with WS_POPUP style

本文关键字:永远 POPUP WS 消息 WM PAINT 样式 Window 创建 如果      更新时间:2023-10-16

我正在尝试使用"WS_POPUP">样式创建一个没有标题栏的窗口,我还需要在边框上进行一些绘画。

当我收到">WM_PAINT">消息时,我正在"WndProc">中实现我的绘图逻辑。但是,它从未交付。

我尝试过弄乱样式,但每当使用WS_POPUP样式时,WM_PAINT永远不会始终如一地交付。

当您使用 Visual Studio Community 2019 创建新的"Windows 桌面应用程序"项目时,这是从自动生成的代码中复制的,仅更改了一件事:

WS_OVERLAPPEDWINDOW --> WS_POPUP

创建窗口:

HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_POPUP | WS_VISIBLE,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

注册窗口类:

WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style          = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc    = WndProc;
wcex.cbClsExtra     = 0;
wcex.cbWndExtra     = 0;
wcex.hInstance      = hInstance;
wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT2));
wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT2);
wcex.lpszClassName  = szWindowClass;
wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);

消息循环:

while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

进程窗口消息:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
PAINTSTRUCT ps; // NEVER CALLED !!!
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code that uses hdc here...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

我希望传递WM_PAINT的信息,这样我就可以画一些画。但是,它从未交付。

如果您修改 CreateWindow 调用,您将在启动时收到一个 WM_PAINT 事件,如下所示:

HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_POPUP | WS_VISIBLE, 
0, 0, 800, 600, nullptr, nullptr, hInstance, nullptr);

您只需要放置一些有效的宽度和高度。 不过,下次您会收到WM_PAINT时,将是当您使窗口失效时。 或者,例如,如果您单击"显示桌面"按钮(右下角)并恢复窗口(从最小化恢复)。 请注意,当您的窗口重新获得焦点(alt-tab)时,您不会收到WM_PAINT,除非您使它失效,如下所示:

case WM_ACTIVATE:
InvalidateRect(hWnd, NULL, TRUE);
break;