---- Windows應(yīng)用程序可以同時打開多個實例,有時候要限制用戶只能打開應(yīng)用程序的一個實例。最簡單的方法是用 FindWindow函數(shù)檢測有沒有某個標題的窗口存在,但只這樣無法處理標題欄自動改變的程序。有資料介紹了枚舉 Windows任務(wù)列表的辦法,但較為復(fù)雜。
---- 一個巧妙的方法是用文件(或注冊表)結(jié)合FindWindow函數(shù)來實現(xiàn)。其思路是:程序運行時在一個特定文件(或注冊表中)做個"運行標記",同時記錄窗口的標題,當(dāng)窗口標題變化時同時修改記錄的窗口標題,在退出刪除"運行標記"或做個"結(jié)束標記",刪除記錄的窗口標題。這樣,在程序運行時先檢測特定文件(或注冊表)中有沒有"運行標記"。如果有"運行標記",再用FindWindow檢測有沒有所記錄標題的窗口在運行。如果有則報警退出(或激活已經(jīng)運行的實例窗口),如果沒有則可能是程序上次不正常退出,提示用戶并讓用戶決定是否運行。
---- 下面以C++Builder做示范:
啟動時的檢測可加在項目文件 Project1.cpp中:
#include < IniFiles.hpp >
//增加代碼
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
TIniFile *RunFlag=new TIniFile("MyTest.ini");
//增加代碼
AnsiString RunCaption[2]; //增加代碼
try
{
Application- >Initialize();
//以下為增加代碼
if(RunFlag->ReadInteger("Rec","RunFlag",0)==1)
{
RunCaption[0]=RunFlag- >ReadString("Rec","Caption","");
HWND PrevWindow=FindWindow
("TForm1",RunCaption[0].c_str());
if(PrevWindow)
{
ShowWindow(PrevWindow,SW_SHOW);
SetForegroundWindow(PrevWindow);
Application- >Terminate();
}
else
{
int button = Application- >MessageBox
("上次沒有正常退出,要繼續(xù)運行嗎?",
"警告", MB_OKCANCEL);
if (button == IDCANCEL)
Application- >Terminate();
}
}
else
{ RunFlag- >WriteInteger("Rec","RunFlag",1);
RunFlag- >WriteString("Rec","Caption","Form1");
}
delete RunFlag;
//上面的為增加代碼
Application- >CreateForm(__classid(TForm1), &Form1);
Application- >Run();
}
catch (Exception &exception)
{ Application- >ShowException(&exception);}
return 0;
}
---- 每個退出程序的地方必須加上以下處理代碼,如Form的OnClose事件處理函數(shù)中、使用exit()函數(shù)前:
TIniFile *RunFlag=new TIniFile("MyTest.ini");
RunFlag- >WriteInteger("Rec","RunFlag",0);
RunFlag- >WriteString("Rec","Caption","");
每當(dāng)標題變化時(如變?yōu)?歡迎光臨")必須加上以下處理代碼:
RunFlag- >WriteString("Rec","Caption","歡迎光臨");