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 classtemplate<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 upBOOL OnStartup(){return TRUE;}//Override this method to do some work on shut downvoid OnShutdown(){}//Override this method to support other native controlsvoid OnInitCommonControl(){AtlInitCommonControls(ICC_COOL_CLASSES|ICC_BAR_CLASSES|ICC_WIN95_CLASSES);}};//CApplication classtemplate<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 upif (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;}};
浙公网安备 33010602011771号