Mike Torrettinni 198 Posted March 20, 2020 I have an example where I create multiple instances of FormX from Main Form. When FormX are created, I can focus individual form or Main Form without problems, but as soon as one of the forms uses ShowMessage or (another Form.ShowModal) all forms are blocked, and waiting for focus to go back to the form. Screenshot of MainForm and 3x FormX, and I can focus any of them - forms are shown by Show method As soon as one of the forms uses ShowMessage('msg...'), the focus is on the message window and none of the other forms can be focused until this message window is closed: This is very simple example, I create forms like this: procedure TForm8.Button1Click(Sender: TObject); var vNewForm: TFormX; begin vNewForm := TFormX.Create(Application); fForms.Add(vNewForm); fForms.Last.Show; end; Is there anyway how to be able to work with other forms, even though one of them is waiting for another window (dialog box, or another Form) to close? Share this post Link to post
Attila Kovacs 629 Posted March 20, 2020 because showmessage pops up a form in modal mode? 1 Share this post Link to post
Anders Melander 1782 Posted March 20, 2020 Um... Because it's a modal dialog. If it didn't block it wouldn't be modal. Share this post Link to post
Mike Torrettinni 198 Posted March 20, 2020 Ok, I see. So, unless I create new process for each new form, I can't prevent modal mode to block all opened forms? Share this post Link to post
Mike Torrettinni 198 Posted March 20, 2020 (edited) So, what I'm trying to do: I have monitoring application and can monitor different different data, files, folders, disks... main form lists all available services to monitor and user selects which ones he wants to monitor and opens up new form with all the details. So, user can have multiple forms open and can work with the monitored data. It can happen that one of the monitored services need attention or connection get lost. In this case a ShowMessage (or new Form.ShowModal) is supposed to alert user with message, while other forms should continue monitoring. User can then decide to reconnect or close the form that is showing an alert, while other should just continue monitoring. So, a modal window that blocks only the form it was called from, would be really useful in this case. Any ideas? Edited March 20, 2020 by Mike Torrettinni Share this post Link to post
Remy Lebeau 1393 Posted March 20, 2020 49 minutes ago, Mike Torrettinni said: It can happen that one of the monitored services need attention or connection get lost. In this case a ShowMessage (or new Form.ShowModal) is supposed to alert user with message, while other forms should continue monitoring. User can then decide to reconnect or close the form that is showing an alert, while other should just continue monitoring. Then don't use ShowMessage() for that. It displays a modal TForm whose owner window (in Win32 API terms, not VCL terms) is the currently active TForm. An owned window is always on top of its owning window. For what you describe, use a normal TForm instead of ShowMessage(). Set its PopupParent property to the monitoring TForm that needs attention, and then show the popup TForm. This way, the popup Tform stays on top of only its monitoring TForm, but other TForms can appear on top of the popup TForm. Otherwise, change your UI to not use a popup TForm at all. Put a visible message inside the TForm that needs attention. 3 1 Share this post Link to post
David Heffernan 2345 Posted March 20, 2020 Yeah, modal dialogs and popup are deeply invasive. Find a different way to let the user know. 2 Share this post Link to post
Mike Torrettinni 198 Posted March 20, 2020 Great, thanks! Also annoying thing about multiple forms opened is that ShowMessage can show up behind the form, and since it's modal, sometimes you can't access it to close it - annoying. 4 hours ago, Remy Lebeau said: Otherwise, change your UI to not use a popup TForm at all. Put a visible message inside the TForm that needs attention. Saw and interesting example where the Form was dimmed, but the notification message was not - very noticeable and no modal windows. Share this post Link to post
Anders Melander 1782 Posted March 21, 2020 3 hours ago, Mike Torrettinni said: Saw and interesting example where the Form was dimmed, but the notification message was not - very noticeable and no modal windows. Sounds like an example of doing something just because you can. Share this post Link to post
Mike Torrettinni 198 Posted March 21, 2020 45 minutes ago, Anders Melander said: Sounds like an example of doing something just because you can. Something new and I will probably go through a few variations until I end up with something I'm OK with. You should see how I choose icons for my projects, I can get crazy picky for that perfect icon and color... 🙂 Share this post Link to post
Fr0sT.Brutal 900 Posted March 24, 2020 On 3/21/2020 at 1:11 AM, Mike Torrettinni said: Saw and interesting example where the Form was dimmed, but the notification message was not - very noticeable and no modal windows. This has come from web, I guess. It's a very frequent pattern there Share this post Link to post
WpgnGaming 0 Posted April 14, 2020 why dont you just create a custom form and use that in place of the dlg then you have much more control over it. Share this post Link to post
Mike Torrettinni 198 Posted April 14, 2020 2 minutes ago, WpgnGaming said: why dont you just create a custom form and use that in place of the dlg then you have much more control over it. Well, idea was to have modal window over the non-modal form that needs attention from user (either to refresh the info, close or do something else that needs user attention/intervention). So, what would modal custom form be different than modal message window? It would still block all other forms, right? Share this post Link to post
WpgnGaming 0 Posted April 14, 2020 just make it, so it dont stay on top by having it set to normal in plaace of ontop FormStyle := fsNormal; Share this post Link to post
Mike Torrettinni 198 Posted April 14, 2020 I need to make it on top of the form that calls it - so it 'blocks' the original form from user access, until message form is closed. Would you suggestion work like this? Share this post Link to post
ConstantGardener 31 Posted April 14, 2020 ...when u use TMS UI Pack try TAdvSmartMessageBox. Stay's on top of the owner form, blend's in and out smooth and so on. 1 Share this post Link to post
Remy Lebeau 1393 Posted April 14, 2020 (edited) 6 hours ago, Mike Torrettinni said: I need to make it on top of the form that calls it - so it 'blocks' the original form from user access, until message form is closed. That is exactly what a TForm's PopupParent property is meant for. A TForm stays on top of its PopupParent Form, it can never go behind the PopupParent. Like I described earlier in this same discussion. Otherwise, just use a TFrame instead. Put it on top of the TForm that needs to be "blocked", and disable access to the TForm's controls until the TFrame is dismissed. Edited April 14, 2020 by Remy Lebeau 1 Share this post Link to post
aehimself 396 Posted April 15, 2020 (edited) Talking from an end-user perspective I'd go insane if one application would open tens of forms. I have one screen only and it will be polluted within seconds. What I would do is to have only one form, with a list on the left and a PageControl on the right. Instead of forms, create a new TabSheet for the monitors. When there is an alert, you can change the ImageIndex property to change the icon of the tab sheet; signaling the user that attention is needed. As for the "messages" I would put an invisible panel inside every tab sheet, on top of everything. It would contain only a TMemo and a button to dismiss. This way if multiple alerts are generated without interaction, you can append it to the memo instead of having 3-4 popup windows for a single monitor. Edited April 15, 2020 by aehimself 1 Share this post Link to post
Mike Torrettinni 198 Posted April 15, 2020 3 minutes ago, aehimself said: Talking from an end-user perspective I'd go insane if one application would open tens of forms. I have one screen only and it will be polluted within seconds. Yes, of course, make sense. Unless you use 'open in new window' option for each resource you want monitored live data. 4 minutes ago, aehimself said: As for the "messages" I would put an invisible panel inside every tab sheet, on top of everything. It would contain only a TMemo and a button to dismiss I tested similar option, too. With good results. 15 hours ago, Remy Lebeau said: That is exactly what a TForm's PopupParent property is meant for. A TForm stays on top of its PopupParent Form, it can never go behind the PopupParent. Like I described earlier in this same discussion. Otherwise, just use a TFrame instead. Put it on top of the TForm that needs to be "blocked", and disable access to the TForm's controls until the TFrame is dismissed. Thanks, I have to put this on hold for a little while, so when I get back to it, I will see what implementation will be suitable. Share this post Link to post
aehimself 396 Posted April 15, 2020 (edited) 33 minutes ago, Mike Torrettinni said: Yes, of course, make sense. Unless you use 'open in new window' option for each resource you want monitored live data. Yes, makes sense; did not think of this. What you can do is to have a TFrame with basic functionality (placeholder for the monitor, invisible panel, etc) and add a "pop out" button there. When you click it, you simply create a TForm and move the current TFrame on that new form. Just, don't forget to free the tabsheet 🙂 I was also experimenting with auto-docking tabsheets a while ago. When you drag them out they turned to forms automatically, and vice versa. Unfortunately though the performance was so bad (flickering and lagging) that I abandoned the idea. Most probably I was doing something wrong; you can look in this direction too instead of a pop-out button. Edit: Seems pretty easy, I don't know what I messed up before. Edit-edit: It works, but the flickering is still there when dragging around the "child" window; even if DoubleBuffered is on. If you don't want to watch the video: Set DockSite of the PageControl to True. Set DragKind of the "child" form to dkDock and in the OnClose event set the Action to caFree. Then, create your "child" forms like this: Var f: TForm2; begin f := TForm2.Create(Application); f.ManualDock(PageControl1); f.Show; End; Edited April 15, 2020 by aehimself Share this post Link to post
PizzaProgram 9 Posted December 10, 2022 On 3/20/2020 at 11:11 PM, Mike Torrettinni said: Also annoying thing about multiple forms opened is that ShowMessage can show up behind the form, and since it's modal, sometimes you can't access it to close it - annoying. I have the same problem too. As it turned out, it is caused by a 3th party component, that is "overriding" all forms. For me it was the "skinning all form" component called: sSkinManager created by: AlphaSkins Had to turn OFF automatic skinning rules by setting at Design time: SkinManager1.SkinningRules := []; But I'm not sure if that's fixing it properly. I've also just created my own custom ShowMessage dialog form, ... but yet looking for a way to override all "ShowMessage(...)" function everywhere in my program. Share this post Link to post
programmerdelphi2k 237 Posted December 11, 2022 you can use "NotificationCenter" class in MSWin10 !!! Share this post Link to post