Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a second UI thread in Delphi with its own message processing loop?

I am working on a VCL (Delphi Win32) forms application platform with embedded scripting and would like to add debugging support. Scripting executes in the main VCL thread - scripts do direct UI manipulation and has some other legacy constraints keeping it in the UI thread.

The debugger UI needs to run in its own thread since the main UI thread will block on script breakpoints. It still needs to be in the same process for the thread-safe debugging component to work.

I tried to follow Blorgbeard's comment on https://stackoverflow.com/a/12505959/243144, but I am not sure if this is even possible with Delphi's VCL. (.NET creates a new ApplicationContext when passing a form to Application.Run) With the following Delphi, blocking of the main UI thread stops message processing on the second thread (and vice versa).

procedure TDebuggerThread.Execute;
begin
  CoInitialize(nil);

  FForm := TForm2.Create(nil);
  FForm.Show;
  Application.Run;
end;
like image 582
carlmon Avatar asked Dec 21 '22 09:12

carlmon


2 Answers

Delphi forms are single-thread only. Any descendant of TControl, including TForm, must only be accessed from the main UI thread. Never call any TApplication method on anything but the main thread.

You're of course allowed to create other windows that are tied to different threads. You just can't use the VCL UI elements in those threads. Instead, you'll use CreateWindow to create the main window and any controls on it. You'll write a window procedure to handle any messages sent to those windows. You'll handle control-notification messages in the parent's window procedure rather than the child's.

like image 94
Rob Kennedy Avatar answered Dec 24 '22 01:12

Rob Kennedy


One of the constraints of the VCL is that all interaction with GUI controls must be performed on the main thread. There's no way to circumvent that.

If you want to show debugger GUI in a separate thread, using VCL, your only option is to use an out-of-process solution. In other words, run your debugger in a different process, and use IPC to communicate between the two processes.

like image 31
David Heffernan Avatar answered Dec 24 '22 02:12

David Heffernan