我們有些程序是可以同時運行多個進程,典型的像Visual Studio.但有些就能一次運行一個進程.比如Outlook.那你可能會問啥時可以讓它同時打開多個應用程序,啥時只能一個啊.這個主要看進程間是否獨立,會不會有沖突,是否會時讀寫相同的文件.
如果你不寫代碼去做些處理默認肯定是可以讓你同時運行多個進程的.那假如只能一次運行一個進程咋整呢?有兩種常用的方式.
使用互斥(Mutex)
在處理線程同步的時候我們也會用到這東東.我們知道它是一個內核對象.系統中一次只能創建一個,如果你再次創建一個同名的會出錯.我們就是利用這個原理來達到一次只運行一個進程.
在APP類中的InitInstance函數的開頭添加如下代碼.
HANDLE hMutex;
BOOL CMyApp::InitInstance(){
hMutex = CreateMutex(NULL,FALSE,_T("ArwenApp"));
if(GetLastError() == ERROR_ALREADY_EXISTS){ //如果已經存在同名的Mutex會得到這個錯誤.
CloseHandle(hMutex);
return FALSE;
}
//其他代碼
}
CMyApp::~CMyApp(){ //析構函數中關閉互斥句柄,當然如果你不寫也沒事.關閉應用程序時系統也會自動給你Close,不過還是自己寫上好點了.
CloseHandle(hMutex);
}
查找窗體是否存在
在APP類中的InitInstance函數的開頭添加如下代碼.
BOOL CMyApp::InitInstance(){
CWnd* pWndExist;
CWnd* pWndPopup;
pWndExist = CWnd::FindWindow(_T("ArwenAppClass"),NULL);
if(pWndExist) { //如果窗體存在說明已經打開了應用程序,下面的操作只是讓程序更人性化.也可以簡單的返回FALSE就行.
pWndPopup = pWndExist->GetLastActivePopup(); //獲得打開的活動窗體
if(pWndPopup->IsIconic())
pWndPopup->ShowWindow(SW_RESTORE); //如果窗體被最小化了,restore它
pWndPopup->ShowWindow(SW_SHOW); //顯示已經打開的窗體
pWndPopup->SetForegroundWindow(); //讓窗體顯示在最前面
return FALSE;
}
WNDCLASS wndcls;
memset(&wndcls, 0, sizeof(WNDCLASS));
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.hInstance = AfxGetInstanceHandle();
wndcls.hIcon = LoadIcon(IDR_MAINFRAME);
wndcls.hCursor = LoadStandardCursor( IDC_ARROW );
wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = _T("ArwenAppClass"); //注冊一個窗體用來做判斷是符存在已經打開的應用程序,除此之外該窗體沒起啥作用
if(!AfxRegisterClass(&wndcls))
{
return FALSE;
}
//其他代碼
}