zoukankan      html  css  js  c++  java
  • 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);
    }
    
  • 相关阅读:
    Eclipse 3.0.1插件方案(Java版) zt
    Vs2003使用时出现这个问题,正在郁闷中,网上找了好久,居然看到同样问题,马上拷贝来:)开心中
    Eclipse+Tomcat集成开发servletzt
    管理定律
    张小娴“禁果之味”
    上海主要特色医院一览表
    分布式网站数据库同步方案——sqlserver数据库同步复制,好文收藏之
    Eclipse 插件汇总(转载+不断更新) zt
    Eclipse零起步系列讲座 zt
    结婚这件事
  • 原文地址:https://www.cnblogs.com/July7th/p/5594516.html
Copyright © 2011-2022 走看看