C++ 为什么';t消息框阻止线程?
考虑下面的代码片段,其中在WM_定时器消息上显示消息框C++ 为什么';t消息框阻止线程?,c++,multithreading,winapi,C++,Multithreading,Winapi,考虑下面的代码片段,其中在WM_定时器消息上显示消息框 #define IDT_TIMER1 1001 INT_PTR CALLBACK DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { //... case WM_INITDIALOG: { //... SetTi
#define IDT_TIMER1 1001
INT_PTR CALLBACK DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch(message) {
//...
case WM_INITDIALOG:
{
//...
SetTimer(hWnd, IDT_TIMER1, 1000, (TIMERPROC)NULL);
break;
}
case WM_TIMER:
{
int ret = MessageBox(hWnd, L"Cancel operation?", NULL, MB_YESNO);
if(ret == IDYES) {
EndDialog(hWnd, 0);
} else {
// no-op: keep going
}
break;
}
//...
default:
return FALSE;
}
return FALSE;
}
我希望这段代码在初始计时器滴答声时显示一个消息框,并阻止线程,直到用户单击一个按钮。实际发生的情况是,即使用户没有单击任何按钮,在每个计时器滴答声处都会显示一个新建消息框
当我检查线程的调用堆栈时,我看到对DialogProc()
的多个调用,所有调用MessageBox()
的调用都停留在行上(即所有调用都等待用户输入)
给定调用堆栈的状态,DialogProc()
在DialogProc()
最后一次调用DialogProc()
时,MessageBox()
尚未返回的线程中,如何可能继续被调用DialogProc()
请注意,我不是在问如何实现所期望的行为。我只是想了解“引擎盖下”到底发生了什么导致了实际的行为。
MessageBox
启动了一个新的,除其他外,它可以通过正常的Windows回调机制访问并调用您的DialogProc
如果它没有这样做,那么像
WM_PAINT
这样的事件就不会得到处理,你的应用程序看起来就像已经死掉了一样(除了消息框)。由于计时器仍在运行,WM_timer
事件在适当的时间排队。MessageBox
进入渲染窗口所需的嵌套消息循环,处理按钮
在MessageBox
call中指定为第一个参数的窗口已被EnableWindow
禁用输入,但这并不会禁用所有消息,因此您仍然会收到WM_PAINT、WM_TIMER和其他消息。通常它会禁用用户输入:鼠标、键盘,但也会使用鼠标调整窗口大小
此伪代码显示了MessageBox模拟的潜在实现方式:
int MessageBox( HWND owner_hwnd, ... )
{
...
HWND box_hwnd = CreateWindowEx( ..., owner_hwnd, ... );
...
EnableWindow( owner_hwnd, FALSE );
...
while ( !done )
{
MSG msg;
GetMessage( &msg, ... );
if ( IsDialogMessage( box_hwnd, &msg ) )
continue;
TranslateMessage( &msg );
DispatchMessage( &msg );
}
...
EnableWindow( owner_hwnd, TRUE );
...
DestroyWindow( box_hwnd );
...
return button;
}