As far as I understand and know the method of the TThread Class, if you synchronize your code, it actually get's executed in the main Application Thread (just like a timer/buttonclick/etc.) I've been playing around and noticed that a MessageBox DOES NOT block the main application, however sleep does just as expected. Why is that?
type
TTestThread = class(TThread)
private
procedure SynchThread;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean);
end;
procedure TTestThread.SynchThread;
begin
MessageBoxA (0, 'Hello', 'Test', 0);
end;
procedure TTestThread.Execute;
begin
Synchronize (SynchThread)
end;
constructor TTestThread.Create(CreateSuspended: Boolean);
begin
inherited;
FreeOnTerminate := True;
end;
procedure StartThread;
var
TestThread : TTestThread;
begin
TestThread := TTestThread.Create (FALSE);
end;
There are two parts to this answer.
Part 1 is nicely explained in If MessageBox()/related are synchronous, why doesn't my message loop freeze?. The MessageBox function is not blocking, it merely creates a dialog box with its own message loop.
Part 2 is explained in the MessageBox documentation.
hWnd: A handle to the owner window of the message box to be created. If this parameter is NULL, the message box has no owner window.
When you display a modal dialog, Windows disables its owner, but if you pass 0 for the first parameter, there is no owner and nothing to disable. Therefore, your program will continue to process messages (and react to them) while the message box is displayed.
To change this behaviour, pass form's handle as a first parameter. For example:
procedure TTestThread.SynchThread;
begin
MessageBoxA (Form1.Handle, 'Hello', 'Test', 0);
end;