这个不是设计模式中的那个单例,是限定程序只能以唯一进程运行在Windows中,我们在开发卫生局培训中心项目的时候用到的,其实不麻烦,利用Win API简单实现了信号量机制,代码如下,一看就会。
在程序的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);