在VC++中編程中,只運行一個實例的方法主要有兩類:
1遍歷當前的所有窗口,查找相同的實例。為了便于查找,一般要事先設一個查找標志。
2利用系統提供的互斥對象或信標,直接讓系統抑制重復的實例。
在發現重復運行時沒有任務的實例在運行,一般還有一個任務沒有任務的實例在運行,就是激活已經存在的窗口。
一、第一類方法的實現
部分關鍵代碼
1、在App的()中枚舉所有窗口,查找本程序實例
1 HWND oldHWnd = NULL; 2 3 EnumWindows(EnumWndProc,(LPARAM)&oldHWnd); //枚舉所有運行的窗口 4 5 if(oldHWnd != NULL) 6 7 { 8 9 AfxMessageBox("本程序已經在運行了"); 10 11 ::ShowWindow(oldHWnd,SW_SHOWNORMAL); //激活找到的前一個程序 12 13 ::SetForegroundWindow(oldHWnd); //把它設為前景窗口 14 15 return false; //退出本次運行 16 17 }
2、添加窗口過程函數://通過自定義的屬性名查找同類實例窗口
1 CString g_szPropName = "Your Prop Name"; //自己定義一個屬性名 2 3 HANDLE g_hValue = (HANDLE)1; //自己定義一個屬性值 4 5 6 7 BOOL CALLBACK EnumWndProc(HWND hwnd,LPARAM lParam) 8 9 { 10 11 HANDLE h = GetProp(hwnd,g_szPropName); 12 13 if( h == g_hValue) 14 15 { 16 17 *(HWND*)lParam = hwnd; 18 19 return false; 20 21 } 22 23 return true; 24 25 }
3、在主窗口的()中添加屬性//設置窗口屬性
1 SetProp(m_hWnd,g_szPropName,g_hValue);
2丶第二種方法:
控制臺下:
1 HANDLE Mutex; 2 3 Mutex = CreateMutex(NULL, TRUE, "me"); 4 5 if(GetLastError() == ERROR_ALREADY_EXISTS) 6 7 { 8 9 cout << "only one instance can run!" << endl; 10 11 return 1; 12 13 } 14 15 else 16 17 { 18 19 ReleaseMutex(Mutex); 20 21 }
MFC下:
1 BOOL CtestInfoApp::InitInstance() 2 3 { 4 5 HANDLE Mutex; 6 7 Mutex = CreateMutex(NULL, TRUE, "me"); 8 9 if(GetLastError() == ERROR_ALREADY_EXISTS) 10 11 { 12 13 AfxMessageBox("only one instance can run!"); 14 15 return 0; 16 17 } 18 19 else 20 21 { 22 23 ReleaseMutex(Mutex); 24 25 } 26 27 … 28 29 }