Watch, Follow, &
Connect with Us

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


Welcome, Guest
Guest Settings
Help

Thread: How to prevent a child form from minimizing


This question is answered.


Permlink Replies: 9 - Last Post: Aug 27, 2015 1:55 AM Last Post By: Marco Cirinei
Marco Cirinei

Posts: 26
Registered: 12/28/99
How to prevent a child form from minimizing  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 25, 2015 7:51 AM
Hi all.
My first "serious" Windows Firemonkey application.
Let's say I don't want that child forms hide when main form minimizes.
I'm trying to translate to FMX a solution that works with VCL (WS_EX_APPWINDOW in the ExStyle and parent window handle set to the Desktop), with this code (Oncreate or onShow, it doesn't do what expected):

.......
frmHWnd := FmxHandleToHWND(Self.Handle);
SetWindowLong(frmHWnd, GWL_EXSTYLE, GetWindowLong(frmHWnd, GWL_EXSTYLE) or WS_EX_APPWINDOW);
winapi.windows.SetParent(frmHWnd, GetDesktopWindow);
.......

Using XE8 upd 1 on a Windows 7 VM.

Any idea of what am I doing wrong?
Thanks a lot.

Marco
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to prevent a child form from minimizing [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 25, 2015 9:26 AM   in response to: Marco Cirinei in response to: Marco Cirinei
Marco wrote:

Any idea of what am I doing wrong?

What is "Self" in this situation? In FireMonkey, only top-level TCommonCustomForm
objects have an HWND (for interaction with the OS), but child controls do
not.

--
Remy Lebeau (TeamB)
Marco Cirinei

Posts: 26
Registered: 12/28/99
Re: How to prevent a child form from minimizing [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 25, 2015 9:35 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Marco wrote:

Any idea of what am I doing wrong?

What is "Self" in this situation? In FireMonkey, only top-level TCommonCustomForm
objects have an HWND (for interaction with the OS), but child controls do
not.

--
Remy Lebeau (TeamB)

Hi Remy.
That code is executed in the OnCreate event of the child form that I want to "protect" (it's an infopoint application and I don't want that someone inadvertently could hide that form , simply minimizing the main form..). So it's the handle of the child form.
Thanks

Marco
Marco Cirinei

Posts: 26
Registered: 12/28/99
Re: How to prevent a child form from minimizing  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 26, 2015 11:14 AM   in response to: Marco Cirinei in response to: Marco Cirinei
Hi,
maybe I'm asking for something that isn't possible at actual state of development of Firemonkey...
Ok, but why can't I even use WindowsState to detect by myself the state of a main form of a blank FMX application?
Better: in the help I read: "Read WindowState to determine whether the form is minimized, maximized, or in a normal state."
Why do I always get "wsnormal"?
Thanks in advance.
Marco

Edited by: Marco Cirinei on Aug 26, 2015 8:28 PM
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to prevent a child form from minimizing [Edit]
Helpful
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 26, 2015 11:54 AM   in response to: Marco Cirinei in response to: Marco Cirinei
Marco wrote:

Why do I always get "wsnormal"?

On Windows, the FMX.Platform.Win unit has a WndProc() function to handle
window messages for all TCommonCustomForm objects. Its WM_WINDOWPOSCHANGED
message handler calls the Win32 GetWindowPlacement() function to get the
window's latest placement info, and then sets the Form's WindowState property
accordingly. So, for the WindowState to always be wsNormal suggests that
maybe GetWindowPlacement() is failing, or otherwise is never reporting the
window is actually minimized/maximized to begin with.

--
Remy Lebeau (TeamB)
Marco Cirinei

Posts: 26
Registered: 12/28/99
Re: How to prevent a child form from minimizing [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 26, 2015 2:58 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Marco wrote:

Why do I always get "wsnormal"?

On Windows, the FMX.Platform.Win unit has a WndProc() function to handle
window messages for all TCommonCustomForm objects. Its WM_WINDOWPOSCHANGED
message handler calls the Win32 GetWindowPlacement() function to get the
window's latest placement info, and then sets the Form's WindowState property
accordingly. So, for the WindowState to always be wsNormal suggests that
maybe GetWindowPlacement() is failing, or otherwise is never reporting the
window is actually minimized/maximized to begin with.

--
Remy Lebeau (TeamB)

Hi Remy and thanks a lot for your (usual) help.
But I need a bit more of it to get to the point.

Delphi 2007,VCL, Forms.pas
FWindowState := wsMinimized; is (eventually) executed when the application starts (Application,run, SW_SHOWMINNOACTIVE) and inside TCustomForm.UpdateWindowState.
The UpdateWindowState method is called (IMHO) only from TCustomForm.WMWindowPosChanging (changing)

Delphi XE8 , FMX, FMX.Platform.Win
LForm.WindowState is never modified inside the code for WM_WINDOWPOSCHANGING messages.
At the start of the code for WM_WINDOWPOSCHANGED messages (from line 2142), I see this:

........
if (Application.MainForm <> nil) and (LForm = Application.MainForm)
and (Placement.showCmd = SW_SHOWMINIMIZED) then
begin
PlatformWin.MinimizeApp;
Result := DefWindowProc(hwnd, uMsg, wParam, lParam);
end
-> ELSE
-> BEGIN
...........

The "problem" seems to be that this code (starting from line 2166):

case Placement.showCmd of
SW_SHOWMINIMIZED: LForm.WindowState := TWindowState.wsMinimized;
SW_SHOWMAXIMIZED: LForm.WindowState := TWindowState.wsMaximized;
else.......

is in the "ELSE BEGIN" portion, so is never executed when am FMX form gets minimized (?!).
This could explain why so many strange behaviours and difficulties trying to manage the minimization of my child FMX forms.
May someone confirm this?
Marco

P.S.
A little curiosity at line 2160: is it correct to find a BEGIN in that position of the source code..? ;(
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to prevent a child form from minimizing [Edit] [Edit]
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 26, 2015 3:22 PM   in response to: Marco Cirinei in response to: Marco Cirinei
Marco wrote:

FWindowState := wsMinimized; is (eventually) executed when the
application starts (Application,run, SW_SHOWMINNOACTIVE) and inside
TCustomForm.UpdateWindowState.

In VCL, TCustomForm.UpdateWindowState() is called only in response to the
WM_WINDOWPOSCHANGING message, yes. But only when the message's SWP_STATECHANGED
flag is enabled. Although FMX does handle WM_WINDOWPOSCHANGING, it does
not handle that particular flag.

Also, the TCustomForm.WindowState property is updated inside of TCustomForm.Resizing(),
which is called in response to WM_SIZE (which FMX does not process).

At the start of the code for WM_WINDOWPOSCHANGED messages (from
line 2142), I see this:

They must have added that in a more recent version of FMX. That condition
does not exist in XE2, for instance. So, in XE2, WindowsState should always
be updated. But, if newer versions are now checking for MainForm minimizing,
then yes, the MainForm's WindowState will not be updated in the WM_WINDOWPOSCHANGED
handler, unless it gets set indirectly when PlatformWin.MinimizeApp() is
called.

The "problem" seems to be that this code (starting from line 2166):

case Placement.showCmd of
SW_SHOWMINIMIZED: LForm.WindowState :=
TWindowState.wsMinimized;
SW_SHOWMAXIMIZED: LForm.WindowState :=
TWindowState.wsMaximized;
else.......

is in the "ELSE BEGIN" portion, so is never executed when am FMX form
gets minimized (?!).

Specifically, only when the MainForm is minimized. Other forms, like your
child forms, should fall into the 'else' block and get updated as expected.

--
Remy Lebeau (TeamB)
Marco Cirinei

Posts: 26
Registered: 12/28/99
Re: How to prevent a child form from minimizing  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 26, 2015 3:39 PM   in response to: Marco Cirinei in response to: Marco Cirinei
Yes Remy, correct.
I don't know if Embarcadero has to be warned of the problem (maybe a simple END at line 2159 could be what someone has forgotten).
So, if I still don't know how to avoid the minimization of a FMX child form when the main for is minimized, at least I can detect when the main is minimized and try some workaround (like reduce or hide the main and try to bring the childs forms maximized in the others monitors)
I'm experimenting now this solution with my app.
Thanks again!
Marco
Douglas Rudd

Posts: 314
Registered: 5/16/97
Re: How to prevent a child form from minimizing  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 26, 2015 7:16 PM   in response to: Marco Cirinei in response to: Marco Cirinei
If you only have one child window that you want to remain visible when you minimize the main window, you can make the old child window the main window and the old main window into a child window. Everything would operate as desired.
Marco Cirinei

Posts: 26
Registered: 12/28/99
Re: How to prevent a child form from minimizing  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 27, 2015 1:55 AM   in response to: Douglas Rudd in response to: Douglas Rudd
Douglas Rudd wrote:
If you only have one child window that you want to remain visible when you minimize the main window, you can make the old child window the main window and the old main window into a child window. > Everything would operate as desired.

Thank you Douglas but the app needs to have multiple childs concurrently opened (in more than one monitor).
For now Im thinking to completely avoid the minimization of the main form, letting it float in an angle of the desktop (ahem...shrinked to 200x200).
Marco

Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02