var
  hPrev: THandle;
  pClass: PChar;
  pClass := PChar('MainForm名称');
  hPrev := FindWindowEx(0, 0 ,pClass, nil);
  IF hPrev <> 0 THEN
    BEGIN
      hPrev := GetWindow(hPrev,GW_HWNDNEXT);
      IF IsIconic(hPrev) THEN
         ShowWindow(hPrev,SW_RESTORE);
      SetForegroundWindow(hPrev);
      Exit;
    END;

解决方案 »

  1.   

    implementation 
    var hnd: THandle;initialization
        hnd := CreateMutex(nil, True, 'irgendwaseinmaliges');
        if GetLastError = ERROR_ALREADY_EXISTS then Halt;finalization
        if hnd <> 0 then CloseHandle(hnd);
    end.
    实现单实例运行的关键是判断前一实例是否存在,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文件进行修改。begin  Application.Initialize;
      Application.Title := 'xxx管理系统;
      hMutex:=CreateMutex(nil,False,'xxx管理系统');
      Ret:=GetLastError;
      If Ret<>ERROR_ALREADY_EXISTS Then
       Begin
       Application.CreateForm(TajMAIN, ajMAIN);  Application.Run;
       End
      Else
       Application.MessageBox('已经运行!','注意!',MB_OK);
       ReleaseMutex(hMutex);end.
      

  2.   

    写注册表:
    procedure WriteReg(input:word);
    var
      tempexe:string;
    begin
      tempexe:=inttostr(input);
    try
      Regtmp:=TRegistry.Create;
      Regtmp.RootKey :=HKEY_LOCAL_MACHINE;
      if Regtmp.OpenKey('\SOFTWARE\Mykey\currentexe',true) then
        begin
          Regtmp.WriteString('curexe',tempexe);
        end;
      Regtmp.Free;
      finally
      //
      end;
    end;
      

  3.   

    var
      hPrev: THandle;
      pClass: PChar;  pClass := PChar('MainForm名称');
      hPrev := FindWindowEx(0, 0 ,pClass, nil);
      IF hPrev <> 0 THEN
        BEGIN
          hPrev := GetWindow(hPrev,GW_HWNDNEXT);
          IF IsIconic(hPrev) THEN
             ShowWindow(hPrev,SW_RESTORE);
          SetForegroundWindow(hPrev);
          Exit;
        END;
      

  4.   

    //读注册表
    function ReadReg:word;
    var
      str:string;
    begin
      try
      Regtmp:=TRegistry.Create;
      Regtmp.RootKey:=HKEY_LOCAL_MACHINE;
      if Regtmp.OpenKey('\SOFTWARE\Mykey\currentexe',true) then
        begin
          str:= Regtmp.ReadString('curexe');
          result:=strtoint(str);
        end
      else
        result:=0;
      Regtmp.Free;
      finally
      //
      end;
    end;
      

  5.   

    //工程文件里。
    uses Windows;
    var
      MutexHandle: THandle;
    begin
      MutexHandle := CreateMutex(nil, TRUE, 'Handlename');
      if (MutexHandle<>0) and (GetLastError=ERROR_ALREADY_EXISTS) then
      begin
        CloseHandle(MutexHandle);
        Halt;
      end;
      //..................
      Application.Initialize;
      Application.Run;
    end;
      

  6.   

    用进程间通信做。
    CreateMutex创建互斥对象,程序启动时用OpenMutex检查该互斥对象。
    详细请参阅Delphi5开发人员指南 P397。
      

  7.   

    unit MultInst;interfaceconst
      MI_QUERYWINDOWHANDLE   = 1;
      MI_RESPONDWINDOWHANDLE = 2;  MI_ERROR_NONE          = 0;
      MI_ERROR_FAILSUBCLASS  = 1;
      MI_ERROR_CREATINGMUTEX = 2;// Call this function to determine if error occurred in startup.
    // Value will be one or more of the MI_ERROR_* error flags.
    function GetMIError: Integer;implementationuses Forms, Windows, SysUtils;const
      UniqueAppStr = 'DDG.I_am_the_Eggman!';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 this is the registered message...
      if Msg = MessageID then
      begin
        case wParam of
          MI_QUERYWINDOWHANDLE:
            // A new instance is asking for main window handle in order
            // to focus the main window, so normalize app and send back
            // message with main window handle.
            begin
              if IsIconic(Application.Handle) then
              begin
                Application.MainForm.WindowState := wsNormal;
                Application.Restore;
              end;
              PostMessage(HWND(lParam), MessageID, MI_RESPONDWINDOWHANDLE,
                Application.MainForm.Handle);
            end;
          MI_RESPONDWINDOWHANDLE:
            // The running instance has returned its main window handle,
            // so we need to focus it and go away.
            begin
              SetForegroundWindow(HWND(lParam));
              Application.Terminate;
            end;
        end;
      end
      // Otherwise, pass message on to old window proc
      else
        Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
    end;procedure SubClassApplication;
    begin
      // We subclass Application window procedure so that
      // Application.OnMessage remains available for user.
      WProc := TFNWndProc(SetWindowLong(Application.Handle, GWL_WNDPROC,
        Longint(@NewWndProc)));
      // Set appropriate error flag if error condition occurred
      if WProc = nil then
        MIError := MIError or MI_ERROR_FAILSUBCLASS;
    end;procedure DoFirstInstance;
    // This is called only for the first instance of the application
    begin
      // Create the mutex with the (hopefully) unique string
      MutHandle := CreateMutex(nil, False, UniqueAppStr);
      if MutHandle = 0 then
        MIError := MIError or MI_ERROR_CREATINGMUTEX;
    end;procedure BroadcastFocusMessage;
    // This is called when there is already an instance running.
    var
      BSMRecipients: DWORD;
    begin
      // Prevent main form from flashing
      Application.ShowMainForm := False;
      // Post message to try to establish a dialogue with previous instance
      BSMRecipients := BSM_APPLICATIONS;
      BroadCastSystemMessage(BSF_IGNORECURRENTTASK or BSF_POSTMESSAGE,
        @BSMRecipients, MessageID, MI_QUERYWINDOWHANDLE,
        Application.Handle);
    end;procedure InitInstance;
    begin
      SubClassApplication;   // hook application message loop
      MutHandle := OpenMutex(MUTEX_ALL_ACCESS, False, UniqueAppStr);
      if MutHandle = 0 then
        // Mutex object has not yet been created, meaning that no previous
        // instance has been created.
        DoFirstInstance
      else
        BroadcastFocusMessage;
    end;initialization
      MessageID := RegisterWindowMessage(UniqueAppStr);
      InitInstance;
    finalization
      // Restore old application window procedure
      if WProc <> Nil then
        SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(WProc));
      if MutHandle <> 0 then CloseHandle(MutHandle);  // Free mutex
    end.//在你的工程的主窗体引用此单元即可。//利用窗口的类名或者标题不可取,因为类名可能重复,标题可能会更改。
      

  8.   

    程序启动时: 
    ReadReg;
    WriteReg(application.Handle);程序退出时:
    xhtWriteReg(0);
      

  9.   

    程序启动时: 
    ReadReg;
    WriteReg(application.Handle);程序退出时:
    WriteReg(0);