views:

1282

answers:

9

Hi, yesterday I've started discussion on "MDI vs tabbed interface". I've asked whether should I continue developing my app as MDI-based, or should I embed the child forms into tab sheets. Someone pointed that I should use TFrames instead... My question is: why?

What are pros of using TFrames when embedding the form over TFrame? So far I don't know any, switching would only require me to rewrite some parts of code...

(I'm not going to use embedding at design time anyway!)

Thanks in advance

A: 

Frames are good when you want to repeat a "sub-form" multiple times in a form. I'd not use them for tabbed interfacing, as the embedded form is a better solution for MDI/Tabbed interface use.

mj2008
Please provide **any** reason why an embedded form would be a better solution than a frame.
mghie
mghie, I'm not arguing with you, however - please provide any reason **why not** ;) I'd really love to know why frames are better for multiple documents tabbed interface?
migajek
Exactly my thought: Who would go for embedded forms if he could just use frames instead? Frames are just so much less hassle. And even if you need it as a form later on, you can just create an empty form ad add the frame with align=alClient.
dummzeuch
Frames are missing some of the event handlers that are available on forms, e.g. FormCreate. Instead of assigning events you need to override some protected methods (e.g. Create or AfterConstruction for FormCreate).This can be slight disadvantage, but can make for clearer code.
Gerry
A: 

I think overlapping windows are very poor GUI design. Manipulating windows by dragging on their edges and corners is a burden on the user's attention, time, and wrists. Tabs neatly avoid this. If two windows do need to be shown at once (eg. for drag-and-drops across) consider tiling.

reinierpost
+4  A: 

Maybe you will find some answers in this thread: gui-design-multiple-forms-vs-simulated-mdi-tabs-vs-pagecontrol

Ralph Rickenbach
+9  A: 

Answering the comment to provide a reason why to use frames:

I would consider frames to be building blocks of the GUI, with design time combination of existing components to more advanced components. Before Delphi 5 one would have used a TCustomPanel descendant with child controls and registered this as the new component, ready to be dropped onto a form. Frames allow for the same thing with less hassle.

They allow you to concentrate on developing exactly the functionality you need, and nothing more. Done right you can then embed them into tab control sheets, into modal or modeless dialogs, into MDI child frames and into standard frames. You can even add several of them into one form - something one would probably not do with embedded forms. The point is that for maximum reusability a layered approach is often necessary, and frames help with that.

A frame is fit for embedding from the go. A form has to be adapted to not show a caption bar and border, normally one would override the CreateParams() and adjust the window style accordingly. There are a lot more form properties in the inspector that just don't make sense for an embedded form. IMHO one should use the most basic and generic entity that suffices. A form just is much more than a control container for embedding.

OTOH I don't know of any disadvantage of embedding a frame that embedding a form wouldn't have.

Edit:

There's a comment regarding events like OnCreate or OnShow that frames don't have. Actually, I'd consider that another advantage of frames, as event handlers don't have parameters, so a lot of stuff gets hard-coded in forms, necessarily.

Consider the case of per-user settings: in OnCreate there's not much information available, so one invariably ends up using a constant or the name of the form for the INI file section, making it very hard or even impossible to reuse the form or to create several instances of it. With frames on the other hand a method LoadSettings is the obvious way to do it, and it can carry the necessary parameters. That way control is returned to where it belongs, to the container of the embedded frame / form. Reusability is only possible if the behaviour can be adjusted from the outside.

For contained objects that are not components and need to be lifetime-managed, there are for example AfterConstruction and BeforeDestruction.

mghie
+1  A: 

I had same decision few years ago for one of our applications, we wanted to make it looks embedded forms, first I used the Frames and I wrote a class to manage it.

Later I found TLMDDisplayForm component from LMDTools, which making embedding forms inside it very easy task, it reduced the code used and we have more features.

one of main goals that we changed from frames to Forms was missing some events of TForm like: OnCreate, OnShow, OnActive which we use for some tasks in our applications, beside missing some properties such as: ActiveControl and other things I don't remember.

If you would like to go with Forms, I suggest you to use LMDTools which make the task easier for you, beside the basic version is free :-)

Mohammed Nasman
+1  A: 

For dynamically inserted forms/frames I personally prefer to use embedded forms over frames. Several versions back when one would edit a frame which was set to alClient, the frame would resize between edits and any controls which were aligned specific to the right of the frame would change position. When using embedded forms this didn't happen so I made the switch. I believe this issue is now fixed with later versions of Delphi.

I strongly agree with the points Mghie made earlier regarding the inability to pass information to the embedded form through notification events. To solve this I generally implement a series of interfaces in each embedded form for communication. This really simplifies the code, and allows for more generic implementations where you have a single "container" that will be dealing with many different types of embedded forms/frames. A few examples of this are available on my blog as part of the wizard framework I designed.

skamradt
A: 

Don't use frames, it's not a good OOP practice.

Tabbed UI is popular these days, but consider how to allow viewing the document side by side if this is needed.

Edwin Yip http://www.InnovationGear.com Mind Mapping Software for capturing ideas and organizing them visually.

Edwin
It's not a good OOP practice? Please, explain that!!!
Fabricio Araujo
Hi Fabricio, I changed my mind, I think I said that because I used frames many years ago in an improper way and that caused my bad impressions on it, it's my own fault ;) I read mghie's comments and tried using frames again and I found it's very useful, it's not against OOP if use frames properly.
Edwin
+2  A: 

Frame use the fastest load and without delay when creating the frame.

But the frame should be has a parent to embedded it. Disadvantage with no onCreate or onShow event has been triggered. but you can call with message for trigger onShow event like this one :

put on private section of frame:

procedure CMShowingChanged(var M: TMessage); message CM_SHOWINGCHANGED;

and then create the code like this :

procedure TFrame1.CMShowingChanged(var M: TMessage);
begin
  inherited;
  if Showing then
  begin
    // .... put your code for onShowing is triggered
  end
  else
  begin
    // .... put your code for onHiding is triggered
  end;
end;

Hope can helping you to consider embedded frame for GUI.

You may consider combined with PageControl to control your frame opening.

Manz

Manz
A: 

I think both should be used. For example, I have a "standard" frame that has a dbnavigator, dbgrid and datasource components which is very handy for the typical data browsing. Instead of inserting such components every time, I insert a frame that also has the ability to export its data (with JVCL :D) to several formats...but I know what I want to display at design time, so I suggest a very easy rule: if it is known at design time, use frames, otherwise use embedded forms.

However, keep in mind that forms were not designed to be embedded. Using them like so, its unnatural (as a vampire states when she buries her 80 old year daughter and she looked like 30 :D). The embedded form knows little about the one that owns it and can also (logically) assume that is not embedded.

Complementing that, a frame is a component, and so, when embedded (owned by) in a form, the form knows about it and the frame knows about the form (can use its methods and properties. An embedded one can also do that but requires extra coding)

Perhaps Embarcadero could give us a hand by creating a TEmbeddableForm or an interface for such purposes

Regards, Alvaro Castiello

Alvaro Castiello