4
votes

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;
2
WinForms means .Net. Are you really using .Net with your Delphi project, or are you just using Delphi forms on Windows?Rob Kennedy
Thanks I meant VCL forms, but I do use some .NET controls in my Delphi project via COM interop :).carlmon
You may get this to work in one thread by using Fibers (see msdn.microsoft.com/en-us/library/windows/desktop/…). It will not work if your scripted code blocks on anything, but it will if you just want to single-step and visualize. Basically you need to turn your script breakpoints into switching the current fiber. I have used this to add single-stepping with visualization to image processing code using a COM library.mghie
@mghie I don't think anyone in the world has ever managed to write a robust program using fibers. Not even MS could manage it for SQL server.David Heffernan
@David: What can I say, the programs in question are robust enough, though, both for me and for the customer. It's not that hard to get right for this task, just two fibers and very defined switching points...mghie

2 Answers

6
votes

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.

5
votes

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.