Jump to content
FabDev

SDI <-> MDI forms

Recommended Posts

Hello,

 

Following this  topic which finish to speak about MDI 😛 :

 

 

 

About MDI component to TDI ( Tabbed Document Interface ). An efficient component exists since a long time in DevExpress component library :

https://docs.devexpress.com/VCL/155103/ExpressBars/fundamentals/tabbed-mdi-manager

https://docs.devexpress.com/VCL/dxTabbedMDI.TdxTabbedMDIManager

 

After tested to convert a MDI application to a SDI application which was too complicated for end users they use TDI the best world of SDI/MDI.

The only thing I don't succeed is to transform a MDI (TDI) form to a SDI one (and SDI -> MDI) without fully recreate it. Purpose  is to do like webbrowser when you drop a tab outside.

With recreate a form it it not very difficult :

procedure TMyForm.Loaded;
begin 
   inherited;
  // default FormStyle := fsMDI 
   if gSDIAsked then
      FormStyle := fsNormal; 
end; 

 

Any idea to switch a form SDI <-> MDI without recreate it ?

 

Edited by FabDev

Share this post


Link to post

I used to work on a project that allowed the user to switch between SDI and MDI. We used DevExpress, FWIW.

 

As far as I can see from the code, all I did to make it work was set Visible=False on the child form before changing FormStyle and set Visible=True after.

You'll also need to adjust the size/position and maybe also the BorderIcons; In our application, we hid the Maximize button in MDI mode because the maximized form would hide the MDI icons (the buttons representing the other, minimized, MDI children) and the user would get confused. As far as I recall we also manually managed the layout of child-forms in MDI mode.

 

Also, and I'm working from 6-7 year old memory here, I believe you need to have Formstyle=fsMDIForm on the main form and keep it that way. MDI child forms are made visible in their constructor (TCustomForm.Create probably) or when FormStyle is set. To avoid that, in the child form constructor, you need to Include(FFormState, fsCreating) before setting FormStyle, set FormStyle and then Exclude(FFormState, fsCreating). You also need to Exclude(FFormState, fsVisible) to avoid the form being shown when the constructor exits.

Share this post


Link to post
2 hours ago, FabDev said:

About MDI component to TDI ( Tabbed Document Interface ). An efficient component exists since a long time in DevExpress component library :

https://docs.devexpress.com/VCL/155103/ExpressBars/fundamentals/tabbed-mdi-manager

https://docs.devexpress.com/VCL/dxTabbedMDI.TdxTabbedMDIManager

This is a bit different from what were are talking about in the other topic. MDI is very different from tabbed.

Share this post


Link to post
23 minutes ago, David Heffernan said:

MDI is very different from tabbed. 

 

I'am not agree Tabbed/TDI = MDI (with child alclient) with tab. Create a MDI application and add a pagecontrol (where 1 tabsheet = 1 mdichild) on top you have a basic TDI application.

Form me a TDI is a sub-type of MDI :

https://en.wikipedia.org/wiki/Comparison_of_document_interfaces

And Embarcadero seems to do that have done Devexpress some years ago :

https://blogs.embarcadero.com/whats-coming-in-delphi-and-cbuilder-libraries/

Edited by FabDev

Share this post


Link to post
2 hours ago, Anders Melander said:

In our application, we hid the Maximize button in MDI mode because the maximized form would hide the MDI icons (the buttons representing the other, minimized, MDI children) and the user would get confused.

The minimized MDI children even when showing are confusing except for the well seasoned operator who is using them to find a minimized window in an Excel workspace display.   

 

Any MDI application should have the task bar menu synched up to the showing windows. Allowing the user to readily select windows in different running apps. 

 

As for snap hovering--good luck.   

Share this post


Link to post
2 hours ago, FabDev said:

 

I'am not agree Tabbed/TDI = MDI (with child alclient) with tab. Create a MDI application and add a pagecontrol (where 1 tabsheet = 1 mdichild) on top you have a basic TDI application.

Form me a TDI is a sub-type of MDI :

https://en.wikipedia.org/wiki/Comparison_of_document_interfaces

And Embarcadero seems to do that have done Devexpress some years ago :

https://blogs.embarcadero.com/whats-coming-in-delphi-and-cbuilder-libraries/

Here's my MDI app

 

mdi.thumb.png.21658c8fb4ab7f2476045ab161585958.png

 

How do I do this with tabs, bearing in mind I want to see both the child windows together.

Share this post


Link to post
36 minutes ago, David Heffernan said:

How do I do this with tabs, bearing in mind I want to see both the child windows together.

You would use a docking system instead which allows the panels to me moved and docked like the Delphi IDE does. My application works this way. (Bottom-right shows tabs for panels that can be grabbed and re-docked.)

 

image.thumb.png.220ded83faf293de2c05de8ac3857a3f.png

 

This video shows some of that in action.

 

 

  • Like 1

Share this post


Link to post
2 hours ago, Brandon Staggs said:

