tags:

views:

2496

answers:

5

I've got an MDI application written in Delphi 2006 which runs XP with the default theme. Is there a way of controlling the appearance of the MDI Children to avoid the large XP-style title bar on each window? I've tried setting the BorderStyle of the MDIChildren to bsSizeToolWin but they are still rendered as normal Forms.

A: 

I don't think there is; in my experience, MDI in Delphi is very strictly limited and controlled by its implementation in the VCL (and perhaps also by the Windows API?). For example, don't try hiding an MDI child (you'll get an exception if you try, and you'll have to jump through a couple of API hoops to work around that), or changing the way an MDI child's main menu is merged with the host form's.

Given these limitations, perhaps you should reconsider why you'd like to have special title bars in the first place? I guess there are also good reasons why this MDI stuff is standardized --- your users might appreciate it :)

(PS: nice to see a Delphi question around here!)

onnodb
A: 

Thanks onnodb

Unfortunately the client insists on MDI and the smaller title bar.

I have worked out one way of doing it which is to hide the title bar by overriding the windows CreateParams and then create my own title bar (simple panel with some Mouse handling for moving). Works well enough so I think I might run it by the client and see if it will do...

Marius
A: 

The way MDI works doesn't gel with what you're trying to do.

If you need the "MDI" format, you should consider using either the built-in or a commercial docking package, and use the docking setup to mimic the MDI feel.

In my Delphi apps, I frequently use TFrames and parent them to the main form, and maximizing them so they take up the client area. This gives you something similar to how Outlook looks. It goes a little something like this:

TMyForm = class(TForm)
private
  FCurrentModule : TFrame;
public
  property CurrentModule : TFrame read FModule write SetCurrentModule;
end;

procedure TMyForm.SetCurrentModule(ACurrentModule : TFrame);
begin
  if assigned(FCurrentModule) then
    FreeAndNil(FCurrentModule);  // You could cache this if you wanted
  FCurrentModule := ACurrentModule;
  if assigned(FCurrentModule) then
  begin
    FCurrentModule.Parent := Self;
    FCurrentModule.Align := alClient;
  end;
end;

To use it, you can simply do this:

MyForm.CurrentModule := TSomeFrame.Create(nil);

There is a good argument that you should use interfaces (creating an IModule interface or something) that you use. I often do that, but it's more complex than needed to explain the concept here.

HTH

Tim Sullivan
+3  A: 

All your need - overload procedure CreateWindowHandle, like this:

unit CHILDWIN;
interface
uses Windows, Classes, Graphics, Forms, Controls, StdCtrls;

type
  TMDIChild = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
    procedure CreateWindowHandle(const Params: TCreateParams); override;
  end;

implementation

{$R *.dfm}
procedure TMDIChild.CreateWindowHandle(const Params: TCreateParams);
begin
  inherited CreateWindowHandle(Params);
  SetWindowLong(Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
end;
end.
CoolMagic
A: 

Thank you very much from CoolMagic

asgarkz