Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么线程处理.Net中的模式对话框窗口?_.net_Multithreading_Modal Dialog - Fatal编程技术网

什么线程处理.Net中的模式对话框窗口?

什么线程处理.Net中的模式对话框窗口?,.net,multithreading,modal-dialog,.net,Multithreading,Modal Dialog,我对GUI线程和消息循环有一个相当基本的了解,但我很好奇这如何适用于一个启动模式窗口的窗口。如果我不得不猜测,我会说两个窗口都在同一个GUI线程下运行,并且一些参数指示只执行带有子窗口(模式窗口)的事件,否则将向用户指出模式窗口 这只是一个半受过教育的猜测,我承认我可能从一开始就错了。我甚至不确定“GUI线程”是否是该线程的正确名称,但人们通常可以猜到我在说什么 那么,简言之,线程和模式窗口是如何相处的呢?一个窗口,或者更确切地说是一个窗口的消息,是由创建窗口的线程处理的:调用。这可能是间接的,

我对GUI线程和消息循环有一个相当基本的了解,但我很好奇这如何适用于一个启动模式窗口的窗口。如果我不得不猜测,我会说两个窗口都在同一个GUI线程下运行,并且一些参数指示只执行带有子窗口(模式窗口)的事件,否则将向用户指出模式窗口

这只是一个半受过教育的猜测,我承认我可能从一开始就错了。我甚至不确定“GUI线程”是否是该线程的正确名称,但人们通常可以猜到我在说什么


那么,简言之,线程和模式窗口是如何相处的呢?

一个窗口,或者更确切地说是一个窗口的消息,是由创建窗口的线程处理的:调用。这可能是间接的,在应用程序代码和
CreateWindowEx
API调用之间有软件层,但在创建新窗口时,调用始终存在。

两个窗口保持在同一线程上。该线程——GUI线程——继续处理两个窗口的消息

模态对话框的特殊之处在于:

  • 对话框的所有者设置为主窗口。这会使对话框始终显示在主窗口的顶部

  • 对话框打开时,所有者窗口停止接收用户输入(鼠标和键盘消息)。对话框正常接收用户输入。这是通过禁用所有者窗口实现的,与禁用对话框上的控件的方式相同


    • 这可能是矛盾的,但不,没有为新窗口启动新线程。但是,会打开一个新的消息循环。这样可以保持消息在窗口中流动,并避免停止其他应用程序

      消息将到达并可能被发送到所有者窗口的消息循环。在“所有者”窗口中,键盘和鼠标输入已被禁用,但所有其他消息都将通过发送。Hans Passant的注释:实际上,同一线程的所有顶级窗口都将以这种方式禁用

      作为您在问题中已经提到的一个示例,
      WM_PAINT
      被发送到父窗口。但也包括WMU定时器,例如。像
      WM\u NCHITTEST
      这样的消息将不会被发送,因为它是一条输入消息。
      WM_KEYDOWN
      和类似功能也不会出现

      这样,messagebox可以被移动,底层所有者可以被整齐地重新绘制,或者一个滴答作响的时钟仍然在滴答作响

      部分信息来自第752+页,旧信息,但仍有价值和有效信息。此信息适用于
      DialogBox
      DialogBoxParam
      DialogBoxIndirectParam
      DialogBoxIndirectParam
      以及任何
      .Ex
      版本。在内部,这些Win32 API函数由WinForms调用。

      模式对话框


      要处理模式对话框的消息,系统启动自己的消息循环,临时控制整个应用程序的消息队列。当系统检索到未明确用于对话框的消息时,会将该消息发送到相应的窗口。如果检索到
      WM_QUIT
      消息,它会将消息发回应用程序消息队列,以便应用程序的主消息循环最终能够检索消息。

      打开模式对话框是一个阻塞调用。调用窗口在处理更多事件之前等待模式对话框关闭。@Robert Harvey,当父窗口被阻止时,模式窗口是否在新线程中运行?这对父窗口的事件(如重新绘制)意味着什么?我的理解是,模式对话框仍然在主GUI线程上运行。如果希望在显示模式对话框时在后台进行处理(包括重新绘制主窗体),则必须派生一个新线程,以便后台进程在其中运行。父窗口仍在重新绘制,因此某些事件仍在父窗口上执行。如果在父窗口显示模式窗口时,从第二个线程调用主窗口上的方法,会怎么样?GUI线程会运行调用吗?或者是因为阻塞,在另一个线程中抛出了一个错误?+1有趣而有趣的问题。答案是:没有线程,没有消息循环;-)注意:当然,可以将所有者设置为另一个窗口,例如(初级程序员经常会这样做),桌面。随机附带的问题是,将窗口的所有者设置为桌面是否有好处?我从没听说过这样做,没有好处。缺点是它会破坏窗口。“我从来没有听说过这样做”>>许多免费、廉价或共享软件程序,或从Java或其他窗口移植到Windows的程序都有此问题,当输入焦点被移除时可以注意到,但对话框不可见,除非最小化所有窗口,其中一个窗口将保持在顶部。正如蒂姆所说:根本没有优势。请注意,这种阻塞行为在Vista中发生了变化,在Windows7中也发生了进一步的变化。Apache Monitor工具就是一个例子,当Apache由于错误而无法启动时。对话框的所有者是桌面,窗口隐藏在所有者的后面。听起来不错,我在自己的应用程序中没有遇到这种情况。“旧”-但窗口的这些部分甚至是older@Tim,这是正确的:)我试图找到它的起源,但似乎,没有函数,甚至没有,可以追溯到更远的地方。@Abel,这是一个很好的历史改写:)。MSDN中的版本号可能是min(微软支持的Windows版本,第一个Windows版本函数出现在中)。我应该检查一下我的Windows 3.0版Petzold。@Tim:哈哈,我不是认真的,我只是说Microsoft停止跟踪旧版本的Windows(可能是他们的end-of-support程序的一部分)。+1,这是accu