Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Bringing "disowned" child forms to front



Permlink Replies: 2 - Last Post: Feb 13, 2018 6:28 AM Last Post By: Damon Theis
Damon Theis

Posts: 4
Registered: 12/22/17
Bringing "disowned" child forms to front
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 12, 2018 1:35 PM
This is getting pretty frustrating. I have a VCL front end for a database with lots of forms. I want to be able to see all open forms on the taskbar in the group rather than the single taskbar icon for the main form.
I have accomplished this by using doing the following:

application.MainFormOnTaskBar := true;
placed in the project source directly after the application.create form statement for the main form.

protected
procedure CreateParams(var Params: TCreateParams) ; override;
placed on each form
along with

procedure TForm1.CreateParams(var Params: TCreateParams) ;
begin
inherited;
Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
Params.WndParent := GetDesktopWindow;

This creates the desired result, but now all child windows show behind the main form unless set to fsstayontop which is not desired for some forms. Setfocus on show has no effect. popupmode changes have no effect either.
Why can't I call a form2.show and get it to display in front?
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Bringing "disowned" child forms to front
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 12, 2018 2:26 PM   in response to: Damon Theis in response to: Damon Theis
Damon Theis wrote:

This is getting pretty frustrating.

That is what happens when you choose to not follow standard UI
practices. You are fighting against what the OS wants you to do.

I have a VCL front end for a database with lots of forms.

Why do you have lots of Forms to begin with? That is not a good UI
choice.

I want to be able to see all open forms on the taskbar in the group
rather than the single taskbar icon for the main form.

All windows created in the same process are grouped together on a
single Taskbar button by default. This is by design. If you want to
display multiple taskbar buttons for different windows, or even control
your own grouping, you need to assign an explicit Application User
Model ID to each individual window:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459.aspx

If different windows owned by one process require different
AppUserModelIDs to control taskbar grouping, use
SHGetPropertyStoreForWindow() to retrieve the window's property store
and set the AppUserModelID as a window property.
...
To separate certain windows from a set in the same process, use the
window's property store to apply a single AppUserModelID to those
windows you want to separate, and then apply a different AppUserModelID
to the process. Any window in that process that was not explicitly
labeled with the window-level AppUserModelID inherits the
AppUserModelID of the process.

I have accomplished this by using doing the following:

All that does is forces each Form window to have its own Taskbar
button, but it does nothing to control the grouping of those buttons.
That is where AppUserModelIDs come into play. If you don't want the
Form windows to be grouped together at all, give each window a unique
AppUserModelID.

This creates the desired result, but now all child windows show
behind the main form unless set to fsstayontop which is not desired
for some forms.

That is because you changed the parent window (from the Win32 API's
perspective, not the VCL's perspective) to be the desktop window. If
you don't want the child windows to appear behind the main Form window,
then you must set the main Form window as the parent window (and you
don't need to override CreateParams() to do that, you can use the
TForm.PopupParent property instead). Only unowned windows with the
WS_EX_APPWINDOW style can appear on the Taskbar automatically, but you
can use the ITaskbarList.AddTab() method to add a button manually for
any HWND you want:

https://msdn.microsoft.com/en-us/library/windows/desktop/bb774646.aspx

--
Remy Lebeau (TeamB)
Damon Theis

Posts: 4
Registered: 12/22/17
Re: Bringing "disowned" child forms to front
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 13, 2018 6:28 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thank you for the detailed response. Now I understand how it works.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02