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.
Do you really need to do blocking I/O in the main UI thread? Blocking operations, such as Indy's socket I/O, should be done in a worker thread instead.
If the main thread needs to block on a socket operation while still processing UI messages, you can use a waitable event object via CreateEvent()
with MsgWaitForMultipleObject()
in a loop that calls Application->ProcessMessages()
only when there are messages to process, breaking the loop when the event is signaled. This is not generally the best option though. An event-driven model, where the worker thread notifies the main thread of activity/results, would be a better choice. You really should never block the main UI thread for anything.
What is the correct way to do this?
I would suggest having the MainForm constructor create a worker thread, and then the thread can manage the socket operations and synchronize with the main UI when needed.
In previous versions or C++Builder, OnCreate and AfterConstruction were both unreliable.
AfterConstruction()
is reliable, and always has been. It is only the OnCreate
event that was unreliable, and should never be used in C++ in favor of the constructor instead.
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).
You really should not rely on TIdAntiFreeze
, a worker thread is a better choice.
One way I thought of is to define a custom windows message and post that to myself
That will work. I use that technique myself at times. Just be aware that it is an HWND
-based solution, so you need to make sure the HWND
you post to is not destroyed/recreated after you post the message and before it is retrieved from the message queue. If you use the MainForm's HWND
, post the message in the OnShow
event. A better option is to use AllocateHWnd()
to create a dedicated HWND
for your custom messages.