使程序只能运行一个实例
2013-12-10 16:03
204 查看
1,目标
使我们的程序只能有一个正在运行的实例。并且在第二次运行时,若前一个实例主窗口处于最小化状态,就让前一个实例恢复原大小显示出来。
2,原理
前一实例进程运行期间得留下一个可供后一实例进程判断的标志,类似进程间通信,可以参考一些IPC的方式。不过这里不需要传递多少数据,仅仅有个标志就OK。一个简单思路:程序开始时创建一个可命名的内核对象,退出时关闭。如果已存在则说明存在实例在使用这个内核对象。
对于找到前实例主窗口:有一个API,可以给窗口添加一个标志:SetProp.通过遍历桌面的子窗口,用GetProp获取标志,可以判断出我们要的窗口。
3,实现
①新建MFC对话框应用程序,在app类中加入:HANDLE m_handle;
②在InitInstance()中加入如下代码:
//防止多次实例 //用应用程序名创建一个互斥量(任意一种可命名的内核对象都行) m_handle = CreateMutex(NULL, FALSE, m_pszExeName); if (GetLastError() == ERROR_ALREADY_EXISTS) { // 前一实例已存在,退出本实例 return FALSE; }
③给app类添加虚函数ExitInstance(),在程序退出前关闭该内核对象引用。
int CTestApp::ExitInstance() { CloseHandle(m_handle); return CWinApp::ExitInstance(); }
现在本程序只能运行一次实例了,下面使第二次运行时前实例窗口大小恢复显示。
④在dlg类 OnCreate()中给对话框添加标记:
int CTestDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialog::OnCreate(lpCreateStruct) == -1) return -1; // 设置窗口标记,用的是应用程序名 ::SetProp(m_hWnd, AfxGetApp()->m_pszExeName, (HANDLE)1); return 0; }⑤添加消息响应OnDestroy(),窗口销毁时去掉标记:
void CTestDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: Add your message handler code here // 删除寻找标记 ::RemoveProp(m_hWnd, AfxGetApp()->m_pszExeName); }
⑥修改app的InitInstance(),使标记的窗口恢复大小:
BOOL CTestApp::InitInstance() { //防止多次实例 //用应用程序名创建一个互斥量(任意一种可命名的内核对象都行) m_handle = CreateMutex(NULL, FALSE, m_pszExeName); if (GetLastError() == ERROR_ALREADY_EXISTS) { //寻找先前实例的主窗口 //桌面句柄 HWND hWndPrevious = ::GetWindow(::GetDesktopWindow(),GW_CHILD); //遍历桌面的子窗口 while (::IsWindow(hWndPrevious)) { // 检查窗口是否有预设的标记? // 有,则是我们寻找的主窗 if (::GetProp(hWndPrevious, m_pszExeName)) { // 主窗口已最小化,则恢复其大小 if (::IsIconic(hWndPrevious)) { ::ShowWindow(hWndPrevious,SW_RESTORE); // 将主窗激活 ::SetForegroundWindow(hWndPrevious); // 将主窗的对话框激活 ::SetForegroundWindow( ::GetLastActivePopup(hWndPrevious)); // 退出本实例 return FALSE; } } // 继续寻找下一个窗口 hWndPrevious = ::GetWindow(hWndPrevious,GW_HWNDNEXT); } // 前一实例已存在,但没找到其主窗口,可能出错了,退出本实例 return FALSE; } …… }
好了,大功告成!
4,效果
效果就是没什么效果了……(当第二次运行)但是为了遵循给自己定的五步流程,仍然加上此条~5,源码
附上VC6源码:http://yun.baidu.com/s/1f8ov2
相关文章推荐
- C#只能运行一个实例程序的方法
- 程序只能运行一个实例
- 只能运行程序的一个实例
- 使程序只能运行一个实例
- 只能运行一个程序实例的两种方法对比
- FCL小应用系列-----------如何使得程序只能有一个实例运行?
- MFC程序唯一运行判断(只能运行一个实例)
- c# 程序只能运行一次(多次运行只能打开同一个程序) 并激活第一个实例,使其获得焦点,并在最前端显示.
- C#只能运行一个实例程序的方法
- C# WINFORM判断程序是否运行,且只能运行一个实例
- MFC 程序只能运行一个实例 互斥对象
- C# WINFORM判断程序是否运行,且只能运行一个实例
- 让程序只能被运行一个实例
- c# Winform 如何实现程序只能同时运行一个实例
- C# WINFORM判断程序是否运行,且只能运行一个实例
- C# WINFORM判断程序是否运行,且只能运行一个实例
- .NET限制程序一次只能运行一个实例
- 使Qt 程序只能运行一个实例的3种方法
- qt编写一个只能运行单个实例的程序,不用Windows API
- windows mobile 只能运行一个程序实例