2

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?

3
  • I've tried this once, and would not recommend it. It entails making a complete copy of Vcl.Forms, and most importantly, making sure everything references that instead of the main one. Commented May 15, 2017 at 23:54
  • ("tried this" as in implementing my own message queue in place of the default one.) Commented May 16, 2017 at 0:11
  • 2
    For the life of me I cannot imagine why you would want to do this. My guess is that whatever is motivating the question, is the wrong solution to the real problem Commented May 16, 2017 at 10:43

2 Answers 2

6

"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.

Sign up to request clarification or add additional context in comments.

10 Comments

Wow, what a hack. I've never seen this one before. Does this work on any read-only literal property?
@Jerry - Yes, if by "literal" you mean a prop that references a field. I think we've discussed this here, it was about changing Application.MainForm.
@Jerry - Sorry, I didn't mean you were involved. I just wanted to note this is not original.
What happens if the implementation changes and the property no longer references a field but a getmethod?
@Pieter - You corrupt memory.
|
1

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:

  • If you need to do some longer actions do them from the worker threads;
  • If you need to do an instant actions do them from your main form or from the other forms.

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.

2 Comments

"WM_CLOSE" handler calls "Close" which on the main form calls "Application.Terminate", which then "PostQuitMessage" is called.
@SertacAkyuz -- oops, sorry, thank you for pointing that out - I have updated the reply.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.