1 #pragma once 2 3 #define UM_ACTIVATE (WM_USER + 0x2001) 4 #define SINGLE_STRING (TEXT( "0x13cc6a4e, 0x2e3a, 0x46fa, 0x9d, 0x60, 0x43, 0x85, 0x71, 0x64, 0xd0, 0x28" )) 5 6 class CSingleSign 7 { 8 HANDLE m_hMutex; 9 public: 10 CSingleSign() 11 { 12 HWND hWndPrevious; 13 14 m_hMutex = ::CreateMutex( NULL, FALSE, SINGLE_STRING ); 15 if ( GetLastError() == ERROR_ALREADY_EXISTS ) 16 { 17 hWndPrevious = ::GetWindow( ::GetDesktopWindow(), GW_CHILD ); 18 while ( ::IsWindow( hWndPrevious ) ) 19 { 20 if ( ::GetProp( hWndPrevious, SINGLE_STRING ) ) 21 { 22 ::PostMessage( hWndPrevious, UM_ACTIVATE, ( WPARAM )0, ( LPARAM )0 ); 23 break; 24 } 25 26 hWndPrevious = ::GetWindow( hWndPrevious, GW_HWNDNEXT ); 27 } 28 29 exit( 0 ); 30 } 31 32 if ( m_hMutex == NULL ) 33 { 34 exit( 0 ); 35 } 36 } 37 38 ~CSingleSign() 39 { 40 ::CloseHandle( m_hMutex ); 41 } 42 }; 43 44 45 template <typename T> 46 class ATL_NO_VTABLE CSingleApp 47 { 48 static CSingleSign _m_SingleSign; 49 public: 50 CSingleApp(){_m_SingleSign;} 51 52 BEGIN_MSG_MAP( CSingleApp<T> ) 53 MESSAGE_HANDLER( WM_CREATE, OnInitializeIt ) 54 MESSAGE_HANDLER( WM_INITDIALOG, OnInitializeIt ) 55 MESSAGE_HANDLER( WM_DESTROY, OnDestroy ) 56 MESSAGE_HANDLER( UM_ACTIVATE, OnActive ) 57 END_MSG_MAP() 58 59 60 LRESULT OnInitializeIt( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) 61 { 62 LRESULT lRet; 63 T* pT = static_cast<T*>( this ); 64 65 lRet = pT->InitializeIt( uMsg, wParam, lParam, bHandled ); 66 67 ::SetProp( pT->m_hWnd, SINGLE_STRING, ( HANDLE )1 ); 68 69 return lRet; 70 } 71 72 LRESULT OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) 73 { 74 T* pT = static_cast<T*>( this ); 75 76 ::RemoveProp( pT->m_hWnd, SINGLE_STRING ); 77 78 return pT->DestroyIt( uMsg, wParam, lParam, bHandled ); 79 } 80 81 82 LRESULT OnActive( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled ) 83 { 84 T* pT = static_cast<T*>( this ); 85 86 if ( pT->IsIconic() ) 87 { 88 pT->ShowWindow( SW_RESTORE ); 89 } 90 else 91 { 92 if ( !pT->IsWindowVisible() ) 93 { 94 pT->ShowWindow( SW_SHOW ); 95 ::BringWindowToTop( pT->m_hWnd ); 96 } 97 98 ::SetForegroundWindow( pT->m_hWnd ); 99 } 100 101 bHandled = TRUE; 102 return 0; 103 } 104 }; 105 106 107 template<typename T> 108 CSingleSign CSingleApp<T>::_m_SingleSign;