Forum > LCL

[SOLVED] Expert needed: how to use 'Application.ShowMainForm:=false' correctly?

(1/12) > >>

Hartmut:
I changed the subject of this Topic in the hope to find someone, who knows what is the correct (intended) use of feature 'Application.ShowMainForm:=false'. Please see reply #14 and the end of reply #18 for a short summary. Thanks a lot.


I have written a common unit to display a Graphic file and some more ... and to save it into the Clipboard. Now I want to use this common unit in a program, which means, that I don't need the Main Form of the program, because the common unit provides its own Main Form. So I wanted to hide the Main Form of the program (which flickers) by


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Application.ShowMainForm:=false;
Everything works perfectly on Windows and Linux except for 1 problem: when I save a graphic file into the Clipboard, then this works only on Windows, but on Linux instead the following message is written to the console:

(project1:3656): Gtk-CRITICAL **: 16:40:01.613: IA__gtk_selection_owner_set: assertion 'widget == NULL || gtk_widget_get_realized (widget)' failed

But when I start the program the "normal way" (without 'Application.ShowMainForm:=false') then saving to the clipboard works on Linux too.

So my question is: what did I wrong in the kind of using 'Application.ShowMainForm:=false'?

I attached a compilable demo project including a demo graphic file:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program project1; {$mode objfpc}{$H+} uses {$IFDEF UNIX} cthreads, {$ENDIF} {$IFDEF HASAMIGA} athreads, {$ENDIF} Interfaces, // this includes the LCL widgetset Forms, unit1, Unit2 { you can add units after this }; {$R *.res} begin// with the following code block it works on Windows AND Linux:(* RequireDerivedFormResource:=True; Application.Scaled:=True; Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run;*) // with the following code block it works only on Windows, but NOT on Linux: RequireDerivedFormResource:=True; Application.Scaled:=True; Application.Initialize; Application.ShowMainForm:=false; {used to hide the main form}writeln('AAA'); Application.CreateForm(TForm1, Form1); {calls FormCreate()}writeln('BBB'); Form1.FormActivate(nil); {is not longer called automatically}writeln('CCC');// Application.Run;       {would be called only AFTER the program has ended}writeln('DDD');end.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit1; {main unit} {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, unit2; type  { TForm1 }  TForm1 = class(TForm)  procedure FormCreate(Sender: TObject);  procedure FormActivate(Sender: TObject); private public end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.FormCreate(Sender: TObject);   begin   writeln('FormCreate');   end; procedure TForm1.FormActivate(Sender: TObject);   const first: boolean = true;   begin   writeln('FormActivate');   if not first then exit;    first:=false;   self.Hide; {flickers without 'Application.ShowMainForm:=false'}   Unit2.Test_Clipboard; {saves a graphic file into the clipboard}   Close;   end; end.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit2; {this is a short extract from a COMMON Unit to display a Graphic             file and more and to save it into the Clipboard} {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ClipBrd; procedure Test_Clipboard; implementation type  { TForm2 }  TForm2 = class(TForm)  Button1: TButton;  procedure Button1Click(Sender: TObject); private public end; { TForm2 } procedure TForm2.Button1Click(Sender: TObject);   {loads a Graphic file and saves it into the Clipboard}   var Picture1: TPicture;   begin   Picture1:=TPicture.Create;   Picture1.LoadFromFile('demo.bmp');   Clipboard.Assign(Picture1);   Picture1.Free;   end; procedure Test_Clipboard;   {abbreviation for to call 'Form2' from within 1 procedure}   var Form2: TForm2;   begin   Form2:=TForm2.CreateNew(Application);    Form2.Button1:=TButton.Create(Form2);   Form2.Button1.Parent:=Form2;   Form2.Button1.Caption:='Clipboard';   Form2.Button1.OnClick:=@Form2.Button1Click;    Form2.ShowModal;   Form2.Free;   end; end.
Versions:
 - Windows 7 with Lazarus 3.6.0 and 2.0.10
 - Linux Ubuntu 22.04 with Lazarus 3.4.0 and 2.0.10 GTK2

Thanks in advance.

jeremiah:
I grabbed your code and in Debian 12 Cinnamon it errors as you state. Then in Debian 12 KDE it works as you want. So perhaps the object is not initialized yet for the GTK?? Lord willing I can have a go later tonight and try.  :)

Hartmut:
Thank you jeremiah for testing. It would be great if you could find out, how feature


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Application.ShowMainForm:=false;
has to be handled correctly.

wp:
I still don't get the intention behind this... (A project without Application.Run is VERY unusual...). Do you want to provide a general-purpose form to display an image and copy it to the clipboard? In this case you do not need a project at all, just put the form into a package and add the package to all projects requiring this form.

Hartmut:
Thank you wp for asking. Obviously I have not explained my intention clear enough.

Everythings said above leads to the situation, that I want to start a program without showing the Main Form (but I want to have a Main Form, because for me this is the easiest way to handle an INI-file).

To hide the Main Form at program start I found in this Forum this command:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Application.ShowMainForm:=false;
I found no real documentation for this command and after a couple of experiments I had this code:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- ... RequireDerivedFormResource:=True; Application.Scaled:=True; Application.Initialize; Application.ShowMainForm:=false; {used to hide the main form} Application.CreateForm(TForm1, Form1); {calls FormCreate()} Form1.FormActivate(nil); {is not longer called automatically} end.
This code worked perfectly for months on Windows and Linux. But now I added a new feature to save something into the clipboard and this does not work on Linux (but on Windows). I found out, that the reason for that clipboard problem in Linux is the kind of how I started my program, because if I do it the "normal way", the clipboard works on Linux too.

So my question is: How has the feature 'Application.ShowMainForm:=false' to be handled correctly? If I use it, how can I then pass control to my code (which is now in procedure 'TForm1.FormActivate' in Unit 'Unit1' of my first post)?

If there are more questions, please ask again. Thanks for your help.

Navigation

[0] Message Index

[#] Next page

Go to full version