Winapi 在先前发送的消息回调完成之前触发消息时会发生什么情况?
我花了一些时间试图研究一个明确的答案,但找不到可靠的来源 我的设想相当简单。我有一个带有消息泵设置的线程,它正在处理来自计时器的重复事件。以下是消息来源:Winapi 在先前发送的消息回调完成之前触发消息时会发生什么情况?,winapi,win32gui,Winapi,Win32gui,我花了一些时间试图研究一个明确的答案,但找不到可靠的来源 我的设想相当简单。我有一个带有消息泵设置的线程,它正在处理来自计时器的重复事件。以下是消息来源: // create timer that goes off every 500 ms UINT_PTR myTimerID = SetTimer(NULL, 0, 500, TimerCallback); // message structure MSG msg; // process and handle messages for th
// create timer that goes off every 500 ms
UINT_PTR myTimerID = SetTimer(NULL, 0, 500, TimerCallback);
// message structure
MSG msg;
// process and handle messages for this thread
BOOL getMessageStatus;
while((getMessageStatus = GetMessage(&msg, NULL, 0, 0)) != 0)
{
// failed get message
if(getMessageStatus == -1)
{
printf("GetMessage FAILED!\n");
}
// process timer message
else if(msg.message == WM_TIMER)
{
// invoke callback
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
如果TimerCallback花费的时间超过500毫秒,则计时器将再次触发其事件。由于回调与消息泵在同一线程上执行,因此我假设回调必须在消息泵处理下一条计时器消息之前完成
正确吗?只要只有一个用于处理消息的入口点,一次只能处理一条消息。通过在已经运行的事件处理程序中处理更多消息,您可能会把事情搞砸,但不要这样做,您应该会没事。只要处理消息只有一个入口点,一次只能处理一条消息。通过在已经运行的事件处理程序中处理更多消息,您可能会把事情搞砸,但不要这样做,您应该会没事。
SetTimer()
是一个基于消息的计时器。当计时器过期时,它会在消息队列中设置一个特殊标志。当您为新消息抽取队列时,如果已设置该标志且队列中没有其他更高优先级的消息等待,则将创建一条WM_TIMER
消息。当您的代码正忙于调度生成的WM\u TIMER
消息时,计时器可以在后台消失并再次设置标志,在您下次为消息抽取队列时生成新的WM\u TIMER
消息。因此,在回调内部直接或通过模式对话框泵送消息时要小心,因为这可能会导致计时器回调的递归调用,从而随着时间的推移可能导致堆栈溢出。但是,如果您的消息泵送仅在主线程循环中,那么您就不会有问题。SetTimer()
是一种基于消息的计时器。当计时器过期时,它会在消息队列中设置一个特殊标志。当您为新消息抽取队列时,如果已设置该标志且队列中没有其他更高优先级的消息等待,则将创建一条WM_TIMER
消息。当您的代码正忙于调度生成的WM\u TIMER
消息时,计时器可以在后台消失并再次设置标志,在您下次为消息抽取队列时生成新的WM\u TIMER
消息。因此,在回调内部直接或通过模式对话框泵送消息时要小心,因为这可能会导致计时器回调的递归调用,从而随着时间的推移可能导致堆栈溢出。但是,如果您的消息泵送仅在主线程循环中,那么您就没事了