让一个程序只允许一个实例,并且如果已经有一个允许实例,则激活它

为该程序在属性列表里面添加一条记录

int CTrainingSystemDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDialog::OnCreate(lpCreateStruct) == -1)
		return -1;
	//设置标记
	::SetProp(m_hWnd, _T("UniqueMark"), AfxGetApp()->m_hInstance);

	return 0;
}

 

在InitInstance函数中判断标记是否存在,如果存在,则激活含有该标记的程序:

HANDLE hMutex = ::CreateMutex(NULL, TRUE, _T("training_system"));
if (::GetLastError() == ERROR_ALREADY_EXISTS)
{
	//AfxMessageBox(_T("程序已经运行"));
	//寻找先前实例的主窗口
	HWND hPrevWnd = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
	while (::IsWindow(hPrevWnd))
	{
		//检查窗口是不是有先前设置的标记
		//如果有,则是我们寻找的窗口
		if (::GetProp(hPrevWnd, _T("UniqueMark")))
		{
			//主窗口已经最小化,则将其恢复
			if (::IsIconic(hPrevWnd))
			{
				::ShowWindow(hPrevWnd, SW_RESTORE);
			}
			//将主窗口激活
			::SetForegroundWindow(hPrevWnd);
			//将主窗口的对话框激活
			::SetForegroundWindow(::GetLastActivePopup(hPrevWnd));
			return FALSE;
		}
		//继续寻找下一个窗口
		hPrevWnd = ::GetWindow(hPrevWnd, GW_HWNDNEXT);
	}
	return FALSE;
}

 

在程序结束时删除标记:

void CTrainingSystemDlg::OnDestroy()
{
	CDialog::OnDestroy();
	//删除标记
	::RemoveProp(m_hWnd, _T("UniqueMark"));
}

 

附:以下是MSDN上面的说明

Before a window is destroyed (that is, before it returns from processing the WM_NCDESTROY message), an application must remove all entries it has added to the property list. The application must use the RemoveProp function to remove the entries.

BOOL SetProp(      
    HWND hWnd,		//要添加或者修改那个窗口的属性列表
    LPCTSTR lpString,		//可以理解成一个key
    HANDLE hData		//可以理解成一个value。当key已经存在,那么就替换掉value,否则创建
);
HANDLE GetProp(      //返回值时key对应的value,也就是你在SetProp的时候指定的hData
    HWND hWnd,		//要返回那个窗口的属性
    LPCTSTR lpString		//要查找的key
);
HANDLE RemoveProp(      
    HWND hWnd,	//要移除谁的属性
    LPCTSTR lpString		//要删除的key
);

转载于:https://www.cnblogs.com/chenkunyun/archive/2012/03/16/2400278.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值