VC 对话框 只允许运行一个实例 ,如果有就激活到前端

来源:互联网 发布:centos 7.2怎么样 编辑:程序博客网 时间:2024/05/14 09:32

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;
}