Delphi模拟最小化恢复关闭按纽

https://yq.aliyun.com/wenji/96083

本文讲的是Delphi模拟最小化恢复关闭按纽, 我们做多文档应用程序开发时,如果在主From中指定mainMenu时,在主菜单上右角上会自动出现最小化,恢复,关闭按纽,但主菜单放入Toolbar等中时,该三个按纽不会自动出现,因此需要编程实现

我们做多文档应用程序开发时,如果在主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.