| アプリケーションの二重起動の防止 |
BOOL CMyApp::InitInstance()
{
AfxEnableControlContainer();
// 標準的な初期化処理
// もしこれらの機能を使用せず、実行ファイルのサイズを小さくしたけ
// れば以下の特定の初期化ルーチンの中から不必要なものを削除して
// ください。
#ifdef _AFXDLL
Enable3dControls(); // 共有 DLL 内で MFC を使う場合はここをコールしてください。
#else
Enable3dControlsStatic(); // MFC と静的にリンクする場合はここをコールしてください。
#endif
// アプリケーションの二重起動防止
::CreateMutex(NULL, TRUE, m_pszExeName);
if( GetLastError() == ERROR_ALREADY_EXISTS) {
// 既に起動されている場合は、CWnd::FindWindow関数を使って
// 起動されているアプリケーションのウィンドウを取得し、
// そのウィンドウを最上位へ持ってくる
CString str;
str.LoadString(IDS_WINDOWTITLE);
// IDS_WINDOWTITLEにはウィンドウのタイトルを設定している
CWnd* pWnd = CWnd::FindWindow(NULL, str);
if( pWnd )
pWnd->SetForegroundWindow();
return FALSE;
}
……
}
上記では、既にアプリケーションが起動されている場合にはCWnd::FindWindow関数を使ってそのウィンドウを取得し、
最上位へ持ってくる作業も行っている。ただし上記の方法では、ウィンドウのタイトル(キャプション)
を頼りにウィンドウを探しているため、動的にキャプションが変更される
(例えば開いているドキュメントのタイトルをキャプションに表示するような)
アプリケーションでは、ウィンドウを正しく取得することができない。
ちなみに、CMutexクラスを使った場合には次のようにすればよい。
BOOL CMyApp::InitInstance()
{
……
// アプリケーションの二重起動防止
CMutex mutex(FALSE, m_pszExeName);
if( mutex.Lock(0) == TRUE ) {
// ウィンドウを開くなどの処理
……
mutex.Unlock();
}
return FALSE;
}