VC 对话框 只允许运行一个实例 ,如果有就激活到前端的实现方法如下:
1。就是在其APP的CPP实现中,定义函数BOOL COnceApp::IsFirstInstance(CString title),并在其函数BOOL COnceApp::InitInstance()中,调用if (!IsFirstInstance(onlyTitle)) return FALSE; 即可。
2。 在其APP的CPP实现文件中,定义一个全局的标题标量,CString onlyTitle="你是我的唯一";
声明标题只是为了后续实例查找激活到前端使用,对于方法2,3 如果不激活到前端就不必要使用了。
3。 在对话框的CPP实现中,定义为外部变量,extern CString onlyTitle;
4。 并在对话框初始化函数中BOOL COnceDlg::OnInitDialog(),调用设置为标题SetWindowText(onlyTitle);
这里列举3种方法,第1种最简单。3种方法的APP实现完整代码如下:
===方法1===
// once.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "once.h"
#include "onceDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// COnceApp
BEGIN_MESSAGE_MAP(COnceApp, CWinApp)
//{{AFX_MSG_MAP(COnceApp)
//}}AFX_MSG_MAP
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/
// COnceApp construction
COnceApp::COnceApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/
// The one and only COnceApp object
COnceApp theApp;
/
// COnceApp initialization
//这里是应用程序的入口,还不能设置标题,需要到后面的出现窗口后才能设置标题
//1。声明唯一标题,只是为了后续实例查找激活到前端使用,对于方法2,3 如果不激活到前端就不必要了。
//2。在后面对话框的实现中,定义为外部变量,extern CString onlyTitle;
//3。并在初始化函数中BOOL COnceDlg::OnInitDialog(),将其设置为标题 SetWindowText(onlyTitle);
//
CString onlyTitle="你是我的唯一";
BOOL COnceApp::IsFirstInstance(CString title)
{
//有以下3中方法,第一种最简单
//=====方法1 普通的简单方式
CWnd *pWndPrev, *pWndChild;
if (pWndPrev = CWnd::FindWindow(NULL,title))
{
//AfxMessageBox( _TEXT("只允许一个实例在运行!"));
pWndChild = pWndPrev->GetLastActivePopup();
if (pWndPrev->IsIconic())
pWndPrev->ShowWindow(SW_RESTORE);
pWndChild->SetForegroundWindow(); //找到并激活到前端
// pWndChild->PostMessage(WM_USER+100,0,0);//发消息让已经有的实例到前段,当然也可以发消息让其退出
return FALSE;
}
else
return TRUE; // 第一个实例
}
BOOL COnceApp::InitInstance()
{
if (!IsFirstInstance(onlyTitle))
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
COnceDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
===方法2===
// once.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "once.h"
#include "onceDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// COnceApp
BEGIN_MESSAGE_MAP(COnceApp, CWinApp)
//{{AFX_MSG_MAP(COnceApp)
//}}AFX_MSG_MAP
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/
// COnceApp construction
COnceApp::COnceApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/
// The one and only COnceApp object
COnceApp theApp;
/
// COnceApp initialization
//这里是应用程序的入口,还不能设置标题,需要到后面的出现窗口后才能设置标题
//以下4行代码,只对于方法2使用
#pragma comment( linker ,"/section:Shared,rws" ) //1 等同在链接器LINK标签选项中增加 /section:Shared,rws
#pragma data_seg("Shared")//2 在数据段中加变量
static LONG g_lInstanceCount = -1;
#pragma data_seg()
//1。声明唯一标题,只是为了后续实例查找激活到前端使用,对于方法2,3 如果不激活到前端就不必要了。
//2。在后面对话框的实现中,定义为外部变量,extern CString onlyTitle;
//3。并在初始化函数中BOOL COnceDlg::OnInitDialog(),将其设置为标题 SetWindowText(onlyTitle);
//
CString onlyTitle="你是我的唯一";
BOOL COnceApp::IsFirstInstance(CString title)
{
//=====方法2 全局的线程变量控制
BOOL bIsFirstInstance = (InterlockedIncrement(&g_lInstanceCount) == 0);
if (!bIsFirstInstance)
{
//AfxMessageBox( _TEXT("只允许一个实例在运行!"));
HWND hwnd=FindWindow(NULL,title );//查找自己的先前同类
ShowWindowAsync(hwnd, 1); //调用api函数,正常显示窗口
SetForegroundWindow(hwnd); //找到并激活到前端
return false;
}
else
return TRUE;// 第一个实例
}
BOOL COnceApp::InitInstance()
{
if (!IsFirstInstance(onlyTitle))
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
COnceDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
===方法3==
// once.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "once.h"
#include "onceDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// COnceApp
BEGIN_MESSAGE_MAP(COnceApp, CWinApp)
//{{AFX_MSG_MAP(COnceApp)
//}}AFX_MSG_MAP
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/
// COnceApp construction
COnceApp::COnceApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/
// The one and only COnceApp object
COnceApp theApp;
/
// COnceApp initialization
//这里是应用程序的入口,还不能设置标题,需要到后面的出现窗口后才能设置标题
//1。声明唯一标题,只是为了后续实例查找激活到前端使用,对于方法2,3 如果不激活到前端就不必要了。
//2。在后面对话框的实现中,定义为外部变量,extern CString onlyTitle;
//3。并在初始化函数中BOOL COnceDlg::OnInitDialog(),将其设置为标题 SetWindowText(onlyTitle);
//
CString onlyTitle="你是我的唯一";
BOOL COnceApp::IsFirstInstance(CString title)
{
//=====方法3 创建进程互斥体
HANDLE m_hMutex = CreateMutex(NULL,TRUE,_T("1"));
if (m_hMutex == NULL) return FALSE;
if (GetLastError() == ERROR_ALREADY_EXISTS)//如果程序已经存在并且正在运行
{
//MessageBox(NULL, _TEXT("只允许一个实例在运行!"), "提示", MB_OK | MB_ICONINFORMATION);
HWND hProgramWnd = ::FindWindow(NULL,_T(title));
if (hProgramWnd)
{
WINDOWPLACEMENT* pWndpl = NULL;
WINDOWPLACEMENT wpm;
pWndpl =&wpm;
GetWindowPlacement(hProgramWnd,&wpm);
if (pWndpl)
{
pWndpl->showCmd = SW_SHOWNORMAL;//将运行的程序窗口还原成正常状态
::SetWindowPlacement(hProgramWnd,pWndpl);
SetWindowPos(hProgramWnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);//找到并激活到前端
}
}
CloseHandle(m_hMutex);//关闭进程互斥体
m_hMutex = NULL;
return FALSE;
}
else
return TRUE;// 第一个实例
}
BOOL COnceApp::InitInstance()
{
if (!IsFirstInstance(onlyTitle))
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
COnceDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}