I'm going to propose a bit different approach to this answer by Server Overflow. We will achieve almost exactly same effect, but without any edit inside the DPR file (main project source file). We will get there by using a class helper in the unit of our main form:
type
{ TAppHelper }
TAppHelper
= Class helper for TApplication
Public Procedure Run;
End;
Procedure TAppHelper.Run;
begin
Unit1.MainForm.PreRun;
inherited Run;
end;
Notice, the Unit1.MainForm.PreRun is some method in your main form, with only one caveat: if your main form is called "MainForm", then you need to prefix it with your unit's name inside the helper's method, because the TApplication class already has a member called MainForm. Incidentally, if you do leave out the prefix, this might still work, given that your Unit1.MainForm is indeed application's main form as well.
The reason why this works, is because the Unit1 is on the uses list of the DPR project, and as long as the TAppHelper is defined in the interface section (not in the implementation section), it will get loaded and by the time the Application.Run method is called in the DPR file, this will already be the helper version of it.
The beauty of this is, that it will run exactly one time, and exactly after all the forms are already created, after all their constructors have already been executed. And the fact that we're effectively customizing the Application.Run call in the DPR file, without editting the DPR file, is kind of ingenious. Again, class helpers in delphi/lazarus !
I will share one more neat trick, first take a look:
Procedure TAppHelper.Run;
begin
TTask.Run(
procedure
begin
sleep(10);
TThread.Synchronize(nil, procedure begin Unit1.MainForm.PreRun; end);
end
);
inherited Run;
end;
This is a trick I use whenever I want the code to execute with a small delay. Why? Because if your code runs before the inherited Run method, it might (depending what happens inside of that code) hang the UI momentarily, but just long enough for the form to flicker and appear not responsive during its startup. Also, we can't simply put the code behind the inherited Run method, because that won't get executed until the application gets terminated. So instead I use TTask from the System.Threading unit. The sleep(10) is probably an overkill, sleep(1) would most likely do the job, possibly even no sleep at all would work, but I do some complex initialization there, so I keep the delay generous. Bonus: if you don't update UI from your PreRun custom method, then you don't even need TThread.Synchronize wrapper, and it becomes even simpler. In case of FPC/Lazarus you can achieve the same by using TApplication.QueueAsyncCall() instead of TTask class.
I really think it's a neat trick, because I can code it entirely outside of the DPR file, in the unit of the form which defines the PreRun method, and it's guaranteed after ALL Forms are already created, not just the one where I implement my PreRun method. Also, if the class helper is in the unit of the form, instead elsewhere, then the PreRun doesn't even need to be public, it will work with protected or even private method as well! This is great for keeping this little logic away from any other part of the code.