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;