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

一. 单文档程序

在程序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. Qt报表控件NCReport教程:添加报表字段

    NCReport是一款轻量级.快速.多平台.简单易用的基于Qt toolkit的C++编写的报表解决方案,目前主要包括报表渲染库和报表设计器GUI应用程序. 在前面的文章<报表控件NCRepor ...

  2. visual Sdudio 快捷键

    项目相关的快捷键 Ctrl + Shift + B = 生成项目 Ctrl + Alt + L = 显示Solution Explorer(解决方案资源管理器) Shift + Alt+ C = 添加 ...

  3. dr.wondr博士随笔之三星某古董智能机GTXXXX 的取证恢复一例

    大家好!欢迎来到我dr.wonde博士的微博! 这是dr.wonde的第一篇微博,不足之处,还请见谅. 今天dr.wonde给你们带来不可能的数据恢复任务之三星非智能机古董机GT-E1088C 的恢复 ...

  4. C#:绘图问题

    1.设置DPI Bitmap bitmap2 = new Bitmap((int)w, (int)h); bitmap2.SetResolution(, ); 2.设置Graphic(如:去锯齿等) ...

  5. Object类型与Array类型

    总结--JS中的引用类型: Object类型,Array类型,Boolean类型,Number类型,String类型,Date类型, Function类型,RegExp类型,单体内置对象(Global ...

  6. android 内存处理工具

    1. LeakCanary 检查内存泄露 LeakCanary 是一个开源的在debug版本中检测内存泄漏的java库. 让我们来看看一个cait的例子: 1 2 3 4 5 6 7 8 9 10 1 ...

  7. 关于ifram之间的相互调用

    window.iframeId.btnClose.click(); 父调子 window.parent.FatherFunciton(); 子调父

  8. Android handle 多线程练习

    Android handle <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android&quo ...

  9. 2.4G高频PCB天线设计

    2.4G高频PCB天线设计 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.   参考链接: http://bbs.rfeda.cn/read-htm-t ...

  10. 三种DSO(标准DSO、写优化DSO、直接更新DSO)、标准DSO覆盖合计规则

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...