📄 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 CWindowInstance
{
HWND hMainWnd;
};
//Class which be used as a static to ensure that we
//only close the file mapping at the very last chance
class _INSTANCE_DATA
{
public:
_INSTANCE_DATA();
~ _INSTANCE_DATA();
protected:
HANDLE hInstanceData;
friend class CInstanceChecker;
};
_INSTANCE_DATA::_INSTANCE_DATA()
{
hInstanceData = NULL;
}
_INSTANCE_DATA::~_INSTANCE_DATA()
{
if (hInstanceData != NULL)
{
::CloseHandle(hInstanceData);
hInstanceData = NULL;
}
}
static _INSTANCE_DATA instanceData;
CInstanceChecker::CInstanceChecker()
{
// Only one object of type CInstanceChecker should be created
VERIFY(instanceData.hInstanceData == NULL);
m_hPrevInstance = NULL;
}
BOOL CInstanceChecker::PreviousInstanceRunning()
{
//MMF name is taken from MFC's AfxGetAppName
LPCTSTR pszAppName = AfxGetAppName();
ASSERT(pszAppName);
ASSERT(_tcslen(pszAppName)); //Missing the Application Title ?
CString sMMF(_T("CInstanceChecker_MMF_"));
sMMF += pszAppName;
//Try to open the MMF first to see if we are the second instance
m_hPrevInstance = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, sMMF);
//If this is the first instance then copy in our info into the shared memory
if (m_hPrevInstance == NULL)
{
//Create the MMF
int nMMFSize = sizeof(CWindowInstance);
instanceData.hInstanceData = ::CreateFileMapping((HANDLE) 0xFFFFFFFF,
NULL, PAGE_READWRITE, 0, nMMFSize,
sMMF);
VERIFY(instanceData.hInstanceData != NULL); //Creating the MMF should work
//Open the MMF
CWindowInstance* pInstanceData = (CWindowInstance*)
::MapViewOfFile(instanceData.hInstanceData,
FILE_MAP_READ |
FILE_MAP_WRITE,
0, 0, nMMFSize);
VERIFY(pInstanceData != NULL); //Opening the MMF should work
// Lock the data prior to updating it
CSingleLock dataLock(&m_instanceDataMutex, TRUE);
// ASSERT(AfxGetMainWnd() != NULL); //Did you forget to set up the mainfrm in InitInstance ?
// ASSERT(AfxGetMainWnd()->GetSafeHwnd() != NULL);
// pInstanceData->hMainWnd = AfxGetMainWnd()->GetSafeHwnd();
VERIFY(::UnmapViewOfFile(pInstanceData));
}
return (m_hPrevInstance != NULL);
}
void CInstanceChecker::ActivatePreviousInstance()
{
VERIFY(m_hPrevInstance != NULL); //Whats happened to my handle !
//Open up the MMF
int nMMFSize = sizeof(CWindowInstance);
CWindowInstance* pInstanceData = (CWindowInstance*)
::MapViewOfFile(m_hPrevInstance,
FILE_MAP_READ |
FILE_MAP_WRITE,
0, 0, nMMFSize);
VERIFY(pInstanceData != NULL); //Opening the MMF should work
// Lock the data prior to reading from it
CSingleLock dataLock(&m_instanceDataMutex, TRUE);
//activate the old window
HWND hWindow = pInstanceData->hMainWnd;
CWnd wndPrev;
wndPrev.Attach(hWindow);
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_hPrevInstance));
m_hPrevInstance = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -