boc7900
asked on
eternal OnShow chaining problem
I only want FormA to show FormB when/after FormA is shown. As you know, using FormA's onShow event causes a "cannot change Visible in OnShow or OnHide".
Using onPaint,onActivate or onCreate events to call FormB.show gives the same error.
I tried to call FormB's show event before application.run in project.dpr -> same error.
I also have tried with Timer events -> same error despite of how many seconds it waits.
Why Delphi guys don't let programmers do this?. The same Delphi shows multiple forms on startup: Object Inspector,main menu and toolbar,... :[[
I hope that such a basic feature must have an easy and smart way to be implemented (i.e.: afterShow event). I don't want to create threads or complex experiments like the ones I found on similar questions here.
I will give 150+ points if the answer is excellent.
Using onPaint,onActivate or onCreate events to call FormB.show gives the same error.
I tried to call FormB's show event before application.run in project.dpr -> same error.
I also have tried with Timer events -> same error despite of how many seconds it waits.
Why Delphi guys don't let programmers do this?. The same Delphi shows multiple forms on startup: Object Inspector,main menu and toolbar,... :[[
I hope that such a basic feature must have an easy and smart way to be implemented (i.e.: afterShow event). I don't want to create threads or complex experiments like the ones I found on similar questions here.
I will give 150+ points if the answer is excellent.
umm that happens when you call Show or Hide of the same form that's being shown or hidden
this works just fine :
uses unit2;
procedure TForm1.FormShow(Sender: TObject);
begin
Form2.Show;
end;
this works just fine :
uses unit2;
procedure TForm1.FormShow(Sender: TObject);
begin
Form2.Show;
end;
Try this example, we create form2 from form1, form2 is available not in autocreate Mode.
Put a timer in Form1 and programm the timer to create the form 2
Procedure CreaFormulario;
begin
Application.CreateForm(Tfo rm2, form2);
form2.Show;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
creaformulario();
Timer1.Enabled :=False;// to avoid a second creation of the form
end;
Best Regards.
Marcos.
Put a timer in Form1 and programm the timer to create the form 2
Procedure CreaFormulario;
begin
Application.CreateForm(Tfo
form2.Show;
end;
procedure TForm1.Timer1Timer(Sender:
begin
creaformulario();
Timer1.Enabled :=False;// to avoid a second creation of the form
end;
Best Regards.
Marcos.
ASKER
Very interesting Nestoura, I suppose that with PostMessage you trigger a mouseDown (which shows FormB) and mouseUp event (to not call show again). But what should I pass as Handle? (note that all I know of PostMessage is what you have typed :) ).
About creating a new message, wouldn't that requiere a new event too?
About creating a new message, wouldn't that requiere a new event too?
ASKER
Lee Nover, your example not only crush but the exception it gives is the essence of the problem I want to solve. :)
ASKER
Marcos, I have tried an example like yours but without Application.CreateForm(Tfo rm2, form2); and it gave the same error ("cannot change..."). I don't think that creating the form before showing it will help.
Thanks anyway. :)
Thanks anyway. :)
boc7900 then your code is flaw
you must do something wrong in your code
or you didn't read carefully what I wrote
you CAN call any forms Show in another forms OnShow or OnHide event
but you CANNOT call Show or Hide in the form that is being Shown or Hidden
you could also create the other form with:
Form2:=TForm2.Create(Appli cation);
you must do something wrong in your code
or you didn't read carefully what I wrote
you CAN call any forms Show in another forms OnShow or OnHide event
but you CANNOT call Show or Hide in the form that is being Shown or Hidden
you could also create the other form with:
Form2:=TForm2.Create(Appli
HI,
Handle is the Handle of the FormA - exactly as it' written.
Sincerely,
Nestorua.
Handle is the Handle of the FormA - exactly as it' written.
Sincerely,
Nestorua.
ASKER
Nestorua, I've executed your proposal step by step and it gives the exception "Cannot change Visible in onShow or onHide" when the program executes the line FormB.Show;
despite that it isn't (aparently) in any OnShow or OnHide.
Thanks
despite that it isn't (aparently) in any OnShow or OnHide.
Thanks
ASKER
Lee Nover, when I call anotherForm.Show from the current form OnShow event, Delphi gives me the exception "Cannot change Visible in onShow or onHide". Don't ask me why.
And it also gives the same exception if I call anotherForm.Show; from OnCreate,OnPaint,... of the current form. So it is impossible to me to show formB sequentially after showing formA.
And it also gives the same exception if I call anotherForm.Show; from OnCreate,OnPaint,... of the current form. So it is impossible to me to show formB sequentially after showing formA.
HI,
I don't know what you are doing to get those exceptions.
Let the FormA be your main form and it's Visible property =True, the FormB be autocreate form and it's Visible property is False. Then all that I proposed must work fine (it does on my comp).
Sincerely,
Nestorua.
I don't know what you are doing to get those exceptions.
Let the FormA be your main form and it's Visible property =True, the FormB be autocreate form and it's Visible property is False. Then all that I proposed must work fine (it does on my comp).
Sincerely,
Nestorua.
ASKER
Sorry Nestoura,with "autocreate form" do you mean a form created from project.dpr? If you mean that, then this is exactly how I have it all.
well I have D6 and I don't get that error
as it doesn't make sence why changing another forms visible state would raise an error
can you paste your exact code ?
as it doesn't make sence why changing another forms visible state would raise an error
can you paste your exact code ?
btw .. you want to show both forms at startup ?
then you can simply do:
// in the project file
begin
Application.Initialize;
Application.CreateForm(TFo rm1, Form1);
Application.CreateForm(Tfo rm2, Form2);
Form.Show;
Application.Run;
end;
:)
then you can simply do:
// in the project file
begin
Application.Initialize;
Application.CreateForm(TFo
Application.CreateForm(Tfo
Form.Show;
Application.Run;
end;
:)
boc7900, I think you have some code in your Form2's OnShow that is causing all these... try commenting out the code of your Form2's OnShow and I believe you can call Form2.Show from Form1's OnShow.
boc7900,
This error means that you are trying to show form that can't be shown. It has nothing to do with OnShow event itself, despite exception message. This can happen for a number of reasons: your app is using MDI layout and Form1 is shown as modal, Form2 is in process of creation or destruction, Form2 is in process of Showing/Hiding (it's Visible property is already changing, during which you try to change it to some 'hardcoded' value)...
Write bare-bones program (clean application with two empty fsNormal forms, and *only* line of code is 'Form2.Show' in OnForm1Show event). Error shouldn't occur.
If it still does, try non-elegant TTimer method.
If it's still there, something is very wrong with your system.
My (and, it seems, all of the others) guess is that bare- bones test app should work OK - that is, error is caused by other piece of code, that you overlooked. If it works OK, tell us and we can work from there as base ground...
This error means that you are trying to show form that can't be shown. It has nothing to do with OnShow event itself, despite exception message. This can happen for a number of reasons: your app is using MDI layout and Form1 is shown as modal, Form2 is in process of creation or destruction, Form2 is in process of Showing/Hiding (it's Visible property is already changing, during which you try to change it to some 'hardcoded' value)...
Write bare-bones program (clean application with two empty fsNormal forms, and *only* line of code is 'Form2.Show' in OnForm1Show event). Error shouldn't occur.
If it still does, try non-elegant TTimer method.
If it's still there, something is very wrong with your system.
My (and, it seems, all of the others) guess is that bare- bones test app should work OK - that is, error is caused by other piece of code, that you overlooked. If it works OK, tell us and we can work from there as base ground...
ASKER
You are right, it doesn't happen in a bare-bones project. But it still fails in my project, perhaps because it has to create more forms and to initialize them all on startup.
//Main-form's onShow event:
procedure TFPrincipal.FormShow(Sende r: TObject);
begin
inherited;
Inicialitza;
end;
//procedure called by onShow;
procedure TFPrincipal.Inicialitza;
begin
inherited;
Usuari:='';
TBPrincipal.Height:=24;
Application.CreateForm(TFF ons, FFons);
FFons.Show; //exception "cannot change Visible..."
end;
//project.dpr source code:
Application.Initialize;
FInicialitza := TFInicialitza.Create(Appli cation);
FInicialitza.Show;
FInicialitza.Update;
Application.CreateForm(TFP rincipal, FPrincipal);
Application.CreateForm(TFM odulDades, FModulDades);
Application.CreateForm(TFI nicialitza , FInicialitza);
Application.CreateForm(TFI dentitat, FIdentitat);
Application.CreateForm(TFC artera, FCartera);
Application.CreateForm(TFO peracio, FOperacio);
FInicialitza.Hide;
FInicialitza.Free;
ServeisG:=TServeis.Create( 'BDProject e');
try
Application.Run;
finally
ServeisG.Free;
end;
Thanks to all of you for your help.
//Main-form's onShow event:
procedure TFPrincipal.FormShow(Sende
begin
inherited;
Inicialitza;
end;
//procedure called by onShow;
procedure TFPrincipal.Inicialitza;
begin
inherited;
Usuari:='';
TBPrincipal.Height:=24;
Application.CreateForm(TFF
FFons.Show; //exception "cannot change Visible..."
end;
//project.dpr source code:
Application.Initialize;
FInicialitza := TFInicialitza.Create(Appli
FInicialitza.Show;
FInicialitza.Update;
Application.CreateForm(TFP
Application.CreateForm(TFM
Application.CreateForm(TFI
Application.CreateForm(TFI
Application.CreateForm(TFC
Application.CreateForm(TFO
FInicialitza.Hide;
FInicialitza.Free;
ServeisG:=TServeis.Create(
try
Application.Run;
finally
ServeisG.Free;
end;
Thanks to all of you for your help.
why do you have inherited; there ?
did you override those procedures ? if not then remove those
Application.CreateForm(TFF ons, FFons);
FFons.Show; //exception "cannot change Visible..."
with this you set the FFons as your MainForm !! because it is the first form that is created with Applicat.CreateForm !!!
so it will be shown without calling .Show
if you don't want it to be your mainform then create it like :
FFons:=TFFons.Create(Appli cation);
otherwise simply remove .Show because it will be shown anyway as it is your mainform
another thing would be to set Application.ShowMain:=fals e; just after you call Application.Initialize;
then you have to call FFons.Show; manually as you have it now
did you override those procedures ? if not then remove those
Application.CreateForm(TFF
FFons.Show; //exception "cannot change Visible..."
with this you set the FFons as your MainForm !! because it is the first form that is created with Applicat.CreateForm !!!
so it will be shown without calling .Show
if you don't want it to be your mainform then create it like :
FFons:=TFFons.Create(Appli
otherwise simply remove .Show because it will be shown anyway as it is your mainform
another thing would be to set Application.ShowMain:=fals
then you have to call FFons.Show; manually as you have it now
ASKER
I'm going to try FFons:=TFFons.Create(Appli cation) and I will comment the result. Thank you Lee!! :)
ASKER
Hi!
I've tried it and got the same exception. When calling FFons.Show:
procedure TFPrincipal.Inicialitza;
begin
inherited;
Usuari:='';
TBPrincipal.Height:=24;
//Application.CreateForm(T FFons, FFons);
FFons:=TFFons.Create(Appli cation);
FFons.Show; //exception
end;
Then I tried this:
procedure TFPrincipal.Inicialitza;
begin
inherited;
Usuari:='';
TBPrincipal.Height:=24;
Application.CreateForm(TFF ons, FFons); //exception
//FFons:=TFFons.Create(App lication);
//FFons.Show;
end;
I haven't tried ShowMainForm:=False
About the inherited, i haven't used override because I'm inheriting from non-virtual procedures, and it executes well the inherited code, I'm sure that the problem doesn't come from ancestors. I think that the problem is in FFons.Show in which I have no code and so I haven't post it, but its parent class has code:
//this code is reached steping inside FFons.Show with F7
procedure TFBackground.FormShow(Send er: TObject);
begin
Inicialitza;
end;
//this code executes step by step perfectly but at the end
//gives the exception
procedure TFBackground.Inicialitza;
begin
width:=screen.Width;
top:=70;
height:=screen.Height-100;
WindowState:=wsMaximized;
BorderStyle:=bsNone;
//exception at finish
end;
What is wrong? :o
I've tried it and got the same exception. When calling FFons.Show:
procedure TFPrincipal.Inicialitza;
begin
inherited;
Usuari:='';
TBPrincipal.Height:=24;
//Application.CreateForm(T
FFons:=TFFons.Create(Appli
FFons.Show; //exception
end;
Then I tried this:
procedure TFPrincipal.Inicialitza;
begin
inherited;
Usuari:='';
TBPrincipal.Height:=24;
Application.CreateForm(TFF
//FFons:=TFFons.Create(App
//FFons.Show;
end;
I haven't tried ShowMainForm:=False
About the inherited, i haven't used override because I'm inheriting from non-virtual procedures, and it executes well the inherited code, I'm sure that the problem doesn't come from ancestors. I think that the problem is in FFons.Show in which I have no code and so I haven't post it, but its parent class has code:
//this code is reached steping inside FFons.Show with F7
procedure TFBackground.FormShow(Send
begin
Inicialitza;
end;
//this code executes step by step perfectly but at the end
//gives the exception
procedure TFBackground.Inicialitza;
begin
width:=screen.Width;
top:=70;
height:=screen.Height-100;
WindowState:=wsMaximized;
BorderStyle:=bsNone;
//exception at finish
end;
What is wrong? :o
if you don't override then there's nothing to inherit :)
just try it without .Show :)
if it doesn't show the form then create it in the project file and use .Show after you create it
Application.Initialize;
FInicialitza := TFInicialitza.Create(nil); // later on you free it yourself so set it's owner as nil
FInicialitza.Show;
FInicialitza.Update;
// I'm guessing you have it this way coz you don't want FInicialitza as your main form - a splash screen readin from it's name :)
// your mainform
Application.CreateForm(TFP rincipal, FPrincipal);
// create your FFons form here
Application.CreateForm(TFF ons, FFons);
FFons.Show; // this really odda work if you remove all the .Create and .Show from the Inicialitza procedure
Application.CreateForm(TFM odulDades, FModulDades);
Application.CreateForm(TFI nicialitza , FInicialitza);
Application.CreateForm(TFI dentitat, FIdentitat);
Application.CreateForm(TFC artera, FCartera);
Application.CreateForm(TFO peracio, FOperacio);
FInicialitza.Hide;
FInicialitza.Free;
ServeisG:=TServeis.Create( 'BDProject e');
try
Application.Run;
finally
ServeisG.Free;
end;
this should work ...
just try it without .Show :)
if it doesn't show the form then create it in the project file and use .Show after you create it
Application.Initialize;
FInicialitza := TFInicialitza.Create(nil);
FInicialitza.Show;
FInicialitza.Update;
// I'm guessing you have it this way coz you don't want FInicialitza as your main form - a splash screen readin from it's name :)
// your mainform
Application.CreateForm(TFP
// create your FFons form here
Application.CreateForm(TFF
FFons.Show; // this really odda work if you remove all the .Create and .Show from the Inicialitza procedure
Application.CreateForm(TFM
Application.CreateForm(TFI
Application.CreateForm(TFI
Application.CreateForm(TFC
Application.CreateForm(TFO
FInicialitza.Hide;
FInicialitza.Free;
ServeisG:=TServeis.Create(
try
Application.Run;
finally
ServeisG.Free;
end;
this should work ...
also, what's in the OnShow of your FFons?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Impressive, you got it Cynna. That was because I could not call FFons.Show from anywhere. As I promised 150+ points for an exellent answer, here you have these 200. :) Thanks to all of you for your interest in this question!!
If I understood you right, the possible solution is the following (the shortest I know by this moment):
procedure TFormA.FormMouseDown(Sende
Shift: TShiftState; X, Y: Integer);
begin
FormB.Show;
end;
procedure TFormA.FormShow(Sender: TObject);
begin
PostMessage(Handle, WM_LBUTTONDOWN, 0, 0);
PostMessage(Handle, WM_LBUTTONUP, 0, 0);
end;
Although, to my mind more reasonable is to create a new Message and override TFormA.WndProc method.
(this solution is very simple as well).
Sincerely,
Nestorua.