📄 sinstance.cpp
字号:
/*
Module : SINSTANCE.CPP
Purpose: Defines the implementation for an MFC wrapper classe
to do instance checking
Created: PJN / 29-07-1998
History: None
Copyright (c) 1998 by PJ Naughter.
All rights reserved.
*/
///////////////////////////////// Includes //////////////////////////////////
#include "stdafx.h"
#include "sinstance.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif
///////////////////////////////// Implementation //////////////////////////////
//struct which is put into shared memory
struct WININSTANCE_S
{
HWND hMainWnd;
};
//Class which be used as a static to ensure that we
//only close the file mapping at the very last chance
class CMmfManager
{
public:
CMmfManager();
~CMmfManager();
protected:
HANDLE m_hMMFCreated;
friend class CInstanceChecker;
};
CMmfManager::CMmfManager()
{
m_hMMFCreated = NULL;
}
CMmfManager::~CMmfManager()
{
if (m_hMMFCreated != NULL)
{
::CloseHandle(m_hMMFCreated);
m_hMMFCreated = NULL;
}
}
static CMmfManager g_obMmfManager;
//////////////////////////////////////////////////////////////////
// Instance checker class implement
//
CInstanceChecker::CInstanceChecker(LPCTSTR szAppName) :
m_mutexInstance(FALSE, szAppName)
{
// Only one object of type CInstanceChecker should be created
VERIFY(g_obMmfManager.m_hMMFCreated == NULL);
m_hPrevMMF = NULL;
m_sMMF = _T("InstanceChecker_MMF_");
m_sMMF += szAppName;
// lock during the checking period
m_mutexInstance.Lock(5000);
}
BOOL CInstanceChecker::InstanceIsRunning()
{
//Try to open the MMF first to see if we are the second instance
m_hPrevMMF = ::OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, m_sMMF);
return (m_hPrevMMF != NULL);
}
void CInstanceChecker::ActivatePrevInstance()
{
VERIFY(m_hPrevMMF != NULL); //Whats happened to my handle !
//Open up the MMF
int nMMFSize = sizeof(WININSTANCE_S);
WININSTANCE_S *pInstanceData = (WININSTANCE_S *) ::MapViewOfFile(m_hPrevMMF, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, nMMFSize);
VERIFY(pInstanceData != NULL); //Opening the MMF should work
//activate the old window
HWND hWindow = pInstanceData->hMainWnd;
CWnd wndPrev;
wndPrev.Attach(hWindow);
if( ::IsWindow(wndPrev.m_hWnd) )
{
CWnd *pWndChild = wndPrev.GetLastActivePopup();
if (wndPrev.IsIconic())
wndPrev.ShowWindow(SW_RESTORE);
pWndChild->SetForegroundWindow();
}
//Detach the CWnd we were using
wndPrev.Detach();
//Unmap the MMF we were using
VERIFY(::UnmapViewOfFile(pInstanceData));
//Close the MMF
VERIFY(::CloseHandle(m_hPrevMMF));
m_hPrevMMF = NULL;
}
void CInstanceChecker::SaveHwnd(HWND hWnd)
{
//If this is the first instance then copy our info into the shared memory
if (m_hPrevMMF != NULL)
{
return;
}
//Create the MMF
int nMMFSize = sizeof(WININSTANCE_S);
g_obMmfManager.m_hMMFCreated = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, nMMFSize, m_sMMF);
VERIFY(g_obMmfManager.m_hMMFCreated != NULL); //Creating the MMF should work
//Open the MMF
WININSTANCE_S *pInstanceData = (WININSTANCE_S *) ::MapViewOfFile(g_obMmfManager.m_hMMFCreated, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, nMMFSize);
VERIFY(pInstanceData != NULL); //Opening the MMF should work
ASSERT(hWnd != NULL);
pInstanceData->hMainWnd = hWnd;
VERIFY(::UnmapViewOfFile(pInstanceData));
}
CInstanceChecker::~CInstanceChecker()
{
if( m_hPrevMMF != NULL )
{
VERIFY(::CloseHandle(m_hPrevMMF));
}
m_mutexInstance.Unlock();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -