代码如下:
1、在应用程序类InitInstance()函数中判断是否已有一个应用程序实例正在运行。
BOOL CMutexApp::InitInstance()
{
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)//创建命名信标对象。
HANDLE hSem=CreateSemaphore(NULL,1,1,"维新");
if(hSem) //信标对象创建成功。
{
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)//信标对象已经存在,则程序已有一个实例在运行。
if(ERROR_ALREADY_EXISTS==GetLastError())
{
CloseHandle(hSem); //关闭信号量句柄。
//获取桌面窗口的一个子窗口。
HWND hWndPrev=::GetWindow(::GetDesktopWindow(),GW_CHILD);
while(::IsWindow(hWndPrev))
{
//判断窗口是否有我们预先设置的标记,如有,则是我们寻找的窗口,并将它激活。
if(::GetProp(hWndPrev,"维新"))
{
//如果主窗口已最小化,则恢复其大小。
if (::IsIconic(hWndPrev))
::ShowWindow(hWndPrev,SW_RESTORE);
//将应用程序的主窗口激活。
::SetForegroundWindow(hWndPrev);
return FALSE; //退出实例。
}
//继续寻找下一个窗口。
hWndPrev = ::GetWindow(hWndPrev,GW_HWNDNEXT);
}
AfxMessageBox("已有一个实例在运行,但找不到它的主窗口!");
}
}
else
{
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)AfxMessageBox("创建信标对象失败,程序退出!");
return FALSE;
}
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMutexDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CMutexView));
AddDocTemplate(pDocTemplate);
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The one and only window has been initialized, so show and update it.
m_pMainWnd-ShowWindow(SW_SHOW);
m_pMainWnd-UpdateWindow();
return TRUE;
}
2、在框架类的OnCreate()函数中设置查找标记。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)TRACE0("Failed to create toolbar/n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)TRACE0("Failed to create status bar/n");
return -1; // fail to create
}
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
//设置查找标记。
::SetProp(m_hWnd,"维新",(HANDLE)1);
return 0;
}
3、在程序退出是删除设置的标记,在框架类中响应WM_DESTROY消息,进行处理。
void CMainFrame::OnDestroy()
{
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)CFrameWnd::OnDestroy();
// TODO: Add your message handler code here
//删除所设置的标记。
::RemoveProp(m_hWnd,"维新");
}
至此,使应用程序只运行一个实例的功能就完成了。