多執行個體指同時有同一個應用程式的多個副本在運作。同一個應用程式的多個副本可以互相獨立地同時運作,是Win32作業系統提供的一個功能。但有時,我們可能希望使用者啟動應用程式後就不再啟動它的别的副本。比如某種裝置資源的控制程式,像數據機和并行端口。這種情況下,用程式代碼防止同時出現多個程式的副本在運作是非常必要的。
在16位的Windows中,要防止出現多個執行個體是很簡單的,因為系統變量hPrevInst可以被用來判斷是否有其他的執行個體存在。當hPrevInst變量不為0時,表示已經有别的應用程式執行個體在運作。
然而,在Win32系統中每個程序之間有R32絕緣層來彼此隔絕。是以,在Win32系統中變量hPrevInst的值總為0。另一種既适合Win32系統又适合于16位的Windows的技術,是調用FindWindow()API函數去搜尋一個已激活的程式視窗。
Windows API 提供了函數FindWindow,可以是應用程式在啟動時檢查自己是否已經存在。 該函數在Delphi中的文法為:
function FindWindow(lpClassName: PChar, lpWindowName: PChar): HWND;
其中,參數lpCalssName 是要查找的視窗的類的名稱,參數lpWindowName是要查找的視窗的标題(Caption)。 如果找到了相應的視窗執行個體,将傳回一個非0 的該視窗句柄的整型值,否則傳回0 。是以,隻要判斷應用程式的主視窗(或者伴随着應用程式存在而存在的視窗)是否存在就可以判斷是否已經有執行個體存在了。
例如:
H := FindWindow('TForm1', nil);
if H = 0 then begin
ShowMessage('沒有發現相同的應用程式執行個體。');
//加入加載應用程式的語句
//

end else begin
ShowMessage('應用程式已經加載。');
SetActiveWindow(H);
end;
其中,參數lpWindowName的位置以Delphi保留字nil 代替,是因為視窗的标題可能在應用程式中是變化的。Windows API 函數SetActiveWindow 用于指定活動視窗。
但是,這種方法有兩個缺陷:一是它隻能基于視窗類名或标題來搜尋視窗,但是在整個系統中視窗很可能會重複。是以,這樣做是不可靠的。而利用視窗的标題的方法也有問題,因為視窗的标題有可能發生變化(以Delphi和Word為例,每次打開不同檔案,它們的标題都會變化),是以這種方法不可取。另一個缺陷是它每次搜尋都要周遊所有視窗,這樣執行進來非常慢。
是以,在Win32系統中最好的解決方案是利用那些不依賴于程序的API對象,并且它們的使用也很簡單,互斥對象就可以解決這個問題。當一個應用程式首次運作時,我們就使一個互斥對象被API函數CreateMutex()建立。這個函數的參數lpName是一個唯一辨別互斥對象的字元串。當應用程式的執行個體要運作前,它首先要用OpenMutex()來打開互斥對象,如果已經有一個CreateMutex()建立的互斥對象則傳回非零值。另外,當試圖運作另一個程式執行個體時,使第一個執行個體被激活。
對于這個問題,最好的解決方法是在首次運作時,利用RegisterWindowMessage()函數注冊一個消息,并在應用程式中建立唯一的消息辨別符。然後,利用第一個執行個體對這個消息的響應使它被第二個執行個體激活。
這種方法阻止新執行個體的産生,但不能提前,不過較簡便。
在Project的Program檔案中
program Live;
uses
Windows,
Forms,
ShellApi,
SysUtils,

..;
{$R *.TLB}
{$R *.res}
var
HMutex:Hwnd;
Ret:Integer;
begin
Application.Initialize;
aTitle := 'LiveAuction';
Application.Title := 'LiveAuction';
HMutex:=CreateMutex(nil,False,Pchar(aTitle)); //建立互斥對象,名字為aTitle--'LiveAuction'
Ret:=GetLastError;
If Ret<>ERROR_ALREADY_EXISTS Then
begin

//做我們正常該做的事情
end else
ReleaseMutex(hMutex); //防止建立多個程式執行個體
Application.Run;
end.
本文轉自 OldHawk 部落格園部落格,原文連結:http://www.cnblogs.com/taobataoma/archive/2007/08/15/856415.html,如需轉載請自行聯系原作者