Recent

Author Topic: [SOLVED] Expert needed: how to use 'Application.ShowMainForm:=false' correctly?  (Read 9034 times)

wp

  • Hero Member
  • *****
  • Posts: 12589
Re: Starting a program with hiding the Main Form: what did I wrong?
« Reply #15 on: December 15, 2024, 04:48:49 pm »
I am convinced that we use 'Application.ShowMainForm:=false' in a wrong way. What is the correct (intended) way
I guess it is needed for applications which are fully controlled by a tray icon - see the attached mini project as a demonstration. It creates the mainform with a TrayIcon, hides it (Application.ShowMainForm := false) and shows the trayicon which then takes control of the entire application.

Application.Run() is only started at the moment, after the program had already finished, where this loop makes no more sense.
The need to avoid the Application.Run is a clear indication to me that you are using the Lazarus LCL GUI application in the wrong way. In fact, you should use a different application template. Simply use the "Simple Program" template which is the easiest type of application; it gives you full control over what is happening.

I want to have a Main Form, because for me this is the easiest way to handle an INI-file).
Really? There is a class TIniFile which you must create, of course, and you add integers/strings/etx to it by calling the WriteInteger/WriteString/etc methods, and you get them back by calling the ReadInteger/ReadString/etc methods. And at the end you destroy the ini file. I think this *is* easy. And you can do this at any time, with/and without a Mainform.
« Last Edit: December 16, 2024, 01:53:35 am by wp »

Bart

  • Hero Member
  • *****
  • Posts: 5510
    • Bart en Mariska's Webstek
Re: Expert needed: how to use 'Application.ShowMainForm:=false' correctly?
« Reply #16 on: December 15, 2024, 04:58:50 pm »
In the first post he uses the clipboard, so a depency on LCL exists.
(But, you still don't need a form fro that.)

Bart

jeremiah

  • New Member
  • *
  • Posts: 18
Re: Expert needed: how to use 'Application.ShowMainForm:=false' correctly?
« Reply #17 on: December 16, 2024, 01:27:58 am »
Here is more. Application.ShowMainForm:=false means just that, do not show main form but visible property "has" to be false also. This is widget dependent and I have no idea how Lazarus/Free Pascal handle this. This was done/tested on Debian 12/Cinnamon. As you can see changing form two from form 1 by ini you can do. I think you need to check your code there?


edit:   Back to furnace...

edit 2: sent correct zip
« Last Edit: December 16, 2024, 01:52:12 am by jeremiah »

Hartmut

  • Hero Member
  • *****
  • Posts: 891
Re: Expert needed: how to use 'Application.ShowMainForm:=false' correctly?
« Reply #18 on: December 16, 2024, 12:19:11 pm »
Thank you wp for your reply and the demo.

I am convinced that we use 'Application.ShowMainForm:=false' in a wrong way. What is the correct (intended) way
I guess it is needed for applications which are fully controlled by a tray icon - see the attached mini project as a demonstration. It creates the mainform with a TrayIcon, hides it (Application.ShowMainForm := false) and shows the trayicon which then takes control of the entire application.

This is a very interesting and important guess. If you are right then I wasted plenty of time to use something in a completely unsuitable way. I feel sad, that this important restriction is not clearly documented in https://lazarus-ccr.sourceforge.io/docs/lcl/forms/tapplication.showmainform.html

Dear LCL Developers, can someone of you prove, that the intended use of 'Application.ShowMainForm:=false' is only for applications, which are fully controlled by a tray icon?

Quote
I want to have a Main Form, because for me this is the easiest way to handle an INI-file).
Really? There is a class TIniFile which you must create, of course, and you add integers/strings/etx to it by calling the WriteInteger/WriteString/etc methods, and you get them back by calling the ReadInteger/ReadString/etc methods. And at the end you destroy the ini file. I think this *is* easy. And you can do this at any time, with/and without a Mainform.

Of course is it *possible* to handle an INI-file completely manually. But you have to read and to write each single property and beside integers and strings there are also more complex controls like e.g. ListBoxes etc. In my eyes this would be unneccessary effort. That's not worth it. I wrote in reply #8:
Quote
I have multiple projects where I want to use feature 'Application.ShowMainForm:=false' but if this feature would mean ... that e.g. the standard use of an INI-file via the Main Form is not longer possible, than this would be the wrong feature for me.
(in this case I would stay with my old "solution" from reply #12)

Quote
Application.Run() is only started at the moment, after the program had already finished, where this loop makes no more sense.
The need to avoid the Application.Run is a clear indication to me that you are using the Lazarus LCL GUI application in the wrong way.

I am convinced that jeremiah and me were using the Lazarus LCL GUI application in a wrong way, because this way Application.Run was useless, because it is started too late. I tried to explain this to jeremiah multiple times, but I fear, that he didn't understand this (and didn't test this). Maybe my English is too bad. The purpose of this Topic was to find out the correct way.

