//防止屢次打開
unit MultInst; interface uses Windows ,Messages, SysUtils, Classes, Forms; implementation const STR_UNIQUE = '{2BE6D96E-827F-4BF9-B33E-8740412CDE96}'; MI_ACTIVEAPP = 1; {激活應用程序} MI_GETHANDLE = 2; {取得句柄} var iMessageID : Integer; OldWProc : TFNWndProc; MutHandle : THandle; BSMRecipients : DWORD; function NewWndProc(Handle: HWND; Msg: Integer; wParam, lParam: Longint): Longint; stdcall; begin Result := 0; if Msg = iMessageID then begin case wParam of MI_ACTIVEAPP: {激活應用程序} if lParam<>0 then begin {收到消息的激活前一個實例} {爲何要在另外一個程序中激活?} {由於在同一個進程中SetForegroundWindow並不能把窗體提到最前} if IsIconic(lParam) then OpenIcon(lParam) else SetForegroundWindow(lParam); Application.Terminate; {終止本實例} end; MI_GETHANDLE: {取得程序句柄} begin PostMessage(HWND(lParam), iMessageID, MI_ACTIVEAPP, Application.Handle); end; end; end else Result := CallWindowProc(OldWProc, Handle, Msg, wParam, lParam); end; procedure InitInstance; begin {取代應用程序的消息處理} OldWProc := TFNWndProc(SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(@NewWndProc))); {打開互斥對象} MutHandle := OpenMutex(MUTEX_ALL_ACCESS, False, STR_UNIQUE); if MutHandle = 0 then begin {創建互斥對象} MutHandle := CreateMutex(nil, False, STR_UNIQUE); end else begin Application.ShowMainForm := False; {已經有程序實例,廣播消息取得實例句柄} BSMRecipients := BSM_APPLICATIONS; BroadcastSystemMessage(BSF_POSTMESSAGE or BSF_POSTMESSAGE,@BSMRecipients,iMessageID,MI_GETHANDLE,Application.Handle); //BroadCastSystemMessage(BSF_IGNORECURRENTTASK or BSF_POSTMESSAGE, @BSMRecipients, iMessageID, MI_GETHANDLE,Application.Handle); end; end; initialization {註冊消息} iMessageID := RegisterWindowMessage(STR_UNIQUE); InitInstance; finalization {還原消息處理過程} if OldWProc <> Nil then SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(OldWProc)); {關閉互斥對象} if MutHandle <> 0 then CloseHandle(MutHandle); end.
在XE7下測試經過.測試