C++Builder - 在应用程序启动时采取操作的正确方法

C++Builder - Correct way to take action on application startup

使用 C++Builder XE5。

我的主窗体有一个 Indy 阻塞套接字,我想在应用程序启动并显示主窗体后立即连接并阻塞它。

正确的做法是什么?

在以前的版本或C++Builder中,OnCreateAfterConstruction都是不可靠的。通常我将这样的代码放在主 .cpp 文件中,就在 Application->Run() 之前,但这在这里不合适,因为我要阻止(并依赖 TIdAntifreeze 进行消息处理) .

我想到的一种方法是定义自定义 windows 消息并 post 给我自己,但我想知道是否有 "proper" 方法。

My main form has an Indy blocking socket which I would like to connect to and block on, as soon as the application has started up and the main form shown.

您真的需要在 UI 主线程中阻塞 I/O 吗?阻塞操作,例如 Indy 的套接字 I/O,应该在工作线程中完成。

如果主线程需要在处理 UI 消息的同时阻塞套接字操作,您可以通过 CreateEvent()MsgWaitForMultipleObject() 在调用的循环中使用可等待事件对象Application->ProcessMessages() 仅当有消息要处理时,在事件发出信号时打破循环。这通常不是最好的选择。工作线程通知主线程 activity/results 的事件驱动模型将是更好的选择。你真的不应该为任何事情阻塞主 UI 线程。

What is the correct way to do this?

我建议让 MainForm 构造函数创建一个工作线程,然后该线程可以管理套接字操作并在需要时与主线程同步 UI。

In previous versions or C++Builder, OnCreate and AfterConstruction were both unreliable.

AfterConstruction() 是可靠的,而且一直都是。只有 OnCreate 事件不可靠,永远不应在 C++ 中使用以支持构造函数。

Normally I put code like this in the main .cpp file, just before Application->Run(), however that is not appropriate here because I am going to block (and rely on the TIdAntifreeze for message processing).

你真的不应该依赖 TIdAntiFreeze,工作线程是更好的选择。

One way I thought of is to define a custom windows message and post that to myself

那行得通。我自己有时会使用这种技术。请注意这是一个基于 HWND 的解决方案,因此您需要确保 post 的 HWND 不是 post 之后的 destroyed/recreated消息和从消息队列中检索之前。如果您使用MainForm 的HWND,post 消息在OnShow 事件中。更好的选择是使用 AllocateHWnd() 为您的自定义消息创建专用的 HWND