程序只运行一个实例,并激活已运行的实例[12月15日更新]

只允许一个实例的方法比较简单:

在InitInstance() 函数里加入如下代码,利用互斥量来保证只运行一次

HANDLE   m_hMutex = CreateMutex(NULL, TRUE, m_pszAppName)
if(GetLastError() == ERROR_ALREADY_EXISTS)
    return   FALSE;

如果要找到已经运行的实例,并激活,则要利用信号量来实现。

在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_SHOW);  
				//将主窗激活  
				::SetForegroundWindow(hWndPrevious);  
				//将主窗的对话框激活  
				::SetForegroundWindow(::GetLastActivePopup(hWndPrevious));  
				//退出本实例  
				return FALSE;  
			}  
			//   继续寻找下一个窗口  
			hWndPrevious = ::GetWindow(hWndPrevious,GW_HWNDNEXT);
		}  
		//   前一实例已存在,但找不到其主窗  
		//   可能出错了  
		//   退出本实例  
		return   FALSE;
	}
在Dlg::OnCreate加入以下代码

::SetProp(m_hWnd,   AfxGetApp()-> m_pszAppName, (HANDLE)1);

在Dlg::OnDestroy()中加入以下代码

::RemoveProp(m_hWnd, AfxGetApp()-> m_pszAppName);

目前存在的问题:

对于最小化到托盘的程序无法激活……

========================================================

2011年12月15日更新


解决对于最小化到托盘的程序无法激活的问题

实际上上面的代码已经含有了最小化的代码部分

				//主窗口已最小化,则恢复其大小  
				if (::IsIconic(hWndPrevious))  
					::ShowWindow(hWndPrevious, SW_SHOW);  
但是个人对其不理解的是IsIconic函数的具体作用,反正我自己写的最小化到托盘的程序里面这个函数没有正确的返回状态。

解决的方法很简单,直接用

::ShowWindow(hWndPrevious, SW_SHOW); 
即可,目前没有发现什么副作用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值