【问题标题】:Window procedure and CreateWindowEx function窗口过程和 CreateWindowEx 函数
【发布时间】:2026-02-17 02:20:03
【问题描述】:

注册时窗口类指定为lpfnWndProc的窗口过程是否在单独的线程中运行?

【问题讨论】:

  • 您的第一个问题太宽泛了。 “真正有效”是什么意思,真的吗?我建议你edit这个问题只问一个具体的问题。
  • 使用特定问题引用此(或类似内容) - docs.microsoft.com/en-us/windows/win32/learnwin32/… 在问题中包含问题的代码。
  • @DrewDormann。我已经删除了问题中非常“一般/广泛”的部分。我真的很想知道window procedure 是在主线程还是单独线程中运行...
  • "...在单独的线程中运行?" - 不 - 它运行在与您调用 CreateWindowEx 相同的线程上。另见*.com/questions/4347404/…
  • @RichardCritten,好的。谢谢:-)

标签: c++ windows winapi


【解决方案1】:

windows中有一个重要的概念叫做message loop

它通常在主函数(又名:WinMain)内部,可以通过以下方式表征:

while (true) {
  // blocks until there's a new message to process
  GetMessage()
  TranslateMessage()
  // ends up calling the propper WndProc callback
  DispatchMessage()
}

更新:当您创建窗口时,创建窗口的线程拥有窗口(及其消息队列)。因此,它必须提供消息循环过程。这通常在应用程序的主线程中完成,但正如其他用户所说,它也可以在单独的线程中完成。

函数DispatchMessage负责执行消息所针对的窗口的WindowProc过程(由消息的hwnd参数指定)。

因此,当您创建一个窗口时,lpfnWndProc 参数指定您希望在哪里收到事件通知(鼠标单击、键盘按下等)。它总是在同一个线程(应用程序的主线程或拥有窗口的线程)中调用。

忠告:如果您需要执行一个可能很长的操作作为事件的结果,您必须为该任务创建一个新线程(也称为后台工作者),并执行某种当函数完成时,IPC 通知主线程。

您可以找到有关如何编写 Windows 程序 here 的说明。此外,wikipedia page 中还有一些关于主循环的信息。

【讨论】:

  • DispatchMessageposted 消息调用窗口过程。 Sent 消息从SendMessage 内部(如果从拥有窗口的线程调用)或从GetMessage() 内部调用窗口过程(并且它不会返回到消息循环)跨度>
  • 这几乎遗漏了每一个重要的细节,并且做出了非常误导性的陈述。没有“主线程”这样的东西。有一个“主线程”,但这并不特别。是对CreateWindow 的调用建立了窗口的线程亲缘关系并定义了要在其上调用窗口过程的线程。坦率地说,这听起来就像你在没有消化课程的情况下反刍所教的内容。这不应该是公认的答案。
【解决方案2】:

在注册期间由窗口类指定为lpfnWndProc的窗口过程是否在单独的线程中运行?

不,当您的消息循环调度事件(又名消息)时,它会被调用(作为回调)。通过这种方式 - 所谓的“事件驱动”模型 - 您的程序能够在用户输入发生时对其做出反应,而无需处理任何多线程或重入问题。

您可能有多个线程,但如果它有与之关联的窗口(即CreateWindowEx 被该线程调用),那么它需要有自己的消息循环。

【讨论】:

  • 窗口过程可重入的。这就是 STA 不够好的全部原因,我们不得不发明 ASTA