gpt4 book ai didi

c - WM_TIMER 在特定条件下丢失

转载 作者:行者123 更新时间:2023-11-30 18:24:07 29 4
gpt4 key购买 nike

#include <windows.h>
#include <stdio.h>

class tWnd {
private:
static LRESULT CALLBACK Disp_test_WndProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam) // second message parameter
{
switch (uMsg)
{
case WM_TIMER:{
printf("timer\n");

return 0;
}

case WM_PAINT:
// Paint the window's client area.
return 0;

case WM_DESTROY:
return 0;

case WM_HOTKEY:{

} return 0;
//
// Process other messages.
//
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}

public:
tWnd() {

WNDCLASSA wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) Disp_test_WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) NULL;
wc.lpszMenuName = "";
wc.lpszClassName = "Test";

if (!RegisterClass(&wc))
return; //cannot register window class



HWND testingWindow = CreateWindowEx(WS_EX_TOPMOST,"Test","topmost",WS_VISIBLE,0,0,200,200,0,0,0,0);

SetTimer(testingWindow,101,500,(TIMERPROC)NULL);

MSG recent;
BOOL result;
while((result=GetMessage(&recent,testingWindow,0,0))&&result!=-1) { //bool can be -1 in MS world
if(recent.message==WM_USER+1) break;
TranslateMessage(&recent);
DispatchMessage(&recent);
}
}
};

int main(int argc, char **argv)
{
tWnd();
return 0;
}

此代码永远不会收到 WM_TIMER 消息。

#include <windows.h>
#include <stdio.h>

class tWnd {
private:
static LRESULT CALLBACK Disp_test_WndProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam) // second message parameter
{
switch (uMsg)
{
case WM_TIMER:{
printf("timer\n");

return 0;
}

case WM_DESTROY:
return 0;

case WM_HOTKEY:{

} return 0;
//
// Process other messages.
//
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}

public:
tWnd() {

WNDCLASSA wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) Disp_test_WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) NULL;
wc.lpszMenuName = "";
wc.lpszClassName = "Test";

if (!RegisterClass(&wc))
return; //cannot register window class



HWND testingWindow = CreateWindowEx(WS_EX_TOPMOST,"Test","topmost",WS_VISIBLE,0,0,200,200,0,0,0,0);

SetTimer(testingWindow,101,500,(TIMERPROC)NULL);

MSG recent;
BOOL result;
while((result=GetMessage(&recent,testingWindow,0,0))&&result!=-1) { //bool can be -1 in MS world
if(recent.message==WM_USER+1) break;
TranslateMessage(&recent);
DispatchMessage(&recent);
}
}
};

int main(int argc, char **argv)
{
tWnd();
return 0;
}

此代码可以很好地获取 WM_TIMER 消息。

两者之间的唯一区别是 WM_PAINT 消息在第二种变体中是默认处理的。为什么处理 WM_PAINT 会阻止程序接收 WM_TIMER 消息?我该如何解决这个问题?

如果重要的话,我正在使用 MingW w64 (GCC 5.3.0)。

最佳答案

当窗口的无效区域非空时,它会收到 WM_PAINT 消息。 ValidateRect() 的文档中对此进行了说明。 :

The system continues to generate WM_PAINT messages until the current update region is validated.

标准 WM_PAINT 处理程序会验证无效区域(例如通过调用 BeginPaint() ),默认实现会这样做。简单地返回 0 不会验证窗口,并且它会继续接收 WM_PAINT 消息。

WM_TIMER 消息的优先级低于 WM_PAINT 消息。您的窗口消息处理程序永远不会看到计时器消息,因为它一直忙于忽略绘制消息。 WM_TIMER 的文档中对此进行了说明。 :

The WM_TIMER message is a low-priority message. The GetMessage and PeekMessage functions post this message only when no other higher-priority messages are in the thread's message queue.

关于c - WM_TIMER 在特定条件下丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44375712/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com