gpt4 book ai didi

c++ - 如果 MessageBox()/related 是同步的,为什么我的消息循环不卡住?

转载 作者:IT老高 更新时间:2023-10-28 23:18:14 25 4
gpt4 key购买 nike

为什么如果我在消息循环中调用像 MessageBox() 这样看似同步的 Windows 函数,循环本身不会像我调用 Sleep() (或类似的功能)代替?为了说明我的观点,请使用以下骨架 WndProc:

int counter = 0;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
SetTimer(hwnd, 1, 1000, NULL); //start a 1 second timer
break;
case WM_PAINT:
// paint/display counter variable onto window
break;
case WM_TIMER: //occurs every second
counter++;
InvalidateRect(hwnd, NULL, TRUE); //force window to repaint itself
break;
case WM_LBUTTONDOWN: //someone clicks the window
MessageBox(hwnd, "", "", 0);
MessageBeep(MB_OK); //play a sound after MessageBox returns
break;
//default ....
}
return 0;
}

在上面的例子中,程序的主要功能是运行一个定时器并每秒显示一次计数器的值。但是,如果用户单击我们的窗口,程序会显示一个消息框,然后在该框关闭后发出哔哔声。

有趣的地方在于:我们可以看出 MessageBox() 是一个同步函数,因为 MessageBeep() 直到消息框关闭时才会执行。但是,计时器会继续运行,并且即使在显示消息框时也会每秒重新绘制一次窗口。因此,虽然 MessageBox() 显然是一个阻塞函数调用,但仍然可以处理其他消息 (WM_TIMER/WM_PAINT)。没关系,除非我将 MessageBox 替换为另一个阻塞调用,例如 Sleep()

    case WM_LBUTTONDOWN:
Sleep(10000); //wait 10 seconds
MessageBeep(MB_OK);
break;

这完全阻止了我的应用程序,并且在 10 秒内没有发生任何消息处理(WM_TIMER/WM_PAINT 未处理,计数器未更新,程序'卡住'等)。那么为什么 MessageBox() 允许消息处理继续,而 Sleep() 不允许呢?鉴于我的应用程序是单线程的,MessageBox() 做了什么来允许此功能?系统是否“复制”我的应用程序线程,这样它就可以在 MessageBox() 完成后完成 WM_LBUTTONDOWN 代码,同时仍然允许原始线程处理其他消息在过渡期? (这是我没有受过教育的猜测)

提前致谢

最佳答案

MessageBox() 和类似的 Windows API 函数不会像 IO 操作或互斥锁那样阻塞执行。 MessageBox() 函数创建一个对话框,通常带有一个确定按钮——因此您希望自动处理与消息框相关的窗口消息。这是通过它自己的消息循环实现的:没有创建新线程,但您的应用程序保持响应,因为选择的消息(如绘画)是通过递归调用您的 WndProc() 函数来处理的,而其他消息是未传输,因为创建的窗口的模态类型。

Sleep() 和其他函数(当直接从处理窗口消息的 WndProc() 调用时)实际上会阻止单线程消息循环的执行 - 否其他消息将被处理。

关于c++ - 如果 MessageBox()/related 是同步的,为什么我的消息循环不卡住?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1256963/

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