发信人: teleme(PassWord)
整理人: teleme(2001-02-11 10:46:50), 站内信件
|
主题:防止DELPHI程序的重入
发信人: yeniu()
使用C语言进行过Windows编程的人都知道,WinMain函数是Windows程序的入口,
它有四个参数,其中HPrevInst保存了16位应用程序的前一个实例的Hinstance值
,第一个实例的值为0。然而,不幸的是,对于32位应用程序,该值总为0。因此
,当我们编制32位程序的时候,不能利用该参数来防止应用程序运行多个实例。
在用DELPHI编制的32位应用程序中,我们可以利用Windows API函数的调用来防止
应用程序运行多个实例。在这里,我们将利用FindWindow函数来查找系统中是否
已有应用程序主窗体的实例。若有,则激活前一实例的主窗体;若无,则运行程
序。下面是我们将要用到的Windows API函数。
1. FindWindow函数。该函数查找指定的窗口,说明为:
HWND FindWindow(LPCTSTR lpClassName,LPCTSTR lpWindowName );
lpClassName为窗口类的名称,lpWindowName为要查找的窗口的名称。如
果
执行成功,返回窗口句柄,否则返NULL。
2. IsWindowVisible函数,查看指定窗口是否可见。参数为窗口句柄,返回值为
BOOL型。
3. SetForegroundWindow函数,将指定窗口置为活动窗口。参数为窗口句柄,返
回值为BOOL型。
为了防止程序重入,我们在程序初始化之前调用FindWindow查找是否存在程序实
例,若无,程序初始化、创建窗体并运行;若有,则执行激活前一实例操作。程
序中定义了一个wm_user消息及响应。下面是一个演示性程序的源代码:
program onedemo; //onedemo.dpr的内容
uses //必须加入windows和Dialogs单元
Forms,windows,Dialogs,onun1 in 'onun1.pas' {MainForm};
{$R *.RES}
var Hwnd:THandle;
begin
Hwnd:=FindWindow('TForm1','MainForm'); //查找窗口实例
if Hwnd=0 then begin
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end
else begin
if not IsWindowVisible(Hwnd) then
PostMessage(Hwnd,wm_user,0,0); //给窗口实例发送wm_user消
息
SetForegroundWindow(Hwnd); //置窗口为活动窗口
end;
end.
unit onun1; //onun1.pas的内容
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dia
logs,
StdCtrls;
const wm_user=200; //消息常量
type
TMainForm = class(TForm)
Label1: TLabel; //用于在主窗体显示一段信息
private
{ Private declarations }
public
{ Public declarations }
procedure wmuser(var Msg:TMessage);
Message wm_user;
end;
var
MainForm: TMainForm;
implementation
{$R *.DFM}
procedure TMainForm.wmuser(var Msg:TMessage); //消息响应
begin
Application.Restore; //恢复Application,因为当窗口最小化时,
//SetForegroundWindow无法将其置为活动
end;
end.
程序在DELPHI 3.0和Windows 95下通过。
|
|