確保應用程式全系統僅運行一個實例,第二次啟動時尋找既有主視窗並將其還原、置於前景。核心技術:視窗屬性(SetProp/GetProp)標記主視窗 + EnumWindows 枚舉搜尋。
CString g_szPropName = _T("MyApp_Unique_Prop_Name_8393"); // 唯一字串
HANDLE g_hPropValue = (HANDLE)1; // 任意非零值
InitInstance 中枚舉視窗檢測BOOL CMyApp::InitInstance() {
HWND hExisting = NULL;
EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL {
if (GetProp(hwnd, g_szPropName) == g_hPropValue) {
*(HWND*)lParam = hwnd; return FALSE; // 停止枚舉
}
return TRUE;
}, (LPARAM)&hExisting);
if (hExisting) {
ShowWindow(hExisting, SW_SHOWNORMAL); // 還原最小化
SetForegroundWindow(hExisting); // 置前景
return FALSE; // 退出第二個實例
}
// ... 繼續正常初始化
return TRUE;
}
OnInitDialog 設定屬性BOOL CMainDlg::OnInitDialog() {
CDialog::OnInitDialog();
SetProp(m_hWnd, g_szPropName, g_hPropValue); // 標記自己
return TRUE;
}
SetForegroundWindow 需符合前景鎖定規則(Windows 2000/XP 允許從非前景程式喚醒前景視窗)。DoModal 前設定屬性,或在建立視窗後立即設定。