方法有很多,以下只是提供一种用的多的

一. 单文档程序

在程序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只运行一个程序实例的更多相关文章

  1. 如何让Windows程序只运行一个程序实例?

    要实现VC++或者MFC只运行一个程序实例,一般采用互斥量来实现,即首先用互斥量封装一个只运行一个程序实例的函数接口: HANDLE hMutex = NULL; void MainDlg::RunS ...

  2. 进程的互斥运行:CreateMutex函数实现只运行一个程序实例

    HANDLE hMutex=CreateMutex(NULL,TRUE,"HDZBUkeyDoctorTool"); if(hMutex) { if(ERROR_ALREADY_E ...

  3. MFC 只启动一个程序实例

    问题描述: 我们开发过程中可能会经常遇到,只启动一个程序实例.即一个程序启动之后,如果再次执行该程序,将会恢复之前打开的程序,而不是打开一个新的程序. 实现原理:利用FindWindow/FindWi ...

  4. Winform程序只允许运行一个程序实例

    /// <summary> /// 应用程序的主入口点. /// </summary> [STAThread] static void Main() { Application ...

  5. C#:只运行一个程序

    一.通过系统事件 1.实现如下: using System; using System.Collections.Generic; using System.Linq; using System.Tex ...

  6. C# 只允许运行一个程序实例

    using System; using System.Windows.Forms; using System.Runtime.InteropServices;//使用DllImport的必须. usi ...

  7. wpf程序,只允许运行一个程序实例问题

    https://bbs.csdn.net/topics/390486402 https://codereview.stackexchange.com/questions/20871/single-in ...

  8. windows mobile 只能运行一个程序实例

    static class Program { [System.Runtime.InteropServices.DllImport("coredll.Dll", SetLastErr ...

  9. VC 实现程序只运行一个实例,并激活已运行的程序

    转载:http://blog.sina.com.cn/s/blog_4b44e1c00100bh69.html 进程的互斥运行:CreateMutex函数实现只运行一个程序实例 正常情况下,一个进程的 ...

随机推荐

  1. 编译libjpeg库

    最近在写车牌识别软件,需要用到BMP转成JPG的功能,自然就想到借助libjpeg来实现 OS: win7 64位 编译器: VS2008 1. 下载源代码下载地址:http://www.ijg.or ...

  2. Eclipse下Tomcat插件的安装

    在Eclipse下安装Tomcat插件使开发,编译,发布变的相当的简单,下面就说一下安装的过程,很简单的: 1.先下载一个tomcat插件 地址:http://www.eclipsetotale.co ...

  3. 配置jsp开发环境

    一.安装jdk(http://pan.baidu.com/s/1sjk9a2p) 二.配置java环境变量 安装好后,配置环境变量:计算机——右击——属性——高级系统设置设置——环境变量 系统变量(没 ...

  4. [算法]检测空间三角形相交算法(Devillers & Guigue算法)

    #pragma once //GYDevillersTriangle.h /* 快速检测空间三角形相交算法的代码实现(Devillers & Guigue算法) 博客原地址:http://bl ...

  5. noi 8462 大盗阿福

    题目链接:http://noi.openjudge.cn/ch0206/8462/ 相邻的两个不能同时取, d[i] = max(d[i-1],d[i-2]+a[i]); http://paste.u ...

  6. Gcc的编译流程分为了四个步骤:

    http://blog.csdn.net/xiaohouye/article/details/52084770(转) Gcc的编译流程分为了四个步骤: 1.预处理,生成预编译文件(.文件): Gcc ...

  7. Android 获取全部应用

      package com.lvshandian.menshen.download;import android.content.Context;import android.content.Inte ...

  8. How can I view currently running MySQL queries?( 查看正在运行的MySQL语句/脚本命令)

    show processlist;show processlist\G;SHOW FULL PROCESSLIST;SHOW FULL PROCESSLIST\G; REF:http://dev.my ...

  9. Ubuntu Linux 12.04 LTS amd64系统本地root提权

    URL:http://www.ichunqiu.com/section/173 由于fusermount二进制调用setuid的(geteuid())重置RUID时,它调用/bin/mount才能使用 ...

  10. Java中Object类

    Object类是所有类的父类,如果一个类没有使用extends关键字明确标识继承另一个类,那么这个类默认继承Object类. Object类中的方法,适合所有子类. Object中的几个重要方法: 1 ...