// MainFrm.cpp : implmentation of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "aboutdlg.h"
#include "testUniquleInstanceView.h"
#include "MainFrm.h"
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
if(CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg))
return TRUE;
return m_view.PreTranslateMessage(pMsg);
}
BOOL CMainFrame::OnIdle()
{
return FALSE;
}
LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
CreateSimpleCEMenuBar(IDR_MAINFRAME, SHCMBF_HMENU);
m_hWndClient = m_view.Create(m_hWnd);
// register object for message filtering and idle updates
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter(this);
pLoop->AddIdleHandler(this);
return 0;
}
LRESULT CMainFrame::OnFileExit(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
PostMessage(WM_CLOSE);
return 0;
}
LRESULT CMainFrame::OnFileNew(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
// TODO: add code to initialize document
return 0;
}
LRESULT CMainFrame::OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CAboutDlg dlg;
dlg.DoModal();
return 0;
}
HRESULT CMainFrame::ActivatePreviousInstance(HINSTANCE hInstance)
{
CFrameWndClassInfo& classInfo = CMainFrame::GetWndClassInfo();
int nRet = ::LoadString(hInstance, IDR_MAINFRAME, classInfo.m_szAutoName, sizeof(classInfo.m_szAutoName)/sizeof(classInfo.m_szAutoName[0]));
ATLASSERT(0 != nRet);
classInfo.m_wc.lpszClassName = classInfo.m_szAutoName;
const TCHAR* pszClass = classInfo.m_wc.lpszClassName;
if(NULL == pszClass || '\0' == *pszClass)
{
return E_FAIL;
}
// Orginally 500ms in SmartPhone 2003 App Wizard generated code
// A lower value will result in a more responsive start-up of
// the existing instance or termination of this instance.
const DWORD dRetryInterval = 100;
// Orginally 5 in SmartPhone 2003 App Wizard generated code
// Multiplied by 5, since wait time was divided by 5.
const int iMaxRetries = 25;
for(int i = 0; i < iMaxRetries; ++i)
{
// Don't need ownership of the mutex
HANDLE hMutex = CreateMutex(NULL, FALSE, pszClass);
DWORD dw = GetLastError();
if(NULL == hMutex)
{
HRESULT hr;
switch(dw)
{
case ERROR_INVALID_HANDLE:
// A non-mutext object with this name already exists.
hr = E_INVALIDARG;
break;
default:
// This should never happen...
hr = E_FAIL;
}
return hr;
}
// If the mutex already exists, then there should be another instance running
if(ERROR_ALREADY_EXISTS == dw)
{
// Just needed the error result, in this case, so close the handle.
CloseHandle(hMutex);
// Try to find the other instance, don't need to close HWND's.
// Don't check title in case it is changed by app after init.
HWND hwnd = FindWindow(pszClass, NULL);
if(NULL == hwnd)
{
// It's possible that the other istance is in the process of starting up or shutting down.
// So wait a bit and try again.
Sleep(dRetryInterval);
continue;
}
else
{
// Set the previous instance as the foreground window
// The "| 0x1" in the code below activates the correct owned window
// of the previous instance's main window according to the SmartPhone 2003
// wizard generated code.
if(0 != SetForegroundWindow(reinterpret_cast<HWND>(reinterpret_cast<ULONG>(hwnd) | 0x1)))
{
// S_FALSE indicates that another instance was activated, so this instance should terminate.
return S_FALSE;
}
}
}
else
{
// This is the first istance, so return S_OK.
// Don't close the mutext handle here.
// Do it on app shutdown instead.
return S_OK;
}
}
// The mutex was created by another instance, but it's window couldn't be brought
// to the foreground, so ssume it's not a invalid instance (not this app, hung, etc.)
// and let this one start.
return S_OK;
}
评论0