Quote
In fact, you should use a different application template. Simply use the "Simple Program" template which is the easiest type of application; it gives you full control over what is happening.

I created a new project with the "Simple Program" template. It's description in the IDE says: "A most simple Free Pascal command line program". By this description I would have expected a console program, not a GUI program. Then one very simple source file was created with only:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. begin
  3. end.
That's all. I tried the Help-Button in the 'Create a new project' dialog. Nothing happened. I used google to find a documentation, what the 9 different project templates mean and how they should be used, but I found nothing. To create a GUI application from this point I would have a lot of manual work by copying peace-by-peace from a "normal" GUI project, but that's not worth it.



Dear jeremiah, I had a look into your new code, but I had clearly written in reply #8:

To avoid misunderstandings:
I am not interested to find some workarounds / detours to handle an INI-file somehow nevertheless. I have multiple projects where I want to use feature 'Application.ShowMainForm:=false' but if this feature would mean ... that e.g. the standard use of an INI-file via the Main Form is not longer possible, than this would be the wrong feature for me. So please don't go in that direction.
Didn't you see that?



Summary: Dear LCL Developers, can someone of you prove the guess of wp, that the intended use of 'Application.ShowMainForm:=false' is only for applications, which are fully controlled by a tray icon?
Then I would close this Topic.

wp

  • Hero Member
  • *****
  • Posts: 12589
Re: Expert needed: how to use 'Application.ShowMainForm:=false' correctly?
« Reply #19 on: December 16, 2024, 01:03:02 pm »
I think the real problem is that you do not want to call Application.Run. How is a Lazarus LCL application supposed to work without it? You say that there are Listboxes which you want to store in the ini file - but without Application.Run these Listboxes will not be shown. I really don't understand what you want to do. Please take the time and set up a small demo application which basically shows your intentions.

Hartmut

  • Hero Member
  • *****
  • Posts: 891
Re: Expert needed: how to use 'Application.ShowMainForm:=false' correctly?
« Reply #20 on: December 16, 2024, 01:53:31 pm »
I think the real problem is that you do not want to call Application.Run.

