#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;
}
Run Code Online (Sandbox Code Playgroud)
此代码永远不会获得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;
}
Run Code Online (Sandbox Code Playgroud)
这段代码很好地获取了WM_TIMER消息.
两者之间的唯一区别是WM_PAINT消息在第二个变体中是默认处理的.为什么要处理WM_PAINT会阻止程序接收WM_TIMER消息?我该如何解决这个问题?
如果重要的话,我正在使用MingW w64(GCC 5.3.0).
窗口WM_PAINT在其无效区域非空时接收消息.这在文档中称为ValidateRect():
系统继续生成WM_PAINT消息,直到验证当前更新区域.
标准WM_PAINT处理程序验证无效区域(例如通过调用BeginPaint()),默认实现执行此操作.简单地返回0将不会验证窗口,并继续接收WM_PAINT消息.
WM_TIMER消息的优先级低于WM_PAINT消息.您的窗口过程永远不会看到计时器消息,因为它一直忙于忽略绘制消息.这在文档中称为WM_TIMER:
该
WM_TIMER消息是低优先级消息.仅当线程的消息队列中没有其他更高优先级的消息时,GetMessage和PeekMessage函数才会发布此消息.