在程序的App::InitInstance()中添加信号量判断部分:
// 用应用程序名创建信号量
HANDLE hSem=CreateSemaphore(NULL,1,1,m_pszAppName);
if (GetLastError() == ERROR_ALREADY_EXISTS)
{ // 信号量存在,则程序已有一个实例运行
// 关闭信号量句柄
CloseHandle(hSem);
// 寻找先前实例的主窗口
HWND hWndPrevious = ::GetWindow(::GetDesktopWindow(),GW_CHILD);
while(::IsWindow(hWndPrevious))
{
//如果窗口有
if (::GetProp(hWndPrevious,m_pszAppName))
{
// 主窗口已最小化,则恢复其大小
if(::IsIconic(hWndPrevious))
::ShowWindow(hWndPrevious,SW_RESTORE);
// 将主窗口及对话框激活
::SetForegroundWindow(hWndPrevious);
::SetForegroundWindow(::GetLastActivePopup(hWndPrevious));
// 退出本实例
return FALSE;
}
// 继续寻找下一个窗口
hWndPrevious = ::GetWindow(hWndPrevious,GW_HWNDNEXT);
}
// 前一实例已存在,但找不到其主窗,可能出错了,退出本实例
return FALSE;
}
在程序的OnCreate()中为实例设置标记:
::SetProp(m_hWnd,::AfxGetApp()->m_pszAppName,(HANDLE)1);
最后在程序的退出部分,删除掉添加的标记,可以在对话框的OnDestroy中:
::RemoveProp(m_hWnd,::AfxGetApp()->m_pszAppName);
本文介绍了一种确保Windows程序只运行一个实例的方法。通过使用信号量来检查是否有其他实例正在运行,并利用窗口属性标记来标识当前实例。当检测到已有实例运行时,会激活并恢复该实例的主窗口。
1万+

被折叠的 条评论
为什么被折叠?