You would use a docking system instead

The problem with docking is that most users don't understand how to use it. I mean, if they have problems with maximized MDI forms, docking isn't going to be easy to understand.

 

That said, one could use docking with manual docking disabled. That way it's just used to organize the forms into a fixed layout.

Edited by Anders Melander

Share this post


Link to post
16 minutes ago, Anders Melander said:

The problem with docking is that most users don't understand how to use it. I mean, if they have problems with maximized MDI forms, docking isn't going to be easy to understand.

 

That said, one could use docking with manual docking disabled. That way it's just used to organize the forms into a fixed layout.

I agree. My application disables docking by default while allowing the user to choose from several optimized layouts and resize the panels with splitters. More advanced users can enable docking and completely customize the layout.

 

However, keep in mind we are talking about implementing a subset of MDI features. MDI on Windows is a particularly awful paradigm and is discouraged from use because it is hard to understand and creates an inconsistent windowing model. Moving to a docking system can update a program to get away from MDI but still allow the type of functionality David asked about.

Share this post


Link to post
12 hours ago, Anders Melander said:

The problem with docking is that most users don't understand how to use it.

 

I confirm only experienced users can handle docking correctly.

But the idea is not bad maybe only if each form can dock between each other in tabbed mode and alclient (= in full size of the destination form). Exactly do a web browser.

 

 

 

Share this post


Link to post

What I don't get in all this is that MDI child windows aren't docked. They are typically tiled. Yes there is cascade but surely nobody wants that. Tabbed is clearly superior to cascade.

 

So any discussion about MDI like GUI without true MDI needs to look at tiling.

Share this post


Link to post
On 6/21/2023 at 3:08 AM, David Heffernan said:

What I don't get in all this is that MDI child windows aren't docked. They are typically tiled. Yes there is cascade but surely nobody wants that. Tabbed is clearly superior to cascade.

 

So any discussion about MDI like GUI without true MDI needs to look at tiling.

I'm not sure what you mean. In any case, docked panels with splitters are "tiled" in that same sense and have the advantage of automatically correcting the size of the other "windows" when someone manually changes the size of a child window, to keep them "tiled." (Using the splitter.) Anyway, the Delphi IDE already does all of this, so you know the benefits or drawbacks of the system.

Share this post


Link to post
2 hours ago, Attila Kovacs said:

I can't imagine either of the above versions working with a multiple monitor system.

Mine works fine -- undock a panel and drag it wherever you want. I have lots of code written to handle dpi changes across monitors.

 

However you're putting your finger on a common problem with the MDI and panel windowing models. Once you start undocking panels they may as well be MDI windows, just not confined to the parent form. At that point you run into the drawback of the Windows model where these child windows can't participate properly with other application windows in the z order. Example would be, if you click on any of the undocked panels, the entire application comes to the front and covers other application windows. This is how it is on Windows and probably makes the most sense, but on Mac, each window of an application can fully participate in the z-ordering of all of the windows open on the desktop, not just within its own application. The move to SDI was a way to solve this on Windows but comes with its own pitfalls, which we are always trying to work around... There are no perfect solutions for multiple child windows of an application and it all depends on your application's needs and your users... there are ways, of course, to create top-level windows that can be interleaved with other application windows. but then you can't have them tiled/docked to a common parent window, etc.

Share this post


Link to post
14 minutes ago, Brandon Staggs said:

but on Mac, each window of an application can fully participate in the z-ordering

because the mac window manager is an MDI application itself

Share this post


Link to post
6 hours ago, Brandon Staggs said:

I'm not sure what you mean. In any case, docked panels with splitters are "tiled" in that same sense and have the advantage of automatically correcting the size of the other "windows" when someone manually changes the size of a child window, to keep them "tiled." (Using the splitter.) Anyway, the Delphi IDE already does all of this, so you know the benefits or drawbacks of the system.

Again that's not accurate. Imagine, say, 7 MDI child windows, tiled. You literally can't get splitters in a grid as 7 is prime.

 

I'm not sure anybody that's posted in this thread understand MDI tiling.

Share this post


Link to post
17 hours ago, David Heffernan said:

Again that's not accurate. Imagine, say, 7 MDI child windows, tiled. You literally can't get splitters in a grid as 7 is prime.

Any tiling configuration you can do with MDI you can do with a docking system. They're all rectangles. I get MDI, I have developed several MDI applications in the past. I think perhaps you're not understanding what you can do with panels. Maybe you could show me a screen shot of your application with a window layout that you don't think can be achieved with a docking system so I can understand what you mean.

Edited by Brandon Staggs

Share this post


Link to post
19 hours ago, Attila Kovacs said:

because the mac window manager is an MDI application itself

Well yeah, but it's a lot more than that. Bottom line is MacOS has a different windowing model than Windows. Personally I find the "menu bar at the top of the screen" paradigm to be absurdly ridiculous in an age of multiple large monitors on one desktop, but it still does have a few advantages.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×