为什么消息框没有阻塞线程?

Kem*_*mal 0 c++ winapi multithreading

请考虑以下代码片段,其中WM_TIMER消息上显示消息框.

#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;
}
Run Code Online (Sandbox Code Playgroud)

我希望此代码在初始计时器时显示一个消息框,并阻止该线程,直到用户单击一个按钮.什么实际情况是,一个新的消息框显示在每个时钟滴答,即使用户并没有点击任何按钮.

当我检查线程的调用堆栈时,我看到多个调用DialogProc(),所有调用都在线MessageBox()调用(即所有等待用户输入).

鉴于调用堆栈的状态,它怎么可能DialogProc()不断得到所谓的在同一地方线程MessageBox()没有恢复到最后一次通话DialogProc()

PS请注意,我不是在问如何完成所需的行为.我只是在寻找洞察力,以了解"幕后"发生的事情,从而导致实际行为.

Cal*_*eth 8

MessageBox启动一个新的消息循环,除其他外,它可以DialogProc通过正常的Windows回调机制访问并调用你的.

如果没有这样做那么事件就像WM_PAINT不会被处理,你的应用程序看起来就像死了(除了消息框).由于计时器仍在运行,因此WM_TIMER事件会在适当的时间排队.