【发布时间】:2010-09-05 17:48:41
【问题描述】:
我有一个用 Delphi 2006 编写的 MDI 应用程序,它以默认主题运行 XP。
有没有办法控制 MDI Children 的外观来避免每个窗口上的 XP 风格的大标题栏?
我尝试将MDIChildren 的BorderStyle 设置为bsSizeToolWin,但它们仍然呈现为普通表单。
【问题讨论】:
我有一个用 Delphi 2006 编写的 MDI 应用程序,它以默认主题运行 XP。
有没有办法控制 MDI Children 的外观来避免每个窗口上的 XP 风格的大标题栏?
我尝试将MDIChildren 的BorderStyle 设置为bsSizeToolWin,但它们仍然呈现为普通表单。
【问题讨论】:
所有你需要的 - 重载过程 CreateWindowHandle,像这样:
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.
【讨论】:
MDI 的工作方式与您正在尝试做的事情不一致。
如果您需要“MDI”格式,您应该考虑使用内置或commercial 对接包,并使用对接设置来模仿 MDI 的感觉。
在我的 Delphi 应用程序中,我经常使用 TFrame 并将它们作为主窗体的父级,并最大化它们以占据客户区。这为您提供了类似于 Outlook 外观的内容。它有点像这样:
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;
要使用它,您只需这样做:
MyForm.CurrentModule := TSomeFrame.Create(nil);
有一个很好的论点是你应该使用你使用的接口(创建一个 IModule 接口或其他东西)。我经常这样做,但它比这里解释的概念要复杂。
HTH
【讨论】:
感谢 onnodb
不幸的是,客户坚持使用 MDI 和较小的标题栏。
我已经找到了一种方法,即通过覆盖窗口 CreateParams 来隐藏标题栏,然后创建我自己的标题栏(带有一些用于移动的鼠标处理的简单面板)。效果很好,所以我想我可以让客户端运行它,看看它是否会......
【讨论】:
我认为没有;根据我的经验,Delphi 中的 MDI 受到其在 VCL 中的实现的非常严格的限制和控制(也许还有 Windows API?)。例如,不要尝试隐藏 MDI 子项(如果尝试,您会遇到异常,并且您必须跳过几个 API 箍来解决此问题),或者更改 MDI 子项的主菜单方式与宿主表单合并。
考虑到这些限制,也许您应该重新考虑一下为什么要首先使用特殊的标题栏?我想这些 MDI 的东西被标准化也有很好的理由 --- 你的用户可能会喜欢它:)
(PS:很高兴在这里看到一个 Delphi 问题!)
【讨论】: