发信人: 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下通过。 
 
  
  
  | 
 
 
 |