Dave Nottage 557 Posted November 6 A client has well established products that are based around the MDI model, and are using the concept of "desktops" by hiding/showing MDI children so that the state of the forms is maintained. The concept of hiding MDI children is actually not officially supported in Delphi, so to work around this, ShowWindow is called thus: ShowWindow(FormHandle, SW_SHOW); // or ShowWindow(FormHandle, SW_HIDE); ..where FormHandle is the handle of the MDI child being shown/hidden. This worked well, up until Delphi 12, when the message handling for forms was reimplemented, using TChildFormMessageHandler (in Vcl.Forms). The new (undesired) behaviour is that once a child form has ShowWindow called on it, then that form becomes active, the last form that was hidden becomes visible again. This can be reproduced using the attached project by using the following steps: Run the app Click File | Show Desktop 1 Click File | Show Desktop 2 Click File | Show Desktop 1 again Set focus to the visible form - the form that "belongs" to Desktop 2 becomes visible again As described above, this works OK in Delphi 11.3. At this point, reimplementing the app away from MDI is a non-option. I'm aware that whatever measures are needed will be a "hacky" workaround - it started out that way anyway. Now for the kicker: this is a package-based application, so I can't even "hack" the Vcl.Forms source. Using a "detours"-like solution might be an option. Any help with how to resolve this would be greatly appreciated. MDIIssue.zip Share this post Link to post
Brian Evans 105 Posted November 6 Could free the forms instead of hiding. Has other issues like losing state but they can be overcome. Adding saving/loading form state is useful between program runs as well so work can be resumed quicker. MDIIssue2.zip Share this post Link to post
DelphiUdIT 176 Posted November 6 (edited) Insert in every child forms this line in the OnCLose Event may be resolve the Issue ? procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := TCloseAction.caHide; end; Edited November 6 by DelphiUdIT Share this post Link to post
DelphiUdIT 176 Posted November 6 (edited) 5 hours ago, Brian Evans said: Could free the forms instead of hiding. Has other issues like losing state but they can be overcome. Adding saving/loading form state is useful between program runs as well so work can be resumed quicker. MDIIssue2.zip I used to loose Form states (or better don't care about them anymore) every time it is closed or hidden. These because all the states of the Form (like input datas, charts, state of the controls) will be resumed from a structure (typ. record or advanced record) when the Form is "reshow". Normally I "deep divide" all data values from graphic controls and save them to records, since these values may be (normally ARE) used and modified by other means. Only when I have DBAware controls I normally maintain the state of the Form (never destroy it or resume data when the Show methods are called). Edited November 6 by DelphiUdIT Share this post Link to post