Recent

Author Topic: [SOLVED] Close application from TMainForm.FormCreate  (Read 327 times)

fatmonk

  • Full Member
  • ***
  • Posts: 217
[SOLVED] Close application from TMainForm.FormCreate
« on: August 14, 2019, 11:55:00 am »
I run a check to see if my application is already running and if it is I warn the user with a MessageDlg and then Close() the application.

Immediately after clicking the 'OK' button in the dialog I get an External: SIGSEGV' exception.

Code: [Select]
procedure TMainForm.FormCreate(Sender: TObject);
begin

  if (WindowsProcIsRunning('myApplication.exe') > 1) then
    begin
      if (MessageDlg('Cannot run application more than once on a machine.'+sLineBreak+sLineBreak+'Exiting...',mtWarning,[mbOK],0) = mrOK) then Close();
    end;

 

What is the correct way to close the application from FormCreate? (Or can I actually close the application before the main form is created?)

Thanks,

FM
« Last Edit: August 14, 2019, 12:55:02 pm by fatmonk »

paweld

  • Full Member
  • ***
  • Posts: 187
Re: Close application from TMainForm.FormCreate
« Reply #1 on: August 14, 2019, 12:06:38 pm »
Code: Pascal  [Select]
  1. procedure TMainForm.FormCreate(Sender: TObject);
  2. begin
  3.   if (WindowsProcIsRunning('myApplication.exe') > 1) then
  4.     begin
  5.       if (MessageDlg('Cannot run application more than once on a machine.'+sLineBreak+sLineBreak+'Exiting...',mtWarning,[mbOK],0) = mrOK) then Halt;
  6.     end;
  7. end;
Best regards
paweld

fatmonk

  • Full Member
  • ***
  • Posts: 217
Re: Close application from TMainForm.FormCreate
« Reply #2 on: August 14, 2019, 12:16:13 pm »
Perfect, thanks.

What's the difference in how Close() and Halt operate? Is Close() just trying to close the form before it has fully been created or is it something completely different?

Thanks,

FM

lucamar

  • Hero Member
  • *****
  • Posts: 2126
Re: Close application from TMainForm.FormCreate
« Reply #3 on: August 14, 2019, 01:35:08 pm »
What's the difference in how Close() and Halt operate? Is Close() just trying to close the form before it has fully been created or is it something completely different?

I've not been able to reproduce your problem (though in my very small test I have found a little glitch: calling Close in the OnCreate handler is, apparently, ignored).

But yes, when the OnCreate event is fired the form and its controls are not yet *fully* initialized. In my experience quite a lot of things have to be deferred to an OnShow or OnActivate handler, which you can also do in this case.

Calling Halt in a GUI application should be left for exceptional circumstances; if I were you I would do something like:

Code: Pascal  [Select]
  1. const
  2.   AlreadyRunning: Boolean;
  3.  
  4. procedure TMainForm.FormCreate(Sender: TObject);
  5. begin
  6.   AlreadyRunning := WindowsProcIsRunning('myApplication.exe') > 1;
  7.   if AlreadyRunning then
  8.     Exit;
  9.   {... other initializations ...}
  10. end;
  11.  
  12. procedure TMainForm.FormShow(Sender: TObject);
  13. begin
  14.   OnShow := Nil; { If you only do this: }
  15.   if AlreadyRunning then begin
  16.     ShowMessage('Only one instance allowed!' + LineEnding
  17.                 + 'Click "OK" to exit...');
  18.     Close;
  19.   end;
  20. end;
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

ASerge

  • Hero Member
  • *****
  • Posts: 1420
Re: [SOLVED] Close application from TMainForm.FormCreate
« Reply #4 on: August 14, 2019, 02:42:02 pm »
What is the correct way to close the application from FormCreate? (Or can I actually close the application before the main form is created?)
The main form has already been created in OnCreate.
Best way - Application.Terminate. The disadvantages of the Halt command are listed in the documentation https://www.freepascal.org/docs-html/rtl/system/halt.html
In form events OnShow, OnActivate, OnHide you can check Application.Terminated to skip long work. OnClose, OnCloseQuery, OnDeactivated will be skipped.

Fungus

  • Sr. Member
  • ****
  • Posts: 352
Re: [SOLVED] Close application from TMainForm.FormCreate
« Reply #5 on: August 14, 2019, 03:47:52 pm »
You should perform you check before the GUI is initialized and form(s) have been created, in the project source (Lazarus menu: Project->View Project Source) and make something like:

Code: [Select]
begin
  If ProcessIsAlreadyRunning Then Exit;
  Application.Initialize;
  Application.CreateForm(TSomeForm, SomeForm);
  Application.Run;
end.

You could also use component for the purpose: https://wiki.freepascal.org/UniqueInstance

garlar27

  • Hero Member
  • *****
  • Posts: 621
Re: [SOLVED] Close application from TMainForm.FormCreate
« Reply #6 on: August 14, 2019, 04:49:17 pm »
I use UniqueInstance and is very easy. and you can bring to front the other instance and close the new instance silently, even though I couldn't make it set focus to it so, it becomes visible but you need to click the form to use it.