【问题标题】:Should every VCL form has its own message loop/pump for threading?每个 VCL 表单都应该有自己的消息循环/泵用于线程吗?
【发布时间】:2011-03-12 18:02:54
【问题描述】:

我正在尝试在我的最新项目中实现 MVP 模式。目前使用 C++ Builder 2007 附带的 VCL 库。我的想法是我不需要执行 Application->Run(),或者更糟糕的是 Application->CreateForm(),它创建一个主窗体并在该窗体上循环。我不想要一个主窗体,我想要一个主 Presenter

然后我的问题变成了如何创建线程化的 TForms?

选项 1: 如果只有一个消息循环(Presenter),那么我系统中的每个随机线程都必须向这个主线程发布一条消息并让它创建表单。

选项 2: 每个表单都有自己的消息循环。现在随机线程可以根据需要新建和删除它们。发布消息仍然用于它们之间的通信。

如果推荐选项 2,是否有人对实施此方法有任何建议?

编辑: 如何更改以下内容以允许使用 new 创建表单并仍然允许循环工作?

// Start VCL library
pApplication->Initialize();

// Create the Main form and assign the MainForm property
pApplication->CreateForm(__classid(TForm1), &pFormMain);

// Show the form
pFormMain->Show();

// Run the loop
pApplication->Run();

【问题讨论】:

  • MVP 模式绝不需要或指定线程。你必须有一个消息循环。所有窗口都应该在一个线程上创建。不要让随机线程创建窗口。偏离这些规则会给你带来很大的麻烦。
  • 我认为 TApplication 已经充当了演示者,而实现它最多只能让您重新发明轮子。 :)
  • @Hans,明智的话,我会按照你的建议去做。 @TommyA,是的,在某种程度上是这样,但它太严格了,这就是为什么我要问@Ken White 的问题。

标签: c++ multithreading c++builder vcl message-pump


【解决方案1】:

您不会将每个表单放在自己的线程中。您将每个表单都放在主线程中。

一个线程只有一个消息循环。例外情况是在以模态方式显示表单时运行的特殊消息循环。

pApplication->Run(); 运行您的消息循环。当发布的消息被处理时,它们被分派到适当的窗口过程。发送消息时,它们会同步直接传递到窗口过程。

您可以创建和显示任意数量的表单,并从同一个消息循环中为它们提供服务。您不仅可以做到这一点,它还是做事的方式。

如何将这些知识映射到 MVP 框架中是另一回事,但在任何解决方案中,在单个线程之外运行 GUI 都是一个固定点。

编辑

如果您没有可见的主窗体,您会问如何使用 VCL 运行消息循环。你有两个选择:

  1. 在致电pApplication->Run();之前创建一个不可见的表单。
  2. 运行您自己的消息循环。

在我看来,选项 1 是更好的选择。

【讨论】:

  • @David,谢谢。那么我如何使用 VCL 框架使循环运行而不必将其分配给第一个表单?我真的不想要 MainForm,我想要一个消息循环,必须,然后我将发布到该循环以根据需要创建表单。我应该使用隐藏的表单,只有消息的窗口吗?
  • @David,这似乎是这样。只是让你知道......我认为 TApplication 有它自己的隐藏窗口......如果我从不创建 TApplication,创建我自己的循环就可以了,但看起来工作量很大,我猜还不如使用 wxWidgets。嗯...
  • @pcunite TApplication 确实创建了一个窗口。但是,如果您在调用pApplication->Run() 之前没有至少调用一次pApplication->CreateForm(),那么您的程序将立即终止。
  • @David,是的,我注意到...你知道,我只想访问循环处理的消息,也许我可以覆盖 TApplication 方法。
  • @pcunite 最简单的方法是声明一个表单,一个 TForm 的子类。使用 CreateForm() 创建它。将可见设置为假。调用 pAppliction->Run()。然后使用表单的 Handle 属性作为窗口句柄并处理表单的 WndProc 中的任何消息,或者您打算在 C++ VCL 中处理消息(我真的是一个 Delphi 人)。
【解决方案2】:

您不能使用 VCL 安全地创建线程表单,因为 VCL 不是线程安全的。

此外,每个表单已经包含了它自己的消息循环。 TApplication 只是将消息分派到每个表单的循环中。

【讨论】:

  • 我完全明白,你是对的,这就是为什么我可以在每个表单中捕获消息的原因。我现在的问题...查看我的编辑...
  • @pcunite,我认为@David Heffernan 回答了您编辑提出的问题。如果没有,你能澄清一下吗?
猜你喜欢
  • 1970-01-01
  • 2013-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-21
  • 1970-01-01
  • 2012-07-06
相关资源
最近更新 更多