我們做多文檔應用程序開發時,如果在主From中指定mainMenu時,在主菜單上右角上會自動出現最小化,恢復,關閉按紐,但主菜單放入Toolbar等中時,該三個按紐不會自動出現,因此需要編程實現。
實現原理:
按紐的實現,從Tbitbtn繼承下來最理想,但需要過濾TbitBtn的焦點響應消息,使其不能獲得焦點狀態。
按紐的功能的實現是比較關鍵的,Delphi中提供了標准action對象(Twindowclose)來實現關閉當前激活的子窗體的功能。
當沒有提供最小化及恢復功能的Action,因此有必須編程實現該兩個對象分別命名為TWindowMinimize和TWindowRestore;並且編程是十分簡單的。
為什麼要采用action來實現最小化,恢復和關閉MDI子窗體具體的功能呢,這是因為,Delphi已經實現了其狀態的自動變更。
另外,這三按紐必須保持在主界面的位置一直處於右上角.因此,需要在主窗體改變大小的時候,重新計算其位置。
由於只有子窗體最大化時,這三個按紐才能出現,因此,需要在idel事件中去判斷當前的子窗體的狀態,以便決定這三個按紐是否隱藏或可見.
具體代碼如下:
unit ufrmMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ActnList, AppEvnts, ImgList, StdCtrls, Buttons, StdActns, Menus,
ToolWin, ComCtrls;
type
//最大最小化按紐類
TMDIButton = class(TBitbtn)
private
public
//由於由Tbitn繼承而來,因此需要屏蔽其獲得焦點的消息
procedure wndproc(var message: Tmessage); override;
end;
TWindowMinimize = class(TWindowAction)
public
//按紐功能,將當前最前的子window狀態改為wsMinimize;
procedure ExecuteTarget(Target: TObject); override;
end;
TWindowRestore = class(TWindowAction)
public
//按紐功能,將當前最前的子window狀態改為wsNormal;
procedure ExecuteTarget(Target: TObject); override;
end;
TFrmMain = class(TForm)
//保存windows的最小化,恢復,關閉的圖標
MDIImageList: TImageList;
//當程序不忙時,判斷最大,最小化按紐的是否應該隱藏還是可見
ApplicationEvents1: TApplicationEvents;
//
ActMdiForm: TActionList;
ToolBar1: TToolBar;
MainMenu1: TMainMenu;
N1: TMenuItem;
open1: TMenuItem;
help1: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
procedure FormResize(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure open1Click(Sender: TObject);
private
//模擬mdiform窗體最小化,關閉及恢復按紐對象
BtnMin, BtnRestore, BtnClose: TMDIButton;
Windowclose: TWindowClose;
WindowMinimize: TWindowMinimize;
WindowRestore: TWindowRestore;
procedure SetMDIFormActionPos;
public
{ Public declarations }
end;
var
FrmMain: TFrmMain;
implementation
{$R *.dfm}
procedure TFrmMain.FormCreate(Sender: TObject);
begin
//建立關閉Button
BtnClose := TMDIButton.Create(self);
BtnClose.Visible := false;
BtnClose.Parent := self;
BtnClose.Width := 16;
Btnclose.Height := 15;
//建立關閉功能Action
WindowClose := TWindowClose.Create(nil);
//指定其圖標
WindowClose.ActionList := ActMdiForm;
WindowClose.ImageIndex := 2; //關閉;
WindowClose.Caption := '';
//將action與button關聯
BtnClose.Action := WindowClose;
BtnClose.BringToFront;
BtnClose.Visible := false;
//建立最小化Button
BtnMin := TMDIButton.Create(self);
BtnMin.Visible := false;
BtnMin.Parent := self;
BtnMin.width := 16;
BtnMin.height := 15;
//建立最小化功能action
WindowMinimize := TWindowMinimize.Create(nil);
//指定其圖標
WindowMinimize.ActionList := ActMdiForm;
WindowMinimize.Caption := '';
WindowMinimize.ImageIndex := 0;
//將action與button關聯
BtnMin.Action := WindowMinimize; //最小化
BtnMin.BringToFront;
BtnMin.Visible := false;
//建立恢復功能Button
BtnRestore := TMDIButton.Create(self);
BtnRestore.Visible := false;
BtnRestore.Parent := self;
BtnRestore.Width := 16;
BtnRestore.height := 15;
//建立恢復功能action
WindowRestore := TWindowRestore.Create(nil);
//指定其圖標
WindowRestore.ActionList := ActMdiForm;
WindowRestore.Caption := '';
WindowRestore.ImageIndex := 1;
//將action與button關聯
BtnRestore.Action := WindowRestore;
BtnRestore.BringToFront;
BtnRestore.Visible := false;
//設置按紐位置,位置保持在主界面上相對不變
SetMDIFormActionPos;
end;
procedure TFrmMain.ApplicationEvents1Idle(Sender: TObject;
var Done: Boolean);
var
show: boolean;
begin
//當前子窗體的狀態為最大化時,顯示三個按紐
show := (self.ActiveMDIChild <> nil) and (self.ActiveMDIChild.WindowState =
wsMaximized);
if assigned(BtnClose) and BtnClose.Visible <> Show then
BtnClose.Visible := Show;
if assigned(BtnMin) and BtnMin.Visible <> Show then
BtnMin.Visible := Show;
if assigned(BtnRestore) and BtnRestore.Visible <> Show then
BtnRestore.Visible := Show;
end;
//設置按紐的相對位置不變
procedure TfrmMain.SetMDIFormActionPos;
begin
if assigned(BtnClose) then
begin
BtnClose.left := Width - 26;
BtnClose.top := 6;
end;
if assigned(BtnRestore) then
begin
BtnRestore.Left := Width - 44;
BtnRestore.Top := 6;
end;
if assigned(BtnMin) then
begin
BtnMin.Left := Width - 60;
BtnMin.Top := 6;
end;
end;
procedure TFrmMain.FormResize(Sender: TObject);
begin
SetMDIFormActionPos;
end;
procedure TFrmMain.FormDestroy(Sender: TObject);
begin
//釋放資源
if assigned(BtnClose) then
begin
WindowClose.ActionList := nil;
WindowClose.free;
BtnClose.Free;
BtnClose := nil;
end;
if assigned(BtnRestore) then
begin
WindowRestore.ActionList := nil;
WindowRestore.free;
BtnRestore.Free;
BtnRestore := nil;
end;
if assigned(BtnMin) then
begin
WindowMinimize.ActionList := nil;
WindowMinimize.free;
BtnMin.Free;
BtnMin := nil;
end;
end;
{ TWindowRestore }
procedure TWindowRestore.ExecuteTarget(Target: TObject);
begin
inherited;
with GetForm(Target) do
ActiveMDIChild.WindowState := wsnormal;
end;
{ TMDIButton }
procedure TMDIButton.wndproc(var message: Tmessage);
begin
if message.msg = wm_SetFocus then exit;
inherited wndproc(message);
end;
{ TWindowMinimize }
procedure TWindowMinimize.ExecuteTarget(Target: TObject);
begin
inherited;
with GetForm(Target) do
ActiveMDIChild.WindowState := wsMinimized;
end;
procedure TFrmMain.open1Click(Sender: TObject);
begin
with Tform.create(self) do
begin
formstyle := fsMDIChild;
end;
end;
end.