返回首页

delphi实现子窗口只打开一个实现代码

时间:2013-07-01 23:52来源:知行网www.zhixing123.cn 编辑:麦田守望者

在做检验科试剂管理系统的时候,我突然发现一个问题。由于我是用菜单来控制功能窗口打开的,如果用户点击两次,就打开了两个窗口,如何解决这个问题?当更换了用户,用户权限变化了的时候,如何关闭原来的窗口?

这还不简单,声明一个窗口的全局变量不就OK了么,要关闭就直接form.close就卡可以了嘛!

但是如果窗口是动态创建的呢?如果我不想弄成全局变量,消耗大量内存呢?

首先想到程序只执行一个实例的方法,用互斥体?这将产生一个问题,你所有的窗口在加载之前都需要建立一个互斥变量,每个窗口你都去重载一次构造函数,你想累死我么?

既然不想保存类的变量,那么不如尝试一下windows窗口的特有属性,HWND,即窗口的句柄。

那么如何解决句柄存在的问题,即通过句柄可以判断这个窗口是否打开呢?吵吵找了半天,找到一个API函数IsWindow。

于是整个流程可以如下运作:

通过保存的句柄判断窗口是否存在->存在即不打开新窗口,不存在就打开新窗口并保存句柄。

关闭所有的窗口只需要向所有的句柄PostMessage WM_QUIT就行了。

我建立了一个类,代码和简单,如下:

unit FMForm; interface uses Winapi.Windows, Winapi.Messages,Data.Win.ADODB, System.Classes,System.Variants,System.SysUtils,Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus,Vcl.Grids,Comobj, StdCtrls; type FormInfo=record Caption:string[20]; Handle:HWND; end; type TFMForm= class(TObject) public function FormExist(ACaption:string):Boolean; function CaptionExist(ACaption:string):Boolean; procedure AddForm(ACaption:string;AHandle:HWND); procedure SetCaptionHandle(ACaption:string;AHandle:HWND); procedure AddCaptionHandle(ACaption:string;AHandle:HWND); procedure CloseAllForms(); private FForms:array of FormInfo; end; implementation function TFMForm.CaptionExist(ACaption:string):Boolean; var i:Integer; begin result:=False; for i := 0 to Length(FForms)-1 do begin if FForms[i].Caption=ACaption then begin Result:=True; Exit; end; end; end; function TFMForm.FormExist(ACaption:string):Boolean; var i:Integer; begin result:=False; for i := 0 to Length(FForms)-1 do begin if FForms[i].Caption=ACaption then begin if isWindow(FForms[i].Handle)=true then begin Result:=True; Exit; end else begin result:=False; Exit; end; end; end; result:=False; end; procedure TFMForm.AddForm(ACaption:string;AHandle:HWND); begin if CaptionExist(ACaption)=True then begin SetCaptionHandle(ACaption,AHandle); end else begin AddCaptionHandle(ACaption,AHandle); end; end; procedure TFMForm.SetCaptionHandle(ACaption:string;AHandle:HWND); var i:Integer; begin for i := 0 to Length(FForms)-1 do begin if FForms[i].caption=ACaption then begin FForms[i].Handle:=AHandle; Exit; end; end; end; procedure TFMForm.AddCaptionHandle(ACaption:string;AHandle:HWND); begin setlength(FForms,Length(FForms)+1); FForms[Length(FForms)-1].Caption:=ACaption; FForms[Length(FForms)-1].Handle:=AHandle; end; procedure TFMForm.CloseAllForms(); var i:Integer; begin for i := 0 to Length(FForms)-1 do begin PostMessage(FForms[i].Handle,WM_CLOSE,0,0); end; end; end.
使用方法也很简单:

if FFMForm.FormExist('使用记录')=false then //判断窗口是否存在 begin frmUseRecord:= TfrmUseRecord.Create(self); frmUseRecord.Show; FFMForm.AddForm('使用记录',frmUseRecord.Handle); end;

------分隔线----------------------------
标签(Tag):delphi delphi教程 delphi实例教程 delphi源代码
------分隔线----------------------------
推荐内容
猜你感兴趣