WTL-支持Single instance的CApplicationT类

为CApplicationT添加了Single instance功能支持:

#pragma once

#include <Windows.h>

#include <ATLHelper.h>

#pragma data_seg("Shared")

volatile HWND _g_hMainWindow = NULL;

#pragma data_seg()

#pragma comment(linker,"/Section:Shared,RWS")

namespace WTL

{

//CApplicationT class

template<typename T, typename TMainWindow, bool bInitializeCom = false>

class CApplicationT :

    public CAppModule

{

public:

    //Call this method in the application's entry point[_tWinMain(...)]

    int WinMain(HINSTANCE hInstance,LPTSTR lpCmdLine,int nCmdShow)

    {

        UNREFERENCED_PARAMETER(lpCmdLine);

        T* pT = static_cast<T*>(this);

        if(!(pT->OnStartup()))

            return 0;

        HRESULT hr = S_OK;

        if (bInitializeCom)

        {

            hr = ::CoInitialize(NULL);

            // If you are running on NT 4.0 or higher you can use the following 

            // call instead to make the EXE free threaded. This means that calls 

            // come in on a random RPC thread.

            //  hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);

            CHECKHR(hr);

        }

        // This resolves ATL window thunking problem when Microsoft Layer 

        // for Unicode (MSLU) is used

        ::DefWindowProc(NULL, 0, 0, 0L);

        pT->OnInitCommonControl();

        hr = Init(NULL, hInstance);

        CHECKHR(hr);

        int nRet = 0;

        {

            CMessageLoop msgLoop;

            AddMessageLoop(&msgLoop);

            TMainWindow wndMain;

            _g_hMainWindow = wndMain.Create(NULL,CWindow::rcDefault);

            if(_g_hMainWindow == NULL)

            {

                ATLTRACE(_T("Failed to create Main window!\n"));

                return 0;

            }

            wndMain.ShowWindow(nCmdShow);

            wndMain.UpdateWindow();

            wndMain.CenterWindow();

            nRet = msgLoop.Run();

            RemoveMessageLoop();

            _g_hMainWindow = NULL;

        }

        Term();

        if (bInitializeCom)

            ::CoUninitialize();

        pT->OnShutdown();

        return nRet;

    }

public:

    BOOL IsAnotherInstanceRunning()

    {

        return (_g_hMainWindow!=NULL);

    }

    void TakeAnotherInstanceForeground()

    {

        if (_g_hMainWindow)

        {

            CWindow mainWnd(_g_hMainWindow);

            if (mainWnd.IsIconic())

                mainWnd.ShowWindow(SW_RESTORE);

            mainWnd.SetForegroundWindow();

        }

    }

protected:

    //Override this method to do some work on start up

    BOOL OnStartup()

    {

        return TRUE;

    }

    //Override this method to do some work on shut down

    void OnShutdown()

    {}

    //Override this method to support other native controls

    void OnInitCommonControl()

    {

        AtlInitCommonControls(ICC_COOL_CLASSES|ICC_BAR_CLASSES|ICC_WIN95_CLASSES);

    }

};

//CApplication class

template<typename TMainWindow, bool bInitializeCom = false>

class CApplication :

    public CApplicationT<CApplication<TMainWindow,bInitializeCom>, TMainWindow, bInitializeCom>

{

};

}//namespace WTL

使用方法:

1.如果CApplicationT提供的功能已满足要求,不需要修改默认行为,也不需要添加Single instance功能支持,可直接用typedef定义自己的WTL应用程序类:

typedef CWinTraits<WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN> CMainWinTraits;

class CMainWindow :

    public CWindowImpl<CMainWindow,CWindow,CMainWinTraits>

{

public:

    //...

};

typedef CApplication<CMainWindow> CMainApp;

CMainApp g_MainApp;

2.如果需要使用Single instance功能,则可以覆盖OnStartup()方法,执行单程序实例检测:

class CMainApp :

    public CApplicationT<CMainApp,CMainWindow>

{

public:

    BOOL OnStartup()

    {

        //Check if another instance is running on start up

        if (IsAnotherInstanceRunning())

        {

            ::MessageBox(

                NULL,

                _T("Another instance is running.\n\nClick OK to take another instance foreground."),

                _T("WTL message"),

                MB_OK|MB_ICONINFORMATION);

            TakeAnotherInstanceForeground();

            return FALSE;

        }

        return TRUE;

    }

};

你可能感兴趣的:(application)