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.
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!)
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...
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
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.