Reputation: 742
The Application.Run procedure calls an infinite loop that handles windows messages:
repeat
try
HandleMessage;
except
HandleException(Self);
end;
until Terminated;
The Terminated
property can be set to true only through Application.Terminate
procedure, which sends PostQuitMesage.
I would like to change the message handling loop so that I can directly stop it using the global variable (without using messages queue):
var MyTerminated:Boolean
....
repeat
try
HandleMessage;
except
HandleException(Self);
end;
until Terminated or MyTerminated;
The question is, is it possible to make the program use your own version of Application.Run?
Upvotes: 2
Views: 2103
Reputation: 4782
Yes, you can make your application use your own version of Application run, but this practice is discouraged because it changes the normal program flow designed by architects of Delphi.
Directly stopping the Application.Run signifies that there is a need to restart Application.Run later, for example, after some action that is wanted to be performed from the main thread. This makes the program puzzled, harder to understand by peer programmers and is more error prone as a whole.
The program design should be simple and straightforward. If an application is big, for example containing two million lines of code, the overall design of the execution flow should be simple anyway:
So a Delphi application's main loop should only be exited on the overall application exit, which is done by the PostQuitMessage. We don't have to avoid this message.
The reason when the PostQuitMessage is wanted to be avoided is probably an instantaneous exit. This is not how VCL applications are supposed to run. If one doesn't need any forms (for example for a Windows Service application), just don't use the TApplication class and don't run forms, just make your own message loop based on MsgWaitForMultipleObjects.
Upvotes: 1
Reputation: 54802
"Terminated" property is read-only. However it is a direct getter of the FTerminated
field, therefore Application.Terminated
directly reads from the boolean field. While the language disallows setting Application.Terminated
, you can set the boolean value at that address using a pointer:
PBoolean(@Application.Terminated)^ := True;
You may also consider using Halt
, which will pass over the message loop completely, for a more abrupt but less hacky solution.
Upvotes: 6