VC只运行一个程序实例
方法有很多,以下只是提供一种用的多的
一. 单文档程序
在程序App类的InitInstance中添加如下代码
BOOL CDDZApp::InitInstance()
{
/*只运行一个实例*/
//创建命名信标对象。
HANDLE hSem = CreateSemaphore(NULL, 1, 1, "DDZ");
if (hSem) //信标对象创建成功。
{
//信标对象已经存在,则程序已有一个实例在运行。
if (ERROR_ALREADY_EXISTS == GetLastError())
{
CloseHandle(hSem); //关闭信号量句柄。
//获取桌面窗口的一个子窗口。
HWND hWndPrev = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
while (::IsWindow(hWndPrev))
{
//判断窗口是否有我们预先设置的标记,如有,则是我们寻找的窗口,并将它激活。
if (::GetProp(hWndPrev, "DDZ"))
{
//如果主窗口已最小化,则恢复其大小。
if (::IsIconic(hWndPrev))
::ShowWindow(hWndPrev, SW_RESTORE);
//将应用程序的主窗口激活。
::SetForegroundWindow(hWndPrev);
return FALSE; //退出实例。
}
//继续寻找下一个窗口。
hWndPrev = ::GetWindow(hWndPrev, GW_HWNDNEXT);
}
AfxMessageBox("已有一个实例在运行,但找不到它的主窗口!");
}
}
else
{
AfxMessageBox("创建信标对象失败,程序退出!");
return FALSE;
} // 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。 否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
// 公共控件类。
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls); CWinApp::InitInstance(); // 初始化 OLE 库
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
} AfxEnableControlContainer(); EnableTaskbarInteraction(FALSE); // 使用 RichEdit 控件需要 AfxInitRichEdit2()
// AfxInitRichEdit2(); // 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
LoadStdProfileSettings(4); // 加载标准 INI 文件选项(包括 MRU) // 注册应用程序的文档模板。 文档模板
// 将用作文档、框架窗口和视图之间的连接
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CDDZDoc),
RUNTIME_CLASS(CMainFrame), // 主 SDI 框架窗口
RUNTIME_CLASS(CDDZView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate); // 分析标准 shell 命令、DDE、打开文件操作的命令行
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo); // 调度在命令行中指定的命令。 如果
// 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
if (!ProcessShellCommand(cmdInfo))
return FALSE; // 唯一的一个窗口已初始化,因此显示它并对其进行更新
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow(); return TRUE;
}
2.在程序结束时删除标记
void CMainFrame::OnDestroy()
{
CFrameWnd::OnDestroy();
// TODO: 在此处添加消息处理程序代码
::RemoveProp(m_hWnd, "DDZ");//删除所设置的标记。 }
二. 对话框程序
在CXXXDlg.h中添加互斥变量
HANDLE m_hMutex; //一个实例的互斥变量;
在 CXXXDlg.cpp的OnCreate中添加如下代码
int CXXXDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialogEx::OnCreate(lpCreateStruct) == -1)
return -1;
//程序只运行一个;
this->m_hMutex = ::CreateMutexW(NULL,FALSE,AfxGetApp()->m_pszExeName);
if(::GetLastError()==ERROR_ALREADY_EXISTS)
{
// 寻找先前实例的主窗口
HWND hWndPrevious = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
while (::IsWindow(hWndPrevious))
{
if (::GetProp(hWndPrevious, AfxGetApp()->m_pszExeName))
{
if (::IsIconic(hWndPrevious))
::ShowWindow(hWndPrevious, SW_RESTORE);
::SetForegroundWindow(hWndPrevious);
::SetForegroundWindow(::GetLastActivePopup(hWndPrevious));
return -1;
}
hWndPrevious = ::GetWindow(hWndPrevious, GW_HWNDNEXT);
}
return -1;
} ::SetProp(m_hWnd, AfxGetApp()->m_pszExeName , (HANDLE)1); return 0;
}
最后程序结束时清除申请的资源
void CXXXDlg::OnDestroy()
{
CDialogEx::OnDestroy();
::CloseHandle(this->m_hMutex);
::RemoveProp(m_hWnd, AfxGetApp()->m_pszExeName);
}
VC只运行一个程序实例的更多相关文章
- 如何让Windows程序只运行一个程序实例?
要实现VC++或者MFC只运行一个程序实例,一般采用互斥量来实现,即首先用互斥量封装一个只运行一个程序实例的函数接口: HANDLE hMutex = NULL; void MainDlg::RunS ...
- 进程的互斥运行:CreateMutex函数实现只运行一个程序实例
HANDLE hMutex=CreateMutex(NULL,TRUE,"HDZBUkeyDoctorTool"); if(hMutex) { if(ERROR_ALREADY_E ...
- MFC 只启动一个程序实例
问题描述: 我们开发过程中可能会经常遇到,只启动一个程序实例.即一个程序启动之后,如果再次执行该程序,将会恢复之前打开的程序,而不是打开一个新的程序. 实现原理:利用FindWindow/FindWi ...
- Winform程序只允许运行一个程序实例
/// <summary> /// 应用程序的主入口点. /// </summary> [STAThread] static void Main() { Application ...
- C#:只运行一个程序
一.通过系统事件 1.实现如下: using System; using System.Collections.Generic; using System.Linq; using System.Tex ...
- C# 只允许运行一个程序实例
using System; using System.Windows.Forms; using System.Runtime.InteropServices;//使用DllImport的必须. usi ...
- wpf程序,只允许运行一个程序实例问题
https://bbs.csdn.net/topics/390486402 https://codereview.stackexchange.com/questions/20871/single-in ...
- windows mobile 只能运行一个程序实例
static class Program { [System.Runtime.InteropServices.DllImport("coredll.Dll", SetLastErr ...
- VC 实现程序只运行一个实例,并激活已运行的程序
转载:http://blog.sina.com.cn/s/blog_4b44e1c00100bh69.html 进程的互斥运行:CreateMutex函数实现只运行一个程序实例 正常情况下,一个进程的 ...
随机推荐
- 为mongodb加用户授权并使用RockMongo进行管理
在刚安装完mongodb后是没有管理员的,如果要为mongodb设置管理员在启动时需要以用户授权的方式启动: /usr/local/webserver/mongodb/bin/mongod --dbp ...
- 思维导图软件MindManager for Windows中如何修改思维导图布局
MindManager for Windows是 Mindjet公司旗下应用于Windows桌面系统的一款思维导图软件,目前已经更新到了v14版本.对于很多刚开始使用MindManager for W ...
- Tomcat 发布war包提示war包超出大小修改
error信息: java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$Size ...
- python(九)re模块
python中re模块提供了正则表达式相关操作. 1. 字符串匹配: . 匹配除换行符以外的任意字符 \w 匹配字符或数字或下划线或汉字 \s 匹配任意空白字符 \d 匹配数字 \b 匹配单词 ...
- 2016年12月25日 星期日 --出埃及记 Exodus 21:20
2016年12月25日 星期日 --出埃及记 Exodus 21:20 "If a man beats his male or female slave with a rod and the ...
- hdu1242 优先队列+bfs
Rescue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- visual studio插件开发dll类库免加全局缓存处理办法
1.卸载VSIXProject 2.然后编辑*.csproj 修改如下: 3.重新加载项目 编辑source.extension.vsixmanifest 添加资产: 完事后,直接安装VISX就可以了
- 微内核架构(Microkernel Architecture)
微内核架构(Microkernel Architecture) 微内核架构有时也被成为插件架构模式(plug-in architecture pattern),通常用于实现基于产品的应用,如Eclip ...
- Scrum Meeting 10-20151216
任务安排 姓名 今日任务 明日任务 困难 董元财 网络连接框架优化 网络连接框架优化 无 胡亚坤 优化商品搜索界面 优化商品搜索界面 无 刘猛 请假(参加编译测试) 无 马汉虎 请假(参加编译测试) ...
- struts入门初步(一)
struts2.0与struts1.0运用了不同的框架,有一定的不兼容性. struts2.0借鉴了webwork的框架思想. Struts2的基本步骤: 1.拷贝struts的jar到项目中(导 ...