var
     MutexHandle: THandle;
     hPrevInst: Boolean;begin
     // -== Check to see if the named mutex object existed before this call ==-
  MutexHandle := CreateMutex(nil, TRUE, 'MysampleAppMutex');
  if MutexHandle <> 0 then
   begin
          if GetLastError = ERROR_ALREADY_EXISTS then
          // -== set hPrevInst property and close the mutex handle ==-
          begin
               MessageBox(0, 'Instance of this application is already running.',
                             'Application already running', mb_IconHand);        hPrevInst := TRUE;
          CloseHandle(MutexHandle);
               Halt; // 'Halt' Is the actual one that prevents a second instance
                     // of your app from running.
          end
         else
              begin
                   // -== indicate no previous instance was found ==-
                   hPrevInst := FALSE;
              end;
    end
     else
         begin
             // -== indicate no previous instance was found ==-
           hPrevInst := FALSE;
         end;  Application.Initialize;
  Application.Title := 'My sample app';
  Application.HelpFile := 'sample.hlp';
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

解决方案 »

  1.   

    实现单实例运行的关键是判断前一实例是否存在,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.   

    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;
    这段程序的意思是如果找到一个类名相同的窗口,则向该窗口发送一个消息,并退出,而本例中原窗口收到该消息后会自动激活或从图标还原,从而达到了避免二次运行且能自动调出前一例程的目
      

  3.   

    或着在运行第一次是创建共享内存区域,并把自己的Application窗口的handle填入第二次运行时,判断是否存在这个共享区域,如果存在就取出Application窗口的handle,用SetForegroundwindow(Appwnd);来把它提升为前景窗口,后结束
    第二次实例。
      

  4.   

    你们的做法我都了解,关键我要实现的是第二次运行时让已运行的程序BringToFront来!!!!!!!!!而且程序还是个systray的程序,
    如JetCar,最小化时把MainForm SW_HIDE了.Application可以让它SW_SHOW出来,
    可form我就不知道如何还原.关键是我把form给hide了..Application.Restore无法让form. show出来
      

  5.   

    1.声明外部函数如下: 
    FUNCTION uLong ShowWindow( ulong winhandle, int wincommand ) Library "user32" 
    FUNCTION uLong BringWindowToTop( ulong HWND ) Library "user32" 
    FUNCTION long FindWindowA( ulong Winhandle, string wintitle ) Library "user32" 
    2. 创建一个窗口'w_test' . 将title 设置为"Test Window". 
    3. 在application的 Open 事件中加入如下代码: 
    long ll_winhandle
    ll_winhandle = FindWindowA( 0, "Test Window" ) 
    If ll_winhandle > 0 Then 
    BringWindowToTop( ll_winhandle ) 
    ShowWindow( ll_winhandle , 5 ) 
    Return 
    End If 
    Open( w_test ) 
     
      

  6.   

    RvHandle  :=  FindWindow(MYAPPNAME,  NIL);
      if  RvHandle  >    0  then
      begin
      PostMessage(RvHandle,  CM_RESTORE,  0,  0);
      Exit;
      end;
      

  7.   

    谢谢各位,参考你们的建议和大富翁的离线包,我终于搞了了..比较完美,
    像jetcar那样的程序驻留在systray,第二次运行时能叫出,简单地写了个DEMO
    以后的新手要学习可向我索取