]> git.saurik.com Git - wxWidgets.git/blame - src/msw/snglinst.cpp
Fix for GetValue
[wxWidgets.git] / src / msw / snglinst.cpp
CommitLineData
68a602fc
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: msw/snglinst.cpp
3// Purpose: implements wxSingleInstanceChecker class for Win32 using
4// named mutexes
5// Author: Vadim Zeitlin
6// Modified by:
7// Created: 08.06.01
8// RCS-ID: $Id$
9// Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
10// License: wxWindows license
11///////////////////////////////////////////////////////////////////////////////
12
13// ============================================================================
14// declarations
15// ============================================================================
16
17// ----------------------------------------------------------------------------
18// headers
19// ----------------------------------------------------------------------------
20
21#ifdef __GNUG__
22 #pragma implementation "snglinst.h"
23#endif
24
25// For compilers that support precompilation, includes "wx.h".
26#include "wx/wxprec.h"
27
28#ifdef __BORLANDC__
29 #pragma hdrstop
30#endif
31
32#if wxUSE_SNGLINST_CHECKER && defined(__WIN32__)
33
34#ifndef WX_PRECOMP
35 #include "wx/string.h"
36 #include "wx/log.h"
37#endif //WX_PRECOMP
38
39#include "wx/snglinst.h"
40
41#include "wx/msw/private.h"
42
d08d71a8
CE
43//variables held in common by the callback and wxSingleInstanceCheckerImpl
44static HWND FirsthWnd;
45static wxString s_Title;
46
47// callback to look for windows whose titles include the search string
48// BCC (at least) does not like the callback to be part of the class :-((
49bool CALLBACK EnumWindowsProc ( HWND hwnd, LPARAM lParam )
50{
51 // Get the title of this window
52 int iTitleLen = ::GetWindowTextLength(hwnd);
53 // possible UNICODE/ANSI bug here, see SDK documentation,
54 // so allow extra space
55 char * cTitle = new char [iTitleLen*2+10] ;
56 ::GetWindowText(hwnd, cTitle, iTitleLen*2+10);
57
58 bool bSuccess = wxString(cTitle).Contains(s_Title) ;
59 delete [] cTitle ;
60
61 if (bSuccess)
62 {
63 FirsthWnd = hwnd ;
64 return FALSE ;
65 }
66 else
67 {
68 //not this window
69 return TRUE;
70 }
71
72}
73
68a602fc
VZ
74// ----------------------------------------------------------------------------
75// wxSingleInstanceCheckerImpl: the real implementation class
76// ----------------------------------------------------------------------------
77
78class WXDLLEXPORT wxSingleInstanceCheckerImpl
79{
80public:
81 wxSingleInstanceCheckerImpl()
82 {
83 // we don't care about m_wasOpened, it can't be accessed before being
84 // initialized
85 m_hMutex = NULL;
86 }
87
88 bool Create(const wxString& name)
89 {
90 m_hMutex = ::CreateMutex(NULL, FALSE, name);
91 if ( !m_hMutex )
92 {
93 wxLogLastError(_T("CreateMutex"));
94
95 return FALSE;
96 }
97
98 // mutex was either created or opened - see what really happened
99 m_wasOpened = ::GetLastError() == ERROR_ALREADY_EXISTS;
100
101 return TRUE;
102 }
103
104 bool WasOpened() const
105 {
106 wxCHECK_MSG( m_hMutex, FALSE,
107 _T("can't be called if mutex creation failed") );
108
109 return m_wasOpened;
d08d71a8
CE
110 };
111
112
113
114 // Activates Previous Instance if a window matching Title is found
115 bool ActivatePrevInstance(const wxString & sSearch)
116 {
117 //store search text and window handle for use by callback
118 s_Title = sSearch ;
119 FirsthWnd = 0;
120
121 EnumWindows (WNDENUMPROC(&EnumWindowsProc), 0L);
122 if (FirsthWnd == 0)
123 {
124 //no matching window found
125 return FALSE;
126 }
127
128 if (::IsIconic(FirsthWnd))
129 {
130 ::ShowWindow(FirsthWnd, SW_SHOWDEFAULT);
131 }
132 ::SetForegroundWindow(FirsthWnd);
133
134 // now try to deal with any active children
135 // Handles to child of previous instance
136 HWND FirstChildhWnd;
137
138 FirstChildhWnd = ::GetLastActivePopup(FirsthWnd);
139 if (FirsthWnd != FirstChildhWnd)
140 {
141 // A pop-up is active so bring it to the top too.
142 ::BringWindowToTop(FirstChildhWnd);
143 }
144 return TRUE;
145 }
146
147 // Activates Previous Instance and passes CommandLine to wxCommandLineEvent
148 // if a window matching Title is found
149 bool PassCommandLineToPrevInstance(const wxString & sTitle, const wxString & sCmdLine)
150 {
151 // this stores a string of up to 255 bytes
152 //ATOM myAtom = GlobalAddAtom ( sCmdLine );
153
154 // this would create a call to wxWindow::OnCommandLine(wxCommandLineEvent & event)
155 // which should retrieve the commandline, and then delete the atom, GlobalDeleteAtom( myAtom );
156 //::SendMessage (FirsthWnd, wxCOMMANDLINE_MESSAGE, 0, myAtom) ;
157 return FALSE;
68a602fc
VZ
158 }
159
160 ~wxSingleInstanceCheckerImpl()
161 {
162 if ( m_hMutex )
163 {
164 if ( !::CloseHandle(m_hMutex) )
165 {
166 wxLogLastError(_T("CloseHandle(mutex)"));
167 }
168 }
169 }
170
171private:
172 // the result of the CreateMutex() call
173 bool m_wasOpened;
174
175 // the mutex handle, may be NULL
176 HANDLE m_hMutex;
d08d71a8 177
68a602fc
VZ
178};
179
180// ============================================================================
181// wxSingleInstanceChecker implementation
182// ============================================================================
183
184bool wxSingleInstanceChecker::Create(const wxString& name,
d699f48b 185 const wxString& WXUNUSED(path))
68a602fc
VZ
186{
187 wxASSERT_MSG( !m_impl,
188 _T("calling wxSingleInstanceChecker::Create() twice?") );
189
190 // creating unnamed mutex doesn't have the same semantics!
191 wxASSERT_MSG( !name.empty(), _T("mutex name can't be empty") );
192
193 m_impl = new wxSingleInstanceCheckerImpl;
194
195 return m_impl->Create(name);
196}
197
198bool wxSingleInstanceChecker::IsAnotherRunning() const
199{
200 wxCHECK_MSG( m_impl, FALSE, _T("must call Create() first") );
201
202 // if the mutex had been opened, another instance is running - otherwise we
203 // would have created it
204 return m_impl->WasOpened();
205}
206
d08d71a8
CE
207 // Activates Previous Instance if a window whose Title contains the search string is found
208bool wxSingleInstanceChecker::ActivatePrevInstance(const wxString & sSearch)
209{
210 if (!IsAnotherRunning())
211 {
212 return FALSE;
213 }
214 return m_impl->ActivatePrevInstance(sSearch) ;
215}
216
217 // Activates Previous Instance and passes CommandLine to wxCommandLineEvent
218 // if a window matching Title is found
219bool wxSingleInstanceChecker::PassCommandLineToPrevInstance(const wxString & sSearch, const wxString & sCmdLine)
220{
221 if (!ActivatePrevInstance(sSearch))
222 {
223 return FALSE;
224 }
225 return m_impl->PassCommandLineToPrevInstance(sSearch, sCmdLine);
226}
227
68a602fc
VZ
228wxSingleInstanceChecker::~wxSingleInstanceChecker()
229{
230 delete m_impl;
231}
232
233#endif // wxUSE_SNGLINST_CHECKER