You can put some code in the application start section to find whether or not there is another instance of itself is running.1. You can use the findwindow() function.
2. You can detect global atom using globalfindatom(), if find the atom, you do exit the current instance. if not found, use the globaladdatom() to add one.

解决方案 »

  1.   

    copy一段给你:1、对主窗口程序的改动:在主窗口(即程序创建的第一个窗口)中interface节加入
    const
    CM_RESTORE = WM_USER + $1000; {自定义的“恢复”消息}
    MYAPPNAME = "My Delphi Program";
    并在Form的定义的public节中加入
    procedure CreateParams(var Params: TCreateParams); override;
    Procedure RestoreRequest(var message: TMessage); message CM_RESTORE;
    在implementation节中加入
    {指定窗口名称}
    procedure TForm1.CreateParams(var Params: TCreateParams);
    begin
    inherited CreateParams(Params);
    Params.WinClassName := MYAPPNAME;
    end;{处理“恢复”消息}
    procedure TForm1.RestoreRequest(var message: TMessage);
    begin
    if IsIconic(Application.Handle) = TRUE then
    Application.Restore
    else
    Application.BringToFront;
    end;经过以上修改,程序的主窗口的类名已经被指定了,这是进行判断的基础。一般在程序刚开始运行的时候进行判断,所以还要对DPR文件进行修改。2、对DPR文件的改动在 uses 节中添加 windows、messages这两个单元加入下列语句,注意两个文件中常量CM_RESTORE和MYAPPNAME的定义必须一致
    const
    CM_RESTORE = WM_USER + $1000; {自定义的“恢复”消息}
    MYAPPNAME = "My Delphi Program";
    var
    RvHandle : hWnd;将下列语句插到程序最前部(在Application.Initialize之前)RvHandle := FindWindow(MYAPPNAME, NIL);
    if RvHandle > 0 then
    begin
      PostMessage(RvHandle, CM_RESTORE, 0, 0);
      Exit;
    end;
    这段程序的意思是如果找到一个类名相同的窗口,则向该窗口发送一个消息,并退出,而本例中原窗口收到该消息后会自动激活或从图标还原,从而达到了避免二次运行且能自动调出前一例程的目的。
      

  2.   

    copy_paste(木石三)用的是FindWindow
    我这边有另外一种方法,用的时候,你把该单元放到主窗口单元的Uses部分中即可:
    unit MultInst;interface
    const
      MI_QUERYWINDOWHANDLE=  1;
      MI_RESPONDWINDOWHANDLE=2;
      MI_ERROR_NONE=         0;
      MI_ERROR_FAILSUBCLASS= 1;
      MI_CREATINGMUTEX=      2;
      UNIQUE_APPSTR='unique application string';
    function GetMIError:integer;implementation
    uses
      Forms,Windows,SysUtils;
    var
      MessageID:integer;
      WProc:TFNWndProc;
      MutHandle:THandle;
      MIError:integer;function GetMIError:integer;
    begin
      Result:=MIError;
    end;function NewWndProc(Handle:HWND;Msg:integer;WParam,LParam:LongInt):Longint;stdcall;
    begin
      Result:=0;
      if Msg=MessageID then
      begin
        case WParam of
          MI_QUERYWINDOWHANDLE:
            begin
              if IsIconic(application.Handle) then
              begin
                Application.MainForm.WindowState:=wsNormal;
                Application.Restore;
              end;
              PostMessage(HWND(LParam),MessageID,MI_QUERYWINDOWHANDLE,Application.MainForm.Handle);
            end;
          MI_RESPONDWINDOWHANDLE:
            begin
              SetForeGroundWindow(HWND(LParam));
              Application.Terminate;
            end;
        end;
      end
      else Result:=CallWindowProc(WProc,Handle,Msg,WParam,LParam);
    end;procedure SubClassApplication;
    begin
      WProc:=TFNWndProc(SetWindowLong(Application.Handle,GWL_WNDProc,Longint(@NewWndProc)));
      if WProc=nil then
         MIError:=MIError or MI_ERROR_FAILSUBCLASS;
    end;procedure DoFirstInstance;
    begin
      MutHandle:=CreateMutex(nil,false,UNIQUE_APPSTR);
      if MutHandle=0 then
           MIError:=MIError or MI_CREATINGMUTEX;
    end;procedure BroadcastFocusMessage;
    var
      bs:DWORD;
    begin
       Application.ShowMainForm:=false;
       bs:=BSM_APPLICATIONS;
       BroadcastSystemMessage(BSF_IGNORECURRENTTASK or BSF_POSTMESSAGE,@bs,
         MessageID,MI_QUERYWINDOWHANDLE,application.Handle);
    end;procedure InitInstance;
    begin
      SubClassApplication;
      MutHandle:=OpenMutex(MUTEX_ALL_ACCESS,false,UNIQUE_APPSTR);
      if MutHandle=0 then
        DoFirstInstance
        else begin
          BroadcastFocusMessage;
          Application.Terminate;
        end;
    end;initialization
      MessageID:=RegisterWindowMessage(UNIQUE_APPSTR);
      InitInstance;
    finalization
      if WProc<>nil then
        SetWindowLong(application.Handle,GWL_WNDPROC,Longint(WProc));
      if MutHandle<>0 then
        CloseHandle(MutHandle);
    end.
     
      

  3.   

    这段代码很有用,试试看了!
    实现单实例运行的关键是判断前一实例是否存在,Win3.x中运行的程序能获知前 
      
    一实例的句柄,从而可以方便地进行判断,但 Windows 95 是抢先式多任务系统,其 
      
    程序的前一实例句柄恒为零,所以只有另寻其他办法。目前最有效的办法是通过查看 
      
    是否有相同窗口类名的例程存在来进行判断。下面介绍在Delphi中实现的方法。 
      
      
      
    1、对主窗口程序的改动: 
      
      
      
    在主窗口(即程序创建的第一个窗口)中interface节加入 
      
    const 
      
    CM_RESTORE = WM_USER + $1000; {自定义的“恢复”消息} 
      
    MYAPPNAME = "My Delphi Program"; 
      
    并在Form的定义的public节中加入 
      
    procedure CreateParams(var Params: TCreateParams); override; 
      
    Procedure RestoreRequest(var message: TMessage); message CM_RESTORE; 
      
    在implementation节中加入 
      
    {指定窗口名称} 
      
    procedure TForm1.CreateParams(var Params: TCreateParams); 
      
    begin 
      
    inherited CreateParams(Params); 
      
    Params.WinClassName := MYAPPNAME; 
      
    end; 
      
      
      
    {处理“恢复”消息} 
      
    procedure TForm1.RestoreRequest(var message: TMessage); 
      
    begin 
      
    if IsIconic(Application.Handle) = TRUE then 
      
    Application.Restore 
      
    else 
      
    Application.BringToFront; 
      
    end; 
      
      
      
    经过以上修改,程序的主窗口的类名已经被指定了,这是进行判断的基础。一般在程 
      
    序刚开始运行的时候进行判断,所以还要对DPR文件进行修改。 
      
      
      
    2、对DPR文件的改动 
      
      
      
    在 uses 节中添加 windows、messages这两个单元加入下列语句,注意两个文件中常 
      
    量CM_RESTORE和MYAPPNAME的定义必须一致 
      
    const 
      
    CM_RESTORE = WM_USER + $1000; {自定义的“恢复”消息} 
      
    MYAPPNAME = "My Delphi Program"; 
      
    var 
      
    RvHandle : hWnd; 
      
      
      
    将下列语句插到程序最前部(在Application.Initialize之前) 
      
      
      
      
      
    RvHandle := FindWindow(MYAPPNAME, NIL); 
      
    if RvHandle > 0 then 
      
    begin 
      
    PostMessage(RvHandle, CM_RESTORE, 0, 0); 
      
    Exit; 
      
    end; 
      这段程序的意思是如果找到一个类名相同的窗口,则向该窗口发送一个消息,并退 
      
    出,而本例中原窗口收到该消息后会自动激活或从图标还原,从而达到了避免二次运