1. Mainform From1 is created when app starts
2. Form1 can become fullscreen (ie set border to none and maximize).
3. From2 has various buttons (like a toolbar) that needs to always be
on top of Form1 but not other apps.
4. I want Form2 to always stay on top of Form1.
After trying various StayOnTop etc code and much trial and error I
cannot get it to work as expected.
Bugs;
1. Form2 sometimes (no logic to the steps) goes behind Form1 so the
user has no buttons.
2. Form2 sometimes goes in front of all other Windows apps. So you
click to Windows Explorer and Form2 is in front. Clicking back and
forth a few times resolves the Z-Order.
Does anyone really know how to lock a form to another form in the
Delphi app alone? This is not for a system-wide stay on top form,
just for the single app. When form2 is visible it always must be
higher in the Z-Order than form1.
Thanks for any help. This is driving me mad.
TG
Have you investigated using Win API call to SetWindowPos() to set the
z-positions of the windows when you work within or away from the
application.
Also Application.NormalizeTopmosts/NormalizeAllTopmosts/
RestoreTopmosts may enable you to control the topmosticity of a form.
Alan Lloyd
Look at the code for the above methods of TApplication in Forms.pas &
also of GetTopmostWindows() (in Delphi VCL) to find out how to
manipulate windows z-order.
Alan Lloyd
> Does anyone really know how to lock a form to another form in the
> Delphi app alone?
From Win3.1 I know about child windows, which always stay on top of
their parents. If that window type is still available, it requires some
low level code to use it during form creation.
DoDi
Wasn't that as simple as setting some Parent property during CreateParams?
Groetjes,
Maarten Wiltink
>>> Does anyone really know how to lock a form to another form in the
>>> Delphi app alone?
>> From Win3.1 I know about child windows, which always stay on top of
>> their parents. If that window type is still available, it requires
>> some low level code to use it during form creation.
>
> Wasn't that as simple as setting some Parent property during CreateParams?
A correction: I meant *popup* windows, not child windows.
I'm not sure about "Parent" here; most probably it specifies the owner
of the window (hWndParent), with the wanted effect that a window always
sits on top of its owner. But there exist more implications.
Apart from that property the WNDCLASS styles distinguish between
WS_OVERLAPPED, WS_POPUP and WS_CHILD windows, what I had in mind.
DoDi
If I understand what you're trying to do, I think you need to rethink your design. It
sounds to me like a homegrown MDI.
If form2 is always going to be on top of form1, then why not just include it all on
one form? Or use a tab control?
Mike
TForm2 = class(TForm)
private
protected
procedure CreateParams(var Params: TCreateParams); override;
public
end;
Then for the CreateParams method...
procedure TFormOwned.CreateParams(var Params: TCreateParams);
begin
//let it be initialized like normal
inherited;
//set the parent window. but since Form2 is not a child window,
//then this field means the owner window
Params.WndParent:= Form1.Handle;
end;
Keep in mind that during the Form2 creation, the Form1 must already been
created. Otherwise you'll get exception error.
> This is one basic windowing feature that Delphi VCL is lacking.
> What you need is the window ownership feature.
> Like Maarteen Wiltink mentioned, you'll have to use CreateParams.
> Override your Form2 CreateParams method like below.
>
> TForm2 = class(TForm)
> private
> protected
> procedure CreateParams(var Params: TCreateParams); override;
> public
> end;
>
> Then for the CreateParams method...
>
> procedure TFormOwned.CreateParams(var Params: TCreateParams);
> begin
> //let it be initialized like normal
> inherited;
> //set the parent window. but since Form2 is not a child window,
> //then this field means the owner window
> Params.WndParent:= Form1.Handle;
> end;
>
> Keep in mind that during the Form2 creation, the Form1 must already been
> created. Otherwise you'll get exception error.
>
I've just used "SetParent(Form2.Handle,Form1.handle)"
Jamie
>> [...] Like Maarteen Wiltink mentioned, ...
I don't mind as much as I used to, but I'd like to _understand_ one of
these days: why do so many people double the 'e'?
>> Override your Form2 CreateParams method like below.
[...]
>> procedure TFormOwned.CreateParams(var Params: TCreateParams);
>> begin
>> //let it be initialized like normal
>> inherited;
>> //set the parent window. but since Form2 is not a child window,
>> //then this field means the owner window
>> Params.WndParent:= Form1.Handle;
>> end;
[...]
> I've just used "SetParent(Form2.Handle,Form1.handle)"
That even has a certain elegance to it.
Where exactly do you place that call?
Groetjes,
Maarten Wiltink
You _could_ change your name to Maartonly1en <g>.
Alan Lloyd
Uh, sorry. It's my keyboard having its own mind after accompanying me
for 16 years.
>> I've just used "SetParent(Form2.Handle,Form1.handle)"
>
> That even has a certain elegance to it.
>
> Where exactly do you place that call?
Been wondering the same.
The form has to be valid before you can do that, of course.
Jamie