Then we misunderstood. I do call Application.Run(). This is my current code in the project file (taken from reply #8):

Code: Pascal  [Select][+][-]
  1. begin
  2.  RequireDerivedFormResource:=True;
  3.  Application.Scaled:=True;
  4.  Application.Initialize;
  5. writeln('AAA');
  6.  Application.CreateForm(TForm1, Form1);
  7. writeln('BBB');
  8.  Application.ShowMainForm:=false;
  9. writeln('CCC');
  10.  Application.Run;
  11. writeln('DDD');
  12. end.

If you want a small demo then you can use the one from jeremiah from reply #5. You only need to insert the 4 writeln commands from above. If you run this code (please do it), you will see, that Application.Run() is only started at the moment, after the program had already finished (I hope my English is clearly enough). But that's too late. Thats why I'm writing again and again, that this way to call Application.Run() makes no sense. I totally agree with you, that Application.Run() *should* be called in a way, that it can do it's important job. But this way it's not possible. This way to call it must be wrong.

As long as this issue is not solved, it makes no sense to proceed with investing more time for INI-files, because as you said, without Application.Run() working correctly the whole application will not work correctly.

cdbc

  • Hero Member
  • *****
  • Posts: 1808
    • http://www.cdbc.dk
Re: Expert needed: how to use 'Application.ShowMainForm:=false' correctly?
« Reply #21 on: December 16, 2024, 02:38:49 pm »
Hi
@Hartmut: It's been a long time since I last saw stuff done like you are trying to do... You've got me baffled & bewildered!
No wonder it doesn't work for you...
The only place I can find, where that property is used is here:
Code: Pascal  [Select][+][-]
  1. procedure TApplication.Run;
  2. begin
  3.   if (FMainForm <> nil) and FShowMainForm then ///<--HERE!
  4.   begin
  5.     WidgetSet.AppSetupMainForm(FMainForm);
  6.     FMainForm.Show;
  7.   end;
  8.   WidgetSet.AppRun(@RunLoop);
  9. end;
  10.  
...and in your Grrrr!#¤/¤#! code you terminate Application before you get to 'Run'!!!
So how the h*ll is it supposed to work?!?!?
/bc
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Hartmut

  • Hero Member
  • *****
  • Posts: 891
Re: Expert needed: how to use 'Application.ShowMainForm:=false' correctly?
« Reply #22 on: December 16, 2024, 03:39:28 pm »
Hi cdbc, thanks for your post. This sourcecode for TApplication.Run() I had found already before, but it didn't help me, because I understand not enough what's going on there. So I could not deviate from that, how 'Application.ShowMainForm:=false' should be used correctly.

...and in your Grrrr!#¤/¤#! code you terminate Application before you get to 'Run'!!!
So how the h*ll is it supposed to work?!?!?

I think you mean this:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.  ShowForm2;
  4. end;
  5.  
  6. procedure TForm1.ShowForm2;
  7. //const first: boolean = true;
  8. begin
  9. // if not first then exit;
  10.  
  11. // first:=false;
  12.  //self.Hide;
  13.  Unit2.Test_Clipboard; {saves a graphic file into the clipboard}
  14.  Close;
  15.  Application.Terminate;
  16. end;

This is not my code, this was created by jeremiah (in reply #5). But I think this is only a minor issue. The major issue is, that Application.Run() ist started too late, after the program has finished.

cdbc

  • Hero Member
  • *****
  • Posts: 1808
    • http://www.cdbc.dk
Re: Expert needed: how to use 'Application.ShowMainForm:=false' correctly?
« Reply #23 on: December 16, 2024, 04:10:42 pm »
Hi
This:
Code: Pascal  [Select][+][-]
  1. procedure Test_Clipboard;
  2.    {abbreviation for to call 'Form2' from within 1 procedure}
  3. var Form2: TForm2;
  4. begin
  5.  Form2:=TForm2.CreateNew(Application);
  6.  Form2.Button1:=TButton.Create(Form2);
  7.  Form2.Button1.Parent:=Form2;
  8.  Form2.Button1.Caption:='Clipboard';
  9.  Form2.Button1.OnClick:=@Form2.Button1Click;
  10.  Form2.ShowModal;
  11.  Form2.Free;
  12. end;
Creates a form in 'pseudo-main-form' mode with its own 'showmodal' message-loop, behind the scenes it calls 'inherited Create();', and adds it to the forms list as the first one, a de-facto 'mainform'.
When that goes away, the application object continues creating 'Form1' until it realizes, it has been terminated and halts the application altogether...
Why would you do stuff like this in the visual apparatus?!?
Cannot for the life of me, see what you want to do...
/bc
« Last Edit: December 16, 2024, 04:12:29 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

alpine

  • Hero Member
  • *****
  • Posts: 1343
Re: Expert needed: how to use 'Application.ShowMainForm:=false' correctly?
« Reply #24 on: December 16, 2024, 04:14:28 pm »
This is not my code, this was created by jeremiah (in reply #5). But I think this is only a minor issue. The major issue is, that Application.Run() ist started too late, after the program has finished.
May i politely ask how the Application.Run() can be started after the program has finished? Seems impossible or misspelled.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

cdbc

  • Hero Member
  • *****
  • Posts: 1808
    • http://www.cdbc.dk
Re: Expert needed: how to use 'Application.ShowMainForm:=false' correctly?
« Reply #25 on: December 16, 2024, 04:20:46 pm »
Hi
Oh, it's true, that's because of his *Shenanigans* in the 'FormCreate' handler, it gets all screwed to h*ll and ends up finishing before 'Run'.
It's a *Shure-fire* way to get burnt, when playing with fire...  :D
There's a lot going on in the LCL, pretty much from the 'getgo', one should treat it with some respect.
/bc
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

alpine

  • Hero Member
  • *****
  • Posts: 1343
Re: Expert needed: how to use 'Application.ShowMainForm:=false' correctly?
« Reply #26 on: December 16, 2024, 04:38:17 pm »
I think the same effect can be achieved by simply setting Form1.Visible to False and without any modification of the project main file. May have got the intent wrong though.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

cdbc

  • Hero Member
  • *****
  • Posts: 1808
    • http://www.cdbc.dk
Re: Expert needed: how to use 'Application.ShowMainForm:=false' correctly?
« Reply #27 on: December 16, 2024, 04:53:19 pm »
Hi
Quote
May have got the intent wrong though.
Struggling with that too... ::)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

LV

  • Full Member
  • ***
  • Posts: 204
Re: Expert needed: how to use 'Application.ShowMainForm:=false' correctly?
« Reply #28 on: December 16, 2024, 05:12:57 pm »
This is not my code, this was created by jeremiah (in reply #5). But I think this is only a minor issue. The major issue is, that Application.Run() ist started too late, after the program has finished.
May i politely ask how the Application.Run() can be started after the program has finished? Seems impossible or misspelled.

It is not the best choice of code that OP suggested, but

Application.Terminate delays termination until Application.Run() processes the main thread's message queue.

Run the debugger, and you will see this result.


 

TinyPortal © 2005-2018