1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * Copyright 2003, 2004, 2005 Martin Fuchs
3*c2c66affSColin Finck *
4*c2c66affSColin Finck * This library is free software; you can redistribute it and/or
5*c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
6*c2c66affSColin Finck * License as published by the Free Software Foundation; either
7*c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
8*c2c66affSColin Finck *
9*c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
10*c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12*c2c66affSColin Finck * Lesser General Public License for more details.
13*c2c66affSColin Finck *
14*c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
15*c2c66affSColin Finck * License along with this library; if not, write to the Free Software
16*c2c66affSColin Finck * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17*c2c66affSColin Finck */
18*c2c66affSColin Finck
19*c2c66affSColin Finck
20*c2c66affSColin Finck //
21*c2c66affSColin Finck // Explorer clone
22*c2c66affSColin Finck //
23*c2c66affSColin Finck // utility.h
24*c2c66affSColin Finck //
25*c2c66affSColin Finck // Martin Fuchs, 23.07.2003
26*c2c66affSColin Finck //
27*c2c66affSColin Finck
28*c2c66affSColin Finck // standard windows headers
29*c2c66affSColin Finck #define WIN32_LEAN_AND_MEAN
30*c2c66affSColin Finck #define WIN32_EXTRA_LEAN
31*c2c66affSColin Finck #define WIN32_NO_STATUS
32*c2c66affSColin Finck #define _INC_WINDOWS
33*c2c66affSColin Finck #define COM_NO_WINDOWS_H
34*c2c66affSColin Finck #include <stdarg.h>
35*c2c66affSColin Finck #include <windef.h>
36*c2c66affSColin Finck #include <winbase.h>
37*c2c66affSColin Finck #include <winuser.h>
38*c2c66affSColin Finck
39*c2c66affSColin Finck //#include <undocuser.h>
40*c2c66affSColin Finck
41*c2c66affSColin Finck // Unicode support
42*c2c66affSColin Finck #if defined(UNICODE) && !defined(_UNICODE)
43*c2c66affSColin Finck #define _UNICODE
44*c2c66affSColin Finck #endif
45*c2c66affSColin Finck #include <tchar.h>
46*c2c66affSColin Finck
47*c2c66affSColin Finck #include <windowsx.h> // for SelectBrush(), ListBox_SetSel(), SubclassWindow(), ...
48*c2c66affSColin Finck #include <commctrl.h>
49*c2c66affSColin Finck
50*c2c66affSColin Finck #include <objbase.h>
51*c2c66affSColin Finck //#include <oleauto.h> // for VARIANT
52*c2c66affSColin Finck
53*c2c66affSColin Finck //#include <malloc.h> // for alloca()
54*c2c66affSColin Finck #include <assert.h>
55*c2c66affSColin Finck //#include <stdlib.h> // for _MAX_DIR, ...
56*c2c66affSColin Finck #include <stdio.h> // for sprintf()
57*c2c66affSColin Finck //#include <time.h>
58*c2c66affSColin Finck
59*c2c66affSColin Finck #ifdef __cplusplus
60*c2c66affSColin Finck
61*c2c66affSColin Finck #ifdef _MSC_VER
62*c2c66affSColin Finck #pragma warning(disable: 4786) // disable warnings about too long debug information symbols
63*c2c66affSColin Finck #endif
64*c2c66affSColin Finck
65*c2c66affSColin Finck // STL headers for strings and streams
66*c2c66affSColin Finck #include <string>
67*c2c66affSColin Finck #include <iostream>
68*c2c66affSColin Finck using namespace std;
69*c2c66affSColin Finck
70*c2c66affSColin Finck #endif /* __cplusplus */
71*c2c66affSColin Finck
72*c2c66affSColin Finck #ifndef _MAX_PATH
73*c2c66affSColin Finck #define _MAX_DRIVE 3
74*c2c66affSColin Finck #define _MAX_FNAME 256
75*c2c66affSColin Finck #define _MAX_DIR _MAX_FNAME
76*c2c66affSColin Finck #define _MAX_EXT _MAX_FNAME
77*c2c66affSColin Finck #define _MAX_PATH 260
78*c2c66affSColin Finck #endif
79*c2c66affSColin Finck
80*c2c66affSColin Finck #define W_VER_NT 0 // constant for HIWORD(GetVersion())>>14
81*c2c66affSColin Finck
82*c2c66affSColin Finck
83*c2c66affSColin Finck #ifdef __cplusplus
84*c2c66affSColin Finck extern "C" {
85*c2c66affSColin Finck #endif
86*c2c66affSColin Finck
87*c2c66affSColin Finck
88*c2c66affSColin Finck #define for if (0) {} else for
89*c2c66affSColin Finck
90*c2c66affSColin Finck #ifdef _countof
91*c2c66affSColin Finck #define COUNTOF _countof
92*c2c66affSColin Finck #else
93*c2c66affSColin Finck #define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
94*c2c66affSColin Finck #endif
95*c2c66affSColin Finck
96*c2c66affSColin Finck
97*c2c66affSColin Finck #define BUFFER_LEN 2048
98*c2c66affSColin Finck
99*c2c66affSColin Finck
100*c2c66affSColin Finck extern void _log_(LPCTSTR txt);
101*c2c66affSColin Finck
102*c2c66affSColin Finck #define LOG(txt) _log_(txt)
103*c2c66affSColin Finck
104*c2c66affSColin Finck
105*c2c66affSColin Finck #ifdef _MSC_VER
106*c2c66affSColin Finck #define LONGLONGARG TEXT("I64")
107*c2c66affSColin Finck #else
108*c2c66affSColin Finck #define LONGLONGARG TEXT("L")
109*c2c66affSColin Finck #endif
110*c2c66affSColin Finck
111*c2c66affSColin Finck
112*c2c66affSColin Finck #ifndef _tcsrchr
113*c2c66affSColin Finck #ifdef UNICODE
114*c2c66affSColin Finck #define _tcsrchr wcsrchr
115*c2c66affSColin Finck #else
116*c2c66affSColin Finck #define _tcsrchr strrchr
117*c2c66affSColin Finck #endif
118*c2c66affSColin Finck #endif
119*c2c66affSColin Finck
120*c2c66affSColin Finck #ifndef _stprintf
121*c2c66affSColin Finck #ifdef UNICODE
122*c2c66affSColin Finck #define _stprintf wcsprintf
123*c2c66affSColin Finck #else
124*c2c66affSColin Finck #define _stprintf sprintf
125*c2c66affSColin Finck #endif
126*c2c66affSColin Finck #endif
127*c2c66affSColin Finck
128*c2c66affSColin Finck #define U2A(s, d, l) WideCharToMultiByte(CP_ACP, 0, s, -1, d, l, NULL, NULL)
129*c2c66affSColin Finck #define U2nA(s, d, l) WideCharToMultiByte(CP_ACP, 0, s, l, d, l, NULL, NULL)
130*c2c66affSColin Finck #define A2U(s, d, l) MultiByteToWideChar(CP_ACP, 0, s, -1, d, l)
131*c2c66affSColin Finck #define A2nU(s, d, l) MultiByteToWideChar(CP_ACP, 0, s, l, d, l)
132*c2c66affSColin Finck
133*c2c66affSColin Finck
134*c2c66affSColin Finck #ifdef __WINE__
135*c2c66affSColin Finck #ifdef UNICODE
136*c2c66affSColin Finck extern void _wsplitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext);
137*c2c66affSColin Finck #else
138*c2c66affSColin Finck extern void _splitpath(const CHAR* path, CHAR* drv, CHAR* dir, CHAR* name, CHAR* ext);
139*c2c66affSColin Finck #endif
140*c2c66affSColin Finck #define _tcsnicmp strncasecmp
141*c2c66affSColin Finck #define _tcsicoll strcasecmp
142*c2c66affSColin Finck #endif
143*c2c66affSColin Finck
144*c2c66affSColin Finck #ifndef FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
145*c2c66affSColin Finck #define FILE_ATTRIBUTE_ENCRYPTED 0x00000040
146*c2c66affSColin Finck #define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
147*c2c66affSColin Finck #define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
148*c2c66affSColin Finck #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
149*c2c66affSColin Finck #endif
150*c2c66affSColin Finck
151*c2c66affSColin Finck
152*c2c66affSColin Finck #define SetDlgCtrlID(hwnd, id) SetWindowLongPtr(hwnd, GWL_ID, id)
153*c2c66affSColin Finck #define SetWindowStyle(hwnd, val) (DWORD)SetWindowLongPtr(hwnd, GWL_STYLE, val)
154*c2c66affSColin Finck #define SetWindowExStyle(h, val) (DWORD)SetWindowLongPtr(hwnd, GWL_EXSTYLE, val)
155*c2c66affSColin Finck #define Window_SetIcon(hwnd, type, hicon) (HICON)SendMessage(hwnd, WM_SETICON, type, (LPARAM)(hicon))
156*c2c66affSColin Finck
157*c2c66affSColin Finck
158*c2c66affSColin Finck // center window in respect to its parent window
159*c2c66affSColin Finck extern void CenterWindow(HWND hwnd);
160*c2c66affSColin Finck
161*c2c66affSColin Finck // move window into visibility
162*c2c66affSColin Finck extern void MoveVisible(HWND hwnd);
163*c2c66affSColin Finck
164*c2c66affSColin Finck // display error message
165*c2c66affSColin Finck extern void display_error(HWND hwnd, DWORD error);
166*c2c66affSColin Finck
167*c2c66affSColin Finck // convert time_t to WIN32 FILETIME
168*c2c66affSColin Finck extern BOOL time_to_filetime(const time_t* t, FILETIME* ftime);
169*c2c66affSColin Finck
170*c2c66affSColin Finck // search for windows of a specific classname
171*c2c66affSColin Finck extern int find_window_class(LPCTSTR classname);
172*c2c66affSColin Finck
173*c2c66affSColin Finck // create a directory with all missing parent directories
174*c2c66affSColin Finck BOOL RecursiveCreateDirectory(LPCTSTR path_in);
175*c2c66affSColin Finck
176*c2c66affSColin Finck // read DWORD value from registry
177*c2c66affSColin Finck DWORD RegGetDWORDValue(HKEY root, LPCTSTR path, LPCTSTR valueName, DWORD def);
178*c2c66affSColin Finck
179*c2c66affSColin Finck // write DWORD value to registry
180*c2c66affSColin Finck BOOL RegSetDWORDValue(HKEY root, LPCTSTR path, LPCTSTR valueName, DWORD value);
181*c2c66affSColin Finck
182*c2c66affSColin Finck // test for existing directory
183*c2c66affSColin Finck BOOL exists_path(LPCTSTR path);
184*c2c66affSColin Finck
185*c2c66affSColin Finck
186*c2c66affSColin Finck #ifdef __cplusplus
187*c2c66affSColin Finck } // extern "C"
188*c2c66affSColin Finck #endif
189*c2c66affSColin Finck
190*c2c66affSColin Finck
191*c2c66affSColin Finck // secure CRT functions
192*c2c66affSColin Finck //@@ _MS_VER: temporarily needed for the ReactOS build environment
193*c2c66affSColin Finck #if defined(__STDC_WANT_SECURE_LIB__) && defined(_MS_VER) // for VS 2005: _MSC_VER>=1400
194*c2c66affSColin Finck
195*c2c66affSColin Finck #define _stprintf_s1 _stprintf_s
196*c2c66affSColin Finck #define _stprintf_s2 _stprintf_s
197*c2c66affSColin Finck
198*c2c66affSColin Finck #else // __STDC_WANT_SECURE_LIB__
199*c2c66affSColin Finck
200*c2c66affSColin Finck #define strcpy_s(d, l, s) strcpy(d, s)
201*c2c66affSColin Finck #define wcscpy_s(d, l, s) wcscpy(d, s)
202*c2c66affSColin Finck #define wcsncpy_s(d, l, s, n) wcsncpy(d, s, n)
203*c2c66affSColin Finck
204*c2c66affSColin Finck #if defined(_tcscpy) && !defined(_tcscpy_s)
205*c2c66affSColin Finck #define _tcscpy_s(d, l, s) _tcscpy(d, s)
206*c2c66affSColin Finck #endif
207*c2c66affSColin Finck
208*c2c66affSColin Finck #if defined(_tsplitpath) && !defined(_tsplitpath_s)
209*c2c66affSColin Finck #define _tsplitpath_s(f, d,dl, p,pl, n,nl, e,el) _tsplitpath(f, d, p, n, e)
210*c2c66affSColin Finck #else
211*c2c66affSColin Finck #define _wsplitpath_s(f, d,dl, p,pl, n,nl, e,el) _wsplitpath(f, d, p, n, e)
212*c2c66affSColin Finck #define _splitpath_s(f, d,dl, p,pl, n,nl, e,el) _splitpath(f, d, p, n, e)
213*c2c66affSColin Finck #endif
214*c2c66affSColin Finck
215*c2c66affSColin Finck #define _stprintf_s1(b, l, f, p1) _stprintf(b, f, p1)
216*c2c66affSColin Finck #define _stprintf_s2(b, l, f, p1,p2) _stprintf(b, f, p1,p2)
217*c2c66affSColin Finck
218*c2c66affSColin Finck #endif // __STDC_WANT_SECURE_LIB__
219*c2c66affSColin Finck
220*c2c66affSColin Finck
221*c2c66affSColin Finck #ifdef __cplusplus
222*c2c66affSColin Finck
223*c2c66affSColin Finck // containers
224*c2c66affSColin Finck #include <map>
225*c2c66affSColin Finck #include <set>
226*c2c66affSColin Finck #include <list>
227*c2c66affSColin Finck #include <stack>
228*c2c66affSColin Finck #include <vector>
229*c2c66affSColin Finck
230*c2c66affSColin Finck
231*c2c66affSColin Finck /* not necessary with correct include file order for comdef.h ("<MS PSDK>\include" path first) */
232*c2c66affSColin Finck #if _MSC_VER>=1300 // VS.Net
233*c2c66affSColin Finck #define _NO_COMUTIL
234*c2c66affSColin Finck #endif
235*c2c66affSColin Finck
236*c2c66affSColin Finck
237*c2c66affSColin Finck #if defined(_MSC_VER) && !defined(_NO_COMUTIL)
238*c2c66affSColin Finck
239*c2c66affSColin Finck // COM utility headers
240*c2c66affSColin Finck #include <comdef.h>
241*c2c66affSColin Finck using namespace _com_util;
242*c2c66affSColin Finck
243*c2c66affSColin Finck #endif // _MSC_VER && !_NO_COMUTIL
244*c2c66affSColin Finck
245*c2c66affSColin Finck
246*c2c66affSColin Finck // launch a program or document file
247*c2c66affSColin Finck extern BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow=SW_SHOWNORMAL, LPCTSTR parameters=NULL);
248*c2c66affSColin Finck #ifdef UNICODE
249*c2c66affSColin Finck extern BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow=SW_SHOWNORMAL, LPCSTR parameters=NULL);
250*c2c66affSColin Finck #else
251*c2c66affSColin Finck #define launch_fileA launch_file
252*c2c66affSColin Finck #endif
253*c2c66affSColin Finck
254*c2c66affSColin Finck // call an DLL export like rundll32
255*c2c66affSColin Finck extern BOOL RunDLL(HWND hwnd, LPCTSTR dllname, LPCSTR procname, LPCTSTR cmdline, UINT nCmdShow);
256*c2c66affSColin Finck
257*c2c66affSColin Finck // launch control panel applet
258*c2c66affSColin Finck extern BOOL launch_cpanel(HWND hwnd, LPCTSTR applet);
259*c2c66affSColin Finck
260*c2c66affSColin Finck
261*c2c66affSColin Finck /// initialization of windows common controls
262*c2c66affSColin Finck struct CommonControlInit
263*c2c66affSColin Finck {
264*c2c66affSColin Finck CommonControlInit(DWORD flags=ICC_LISTVIEW_CLASSES|ICC_TREEVIEW_CLASSES|ICC_BAR_CLASSES|ICC_PROGRESS_CLASS|ICC_COOL_CLASSES)
265*c2c66affSColin Finck {
266*c2c66affSColin Finck INITCOMMONCONTROLSEX icc = {sizeof(INITCOMMONCONTROLSEX), flags};
267*c2c66affSColin Finck
268*c2c66affSColin Finck InitCommonControlsEx(&icc);
269*c2c66affSColin Finck }
270*c2c66affSColin Finck };
271*c2c66affSColin Finck
272*c2c66affSColin Finck
273*c2c66affSColin Finck /// wait cursor
274*c2c66affSColin Finck
275*c2c66affSColin Finck struct WaitCursor ///@todo integrate with WM_SETCURSOR to enable multithreaded background tasks as program launching
276*c2c66affSColin Finck {
WaitCursorWaitCursor277*c2c66affSColin Finck WaitCursor()
278*c2c66affSColin Finck {
279*c2c66affSColin Finck _old_cursor = SetCursor(LoadCursor(0, IDC_WAIT));
280*c2c66affSColin Finck }
281*c2c66affSColin Finck
~WaitCursorWaitCursor282*c2c66affSColin Finck ~WaitCursor()
283*c2c66affSColin Finck {
284*c2c66affSColin Finck SetCursor(_old_cursor);
285*c2c66affSColin Finck }
286*c2c66affSColin Finck
287*c2c66affSColin Finck protected:
288*c2c66affSColin Finck HCURSOR _old_cursor;
289*c2c66affSColin Finck };
290*c2c66affSColin Finck
291*c2c66affSColin Finck
292*c2c66affSColin Finck /// base of all structures storing a window handle
293*c2c66affSColin Finck struct WindowHandle
294*c2c66affSColin Finck {
295*c2c66affSColin Finck WindowHandle(HWND hwnd=0)
_hwndWindowHandle296*c2c66affSColin Finck : _hwnd(hwnd) {}
297*c2c66affSColin Finck
HWNDWindowHandle298*c2c66affSColin Finck operator HWND() const {return _hwnd;}
299*c2c66affSColin Finck HWND* operator&() {return &_hwnd;}
300*c2c66affSColin Finck
301*c2c66affSColin Finck protected:
302*c2c66affSColin Finck HWND _hwnd;
303*c2c66affSColin Finck };
304*c2c66affSColin Finck
305*c2c66affSColin Finck
306*c2c66affSColin Finck /// locally hide a window
307*c2c66affSColin Finck struct HiddenWindow : public WindowHandle
308*c2c66affSColin Finck {
HiddenWindowHiddenWindow309*c2c66affSColin Finck HiddenWindow(HWND hwnd)
310*c2c66affSColin Finck : WindowHandle(IsWindowVisible(hwnd)? hwnd: 0)
311*c2c66affSColin Finck {
312*c2c66affSColin Finck if (_hwnd)
313*c2c66affSColin Finck SetWindowPos(_hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW|SWP_NOREDRAW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
314*c2c66affSColin Finck }
315*c2c66affSColin Finck
~HiddenWindowHiddenWindow316*c2c66affSColin Finck ~HiddenWindow()
317*c2c66affSColin Finck {
318*c2c66affSColin Finck if (_hwnd)
319*c2c66affSColin Finck SetWindowPos(_hwnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
320*c2c66affSColin Finck }
321*c2c66affSColin Finck };
322*c2c66affSColin Finck
323*c2c66affSColin Finck
324*c2c66affSColin Finck /// critical section wrapper
325*c2c66affSColin Finck
326*c2c66affSColin Finck struct CritSect : public CRITICAL_SECTION
327*c2c66affSColin Finck {
CritSectCritSect328*c2c66affSColin Finck CritSect()
329*c2c66affSColin Finck {
330*c2c66affSColin Finck InitializeCriticalSection(this);
331*c2c66affSColin Finck }
332*c2c66affSColin Finck
~CritSectCritSect333*c2c66affSColin Finck ~CritSect()
334*c2c66affSColin Finck {
335*c2c66affSColin Finck DeleteCriticalSection(this);
336*c2c66affSColin Finck }
337*c2c66affSColin Finck };
338*c2c66affSColin Finck
339*c2c66affSColin Finck
340*c2c66affSColin Finck /// Lock protects a code section utilizing a critical section
341*c2c66affSColin Finck
342*c2c66affSColin Finck struct Lock
343*c2c66affSColin Finck {
LockLock344*c2c66affSColin Finck Lock(CritSect& crit_sect)
345*c2c66affSColin Finck : _crit_sect(crit_sect)
346*c2c66affSColin Finck {
347*c2c66affSColin Finck EnterCriticalSection(&crit_sect);
348*c2c66affSColin Finck }
349*c2c66affSColin Finck
~LockLock350*c2c66affSColin Finck ~Lock()
351*c2c66affSColin Finck {
352*c2c66affSColin Finck LeaveCriticalSection(&_crit_sect);
353*c2c66affSColin Finck }
354*c2c66affSColin Finck
355*c2c66affSColin Finck protected:
356*c2c66affSColin Finck CritSect& _crit_sect;
357*c2c66affSColin Finck };
358*c2c66affSColin Finck
359*c2c66affSColin Finck
360*c2c66affSColin Finck /// Thread base class
361*c2c66affSColin Finck
362*c2c66affSColin Finck struct Thread
363*c2c66affSColin Finck {
ThreadThread364*c2c66affSColin Finck Thread()
365*c2c66affSColin Finck : _alive(false),
366*c2c66affSColin Finck _destroy(false)
367*c2c66affSColin Finck {
368*c2c66affSColin Finck _hThread = INVALID_HANDLE_VALUE;
369*c2c66affSColin Finck _evtFinish = CreateEvent(NULL, TRUE, FALSE, NULL);
370*c2c66affSColin Finck }
371*c2c66affSColin Finck
~ThreadThread372*c2c66affSColin Finck virtual ~Thread()
373*c2c66affSColin Finck {
374*c2c66affSColin Finck Stop();
375*c2c66affSColin Finck
376*c2c66affSColin Finck CloseHandle(_evtFinish);
377*c2c66affSColin Finck CloseHandle(_hThread);
378*c2c66affSColin Finck
379*c2c66affSColin Finck if (_destroy)
380*c2c66affSColin Finck delete this;
381*c2c66affSColin Finck }
382*c2c66affSColin Finck
StartThread383*c2c66affSColin Finck void Start()
384*c2c66affSColin Finck {
385*c2c66affSColin Finck if (!_alive) {
386*c2c66affSColin Finck _alive = true;
387*c2c66affSColin Finck _hThread = CreateThread(NULL, 0, ThreadProc, this, 0, NULL);
388*c2c66affSColin Finck }
389*c2c66affSColin Finck }
390*c2c66affSColin Finck
StopThread391*c2c66affSColin Finck void Stop()
392*c2c66affSColin Finck {
393*c2c66affSColin Finck SetEvent(_evtFinish);
394*c2c66affSColin Finck
395*c2c66affSColin Finck if (_alive) {
396*c2c66affSColin Finck {
397*c2c66affSColin Finck Lock lock(_crit_sect);
398*c2c66affSColin Finck _alive = false;
399*c2c66affSColin Finck }
400*c2c66affSColin Finck
401*c2c66affSColin Finck // wait for finishing
402*c2c66affSColin Finck WaitForSingleObject(_hThread, INFINITE);
403*c2c66affSColin Finck }
404*c2c66affSColin Finck }
405*c2c66affSColin Finck
406*c2c66affSColin Finck virtual int Run() = 0;
407*c2c66affSColin Finck
is_aliveThread408*c2c66affSColin Finck bool is_alive() const {return _alive;}
409*c2c66affSColin Finck
410*c2c66affSColin Finck CritSect _crit_sect;
411*c2c66affSColin Finck
412*c2c66affSColin Finck protected:
413*c2c66affSColin Finck static DWORD WINAPI ThreadProc(void* para);
414*c2c66affSColin Finck
415*c2c66affSColin Finck HANDLE _hThread;
416*c2c66affSColin Finck HANDLE _evtFinish;
417*c2c66affSColin Finck bool _alive;
418*c2c66affSColin Finck bool _destroy;
419*c2c66affSColin Finck };
420*c2c66affSColin Finck
421*c2c66affSColin Finck
422*c2c66affSColin Finck // window utilities
423*c2c66affSColin Finck
424*c2c66affSColin Finck /// ClientRect retreives the client area rectangle of a window.
425*c2c66affSColin Finck struct ClientRect : public RECT
426*c2c66affSColin Finck {
ClientRectClientRect427*c2c66affSColin Finck ClientRect(HWND hwnd)
428*c2c66affSColin Finck {
429*c2c66affSColin Finck GetClientRect(hwnd, this);
430*c2c66affSColin Finck }
431*c2c66affSColin Finck
LPRECTClientRect432*c2c66affSColin Finck operator LPRECT() {return this;}
433*c2c66affSColin Finck
posClientRect434*c2c66affSColin Finck POINT& pos() {return *(LPPOINT)this;}
435*c2c66affSColin Finck };
436*c2c66affSColin Finck
437*c2c66affSColin Finck /// ClientRect retreives the window rectangle of a window.
438*c2c66affSColin Finck struct WindowRect : public RECT
439*c2c66affSColin Finck {
WindowRectWindowRect440*c2c66affSColin Finck WindowRect(HWND hwnd)
441*c2c66affSColin Finck {
442*c2c66affSColin Finck GetWindowRect(hwnd, this);
443*c2c66affSColin Finck }
444*c2c66affSColin Finck
LPRECTWindowRect445*c2c66affSColin Finck operator LPRECT() {return this;}
446*c2c66affSColin Finck
posWindowRect447*c2c66affSColin Finck POINT& pos() {return *(LPPOINT)this;}
448*c2c66affSColin Finck };
449*c2c66affSColin Finck
450*c2c66affSColin Finck /// PointL encapsulates the POINT structure into a C++ object.
451*c2c66affSColin Finck struct Point : public POINT
452*c2c66affSColin Finck {
PointPoint453*c2c66affSColin Finck Point(LONG x_, LONG y_)
454*c2c66affSColin Finck {
455*c2c66affSColin Finck x = x_;
456*c2c66affSColin Finck y = y_;
457*c2c66affSColin Finck }
458*c2c66affSColin Finck
459*c2c66affSColin Finck // constructor for being used in processing WM_MOUSEMOVE, WM_LBUTTONDOWN, ... messages
PointPoint460*c2c66affSColin Finck Point(LPARAM lparam)
461*c2c66affSColin Finck {
462*c2c66affSColin Finck x = GET_X_LPARAM(lparam);
463*c2c66affSColin Finck y = GET_Y_LPARAM(lparam);
464*c2c66affSColin Finck }
465*c2c66affSColin Finck
LPPOINTPoint466*c2c66affSColin Finck operator LPPOINT() {return this;}
467*c2c66affSColin Finck };
468*c2c66affSColin Finck
469*c2c66affSColin Finck
470*c2c66affSColin Finck /// transform coordinates in a RECT from client to screen coordiantes
ClientToScreen(HWND hwnd,RECT * prect)471*c2c66affSColin Finck inline void ClientToScreen(HWND hwnd, RECT* prect)
472*c2c66affSColin Finck {::ClientToScreen(hwnd,(LPPOINT)&prect->left); ::ClientToScreen(hwnd,(LPPOINT)&prect->right);}
473*c2c66affSColin Finck
474*c2c66affSColin Finck /// transform coordinates in a RECT from screen to client coordiantes
ScreenToClient(HWND hwnd,RECT * prect)475*c2c66affSColin Finck inline void ScreenToClient(HWND hwnd, RECT* prect)
476*c2c66affSColin Finck {::ScreenToClient(hwnd,(LPPOINT)&prect->left); ::ScreenToClient(hwnd,(LPPOINT)&prect->right);}
477*c2c66affSColin Finck
478*c2c66affSColin Finck
479*c2c66affSColin Finck /// structure containing information about full screen display of the frame window
480*c2c66affSColin Finck struct FullScreenParameters
481*c2c66affSColin Finck {
FullScreenParametersFullScreenParameters482*c2c66affSColin Finck FullScreenParameters()
483*c2c66affSColin Finck : _mode(FALSE)
484*c2c66affSColin Finck {
485*c2c66affSColin Finck }
486*c2c66affSColin Finck
487*c2c66affSColin Finck BOOL _mode;
488*c2c66affSColin Finck RECT _orgPos;
489*c2c66affSColin Finck BOOL _wasZoomed;
490*c2c66affSColin Finck };
491*c2c66affSColin Finck
492*c2c66affSColin Finck
493*c2c66affSColin Finck // drawing utilities
494*c2c66affSColin Finck
495*c2c66affSColin Finck /// PaintCanvas is a encapsulation of device contexts managed by BeginPaint()/EndPaint().
496*c2c66affSColin Finck struct PaintCanvas : public PAINTSTRUCT
497*c2c66affSColin Finck {
PaintCanvasPaintCanvas498*c2c66affSColin Finck PaintCanvas(HWND hwnd)
499*c2c66affSColin Finck : _hwnd(hwnd)
500*c2c66affSColin Finck {
501*c2c66affSColin Finck BeginPaint(hwnd, this);
502*c2c66affSColin Finck }
503*c2c66affSColin Finck
~PaintCanvasPaintCanvas504*c2c66affSColin Finck ~PaintCanvas()
505*c2c66affSColin Finck {
506*c2c66affSColin Finck EndPaint(_hwnd, this);
507*c2c66affSColin Finck }
508*c2c66affSColin Finck
HDCPaintCanvas509*c2c66affSColin Finck operator HDC() const {return hdc;}
510*c2c66affSColin Finck
511*c2c66affSColin Finck protected:
512*c2c66affSColin Finck HWND _hwnd;
513*c2c66affSColin Finck };
514*c2c66affSColin Finck
515*c2c66affSColin Finck /// Canvas is a encapsulation of device contexts.
516*c2c66affSColin Finck struct Canvas
517*c2c66affSColin Finck {
CanvasCanvas518*c2c66affSColin Finck Canvas(HDC hdc) : _hdc(hdc) {}
519*c2c66affSColin Finck
HDCCanvas520*c2c66affSColin Finck operator HDC() {return _hdc;}
521*c2c66affSColin Finck
522*c2c66affSColin Finck protected:
523*c2c66affSColin Finck HDC _hdc;
524*c2c66affSColin Finck };
525*c2c66affSColin Finck
526*c2c66affSColin Finck /// WindowCanvas is a encapsulation of client area device contexts.
527*c2c66affSColin Finck struct WindowCanvas : public Canvas
528*c2c66affSColin Finck {
WindowCanvasWindowCanvas529*c2c66affSColin Finck WindowCanvas(HWND hwnd)
530*c2c66affSColin Finck : Canvas(GetDC(hwnd)), _hwnd(hwnd) {}
531*c2c66affSColin Finck
~WindowCanvasWindowCanvas532*c2c66affSColin Finck ~WindowCanvas() {ReleaseDC(_hwnd, _hdc);}
533*c2c66affSColin Finck
534*c2c66affSColin Finck protected:
535*c2c66affSColin Finck HWND _hwnd;
536*c2c66affSColin Finck };
537*c2c66affSColin Finck
538*c2c66affSColin Finck
539*c2c66affSColin Finck // double buffering classes
540*c2c66affSColin Finck
541*c2c66affSColin Finck /// Memory Canvas creates and destroys memory devoce contexts.
542*c2c66affSColin Finck struct MemCanvas : public Canvas
543*c2c66affSColin Finck {
544*c2c66affSColin Finck MemCanvas(HDC hdc=0)
CanvasMemCanvas545*c2c66affSColin Finck : Canvas(CreateCompatibleDC(hdc)) {assert(_hdc);}
546*c2c66affSColin Finck
~MemCanvasMemCanvas547*c2c66affSColin Finck ~MemCanvas() {DeleteDC(_hdc);}
548*c2c66affSColin Finck };
549*c2c66affSColin Finck
550*c2c66affSColin Finck /// SelectedBitmap is used to localy select bitmaps into device contexts.
551*c2c66affSColin Finck struct SelectedBitmap
552*c2c66affSColin Finck {
SelectedBitmapSelectedBitmap553*c2c66affSColin Finck SelectedBitmap(HDC hdc, HBITMAP hbmp)
554*c2c66affSColin Finck : _hdc(hdc), _old_hbmp(SelectBitmap(hdc, hbmp)) {}
555*c2c66affSColin Finck
~SelectedBitmapSelectedBitmap556*c2c66affSColin Finck ~SelectedBitmap() {DeleteObject(SelectBitmap(_hdc, _old_hbmp));}
557*c2c66affSColin Finck
558*c2c66affSColin Finck protected:
559*c2c66affSColin Finck HDC _hdc;
560*c2c66affSColin Finck HBITMAP _old_hbmp;
561*c2c66affSColin Finck };
562*c2c66affSColin Finck
563*c2c66affSColin Finck /// BufferCanvas manages offscreen bitmaps selected into memory device contexts.
564*c2c66affSColin Finck struct BufferCanvas : public MemCanvas
565*c2c66affSColin Finck {
BufferCanvasBufferCanvas566*c2c66affSColin Finck BufferCanvas(HDC hdc, int x, int y, int w, int h)
567*c2c66affSColin Finck : MemCanvas(hdc), _hdctarg(hdc),
568*c2c66affSColin Finck _x(x), _y(y), _w(w), _h(h),
569*c2c66affSColin Finck _bmp(_hdc, CreateCompatibleBitmap(hdc, w, h)) {}
570*c2c66affSColin Finck
BufferCanvasBufferCanvas571*c2c66affSColin Finck BufferCanvas(HDC hdc, const RECT& rect)
572*c2c66affSColin Finck : MemCanvas(hdc), _hdctarg(hdc),
573*c2c66affSColin Finck _x(rect.left), _y(rect.top), _w(rect.right-rect.left), _h(rect.bottom-rect.top),
574*c2c66affSColin Finck _bmp(_hdc, CreateCompatibleBitmap(hdc, _w, _h)) {}
575*c2c66affSColin Finck
576*c2c66affSColin Finck protected:
577*c2c66affSColin Finck HDC _hdctarg;
578*c2c66affSColin Finck int _x, _y, _w, _h;
579*c2c66affSColin Finck SelectedBitmap _bmp;
580*c2c66affSColin Finck };
581*c2c66affSColin Finck
582*c2c66affSColin Finck /// BufferedCanvas enables double buffering for a device context.
583*c2c66affSColin Finck struct BufferedCanvas : public BufferCanvas
584*c2c66affSColin Finck {
585*c2c66affSColin Finck BufferedCanvas(HDC hdc, int x, int y, int w, int h, DWORD mode=SRCCOPY)
BufferCanvasBufferedCanvas586*c2c66affSColin Finck : BufferCanvas(hdc, x, y, w, h), _mode(mode) {}
587*c2c66affSColin Finck
588*c2c66affSColin Finck BufferedCanvas(HDC hdc, const RECT& rect, DWORD mode=SRCCOPY)
BufferCanvasBufferedCanvas589*c2c66affSColin Finck : BufferCanvas(hdc, rect), _mode(mode) {}
590*c2c66affSColin Finck
~BufferedCanvasBufferedCanvas591*c2c66affSColin Finck ~BufferedCanvas() {BitBlt(_hdctarg, _x, _y, _w, _h, _hdc, 0, 0, _mode);}
592*c2c66affSColin Finck
593*c2c66affSColin Finck DWORD _mode;
594*c2c66affSColin Finck };
595*c2c66affSColin Finck
596*c2c66affSColin Finck /// BufferedPaintCanvas extends PaintCanvas for double buffering.
597*c2c66affSColin Finck struct BufferedPaintCanvas : public PaintCanvas, public BufferedCanvas
598*c2c66affSColin Finck {
BufferedPaintCanvasBufferedPaintCanvas599*c2c66affSColin Finck BufferedPaintCanvas(HWND hwnd)
600*c2c66affSColin Finck : PaintCanvas(hwnd),
601*c2c66affSColin Finck BufferedCanvas(PAINTSTRUCT::hdc, 0, 0, rcPaint.right, rcPaint.bottom)
602*c2c66affSColin Finck {
603*c2c66affSColin Finck }
604*c2c66affSColin Finck
HDCBufferedPaintCanvas605*c2c66affSColin Finck operator HDC() {return BufferedCanvas::_hdc;}
606*c2c66affSColin Finck };
607*c2c66affSColin Finck
608*c2c66affSColin Finck
609*c2c66affSColin Finck /// TextColor locally selects a text color for drawing.
610*c2c66affSColin Finck struct TextColor
611*c2c66affSColin Finck {
TextColorTextColor612*c2c66affSColin Finck TextColor(HDC hdc, COLORREF color)
613*c2c66affSColin Finck : _hdc(hdc), _old_color(SetTextColor(hdc, color)) {}
614*c2c66affSColin Finck
~TextColorTextColor615*c2c66affSColin Finck ~TextColor() {SetTextColor(_hdc, _old_color);}
616*c2c66affSColin Finck
617*c2c66affSColin Finck protected:
618*c2c66affSColin Finck HDC _hdc;
619*c2c66affSColin Finck COLORREF _old_color;
620*c2c66affSColin Finck };
621*c2c66affSColin Finck
622*c2c66affSColin Finck /// BkMode locally sets the background mode for drawing.
623*c2c66affSColin Finck struct BkMode
624*c2c66affSColin Finck {
BkModeBkMode625*c2c66affSColin Finck BkMode(HDC hdc, int bkmode)
626*c2c66affSColin Finck : _hdc(hdc), _old_bkmode(SetBkMode(hdc, bkmode)) {}
627*c2c66affSColin Finck
~BkModeBkMode628*c2c66affSColin Finck ~BkMode() {SetBkMode(_hdc, _old_bkmode);}
629*c2c66affSColin Finck
630*c2c66affSColin Finck protected:
631*c2c66affSColin Finck HDC _hdc;
632*c2c66affSColin Finck COLORREF _old_bkmode;
633*c2c66affSColin Finck };
634*c2c66affSColin Finck
635*c2c66affSColin Finck /// FontSelection locally selects a font for drawing.
636*c2c66affSColin Finck struct FontSelection
637*c2c66affSColin Finck {
FontSelectionFontSelection638*c2c66affSColin Finck FontSelection(HDC hdc, HFONT hFont)
639*c2c66affSColin Finck : _hdc(hdc), _old_hFont(SelectFont(hdc, hFont)) {}
640*c2c66affSColin Finck
~FontSelectionFontSelection641*c2c66affSColin Finck ~FontSelection() {SelectFont(_hdc, _old_hFont);}
642*c2c66affSColin Finck
643*c2c66affSColin Finck protected:
644*c2c66affSColin Finck HDC _hdc;
645*c2c66affSColin Finck HFONT _old_hFont;
646*c2c66affSColin Finck };
647*c2c66affSColin Finck
648*c2c66affSColin Finck /// BitmapSelection locally selects a bitmap into a device context.
649*c2c66affSColin Finck struct BitmapSelection
650*c2c66affSColin Finck {
BitmapSelectionBitmapSelection651*c2c66affSColin Finck BitmapSelection(HDC hdc, HBITMAP hBmp)
652*c2c66affSColin Finck : _hdc(hdc), _old_hBmp(SelectBitmap(hdc, hBmp)) {}
653*c2c66affSColin Finck
~BitmapSelectionBitmapSelection654*c2c66affSColin Finck ~BitmapSelection() {SelectBitmap(_hdc, _old_hBmp);}
655*c2c66affSColin Finck
656*c2c66affSColin Finck protected:
657*c2c66affSColin Finck HDC _hdc;
658*c2c66affSColin Finck HBITMAP _old_hBmp;
659*c2c66affSColin Finck };
660*c2c66affSColin Finck
661*c2c66affSColin Finck /// BrushSelection locally selects a brush into a device context.
662*c2c66affSColin Finck struct BrushSelection
663*c2c66affSColin Finck {
BrushSelectionBrushSelection664*c2c66affSColin Finck BrushSelection(HDC hdc, HBRUSH hBrush)
665*c2c66affSColin Finck : _hdc(hdc), _old_hBrush(SelectBrush(hdc, hBrush)) {}
666*c2c66affSColin Finck
~BrushSelectionBrushSelection667*c2c66affSColin Finck ~BrushSelection() {SelectBrush(_hdc, _old_hBrush);}
668*c2c66affSColin Finck
669*c2c66affSColin Finck protected:
670*c2c66affSColin Finck HDC _hdc;
671*c2c66affSColin Finck HBRUSH _old_hBrush;
672*c2c66affSColin Finck };
673*c2c66affSColin Finck
674*c2c66affSColin Finck
675*c2c66affSColin Finck /// Popup Menus
676*c2c66affSColin Finck struct PopupMenu
677*c2c66affSColin Finck {
PopupMenuPopupMenu678*c2c66affSColin Finck PopupMenu()
679*c2c66affSColin Finck : _hmenu(CreatePopupMenu())
680*c2c66affSColin Finck {
681*c2c66affSColin Finck }
682*c2c66affSColin Finck
~PopupMenuPopupMenu683*c2c66affSColin Finck ~PopupMenu()
684*c2c66affSColin Finck {
685*c2c66affSColin Finck DestroyMenu(_hmenu);
686*c2c66affSColin Finck }
687*c2c66affSColin Finck
688*c2c66affSColin Finck PopupMenu(UINT nid);
689*c2c66affSColin Finck
HMENUPopupMenu690*c2c66affSColin Finck operator HMENU() {return _hmenu;}
691*c2c66affSColin Finck
692*c2c66affSColin Finck void Append(UINT id, LPCTSTR str, UINT flags=MF_STRING)
693*c2c66affSColin Finck {
694*c2c66affSColin Finck AppendMenu(_hmenu, flags, id, str);
695*c2c66affSColin Finck }
696*c2c66affSColin Finck
697*c2c66affSColin Finck int TrackPopupMenu(HWND hwnd, const POINT& pt, UINT flags=TPM_LEFTBUTTON|TPM_RIGHTBUTTON, LPTPMPARAMS tpm=NULL) {
698*c2c66affSColin Finck return TrackPopupMenuEx(_hmenu, flags, pt.x, pt.y, hwnd, tpm);
699*c2c66affSColin Finck }
700*c2c66affSColin Finck
701*c2c66affSColin Finck int PopupContextMenu(HWND hwnd, POINTS pos, UINT flags=TPM_LEFTBUTTON|TPM_RIGHTBUTTON) {
702*c2c66affSColin Finck POINT pt;
703*c2c66affSColin Finck pt.x = pos.x;
704*c2c66affSColin Finck pt.y = pos.y;
705*c2c66affSColin Finck return TrackPopupMenuEx(_hmenu, flags, pt.x, pt.y, hwnd, NULL);
706*c2c66affSColin Finck }
707*c2c66affSColin Finck
708*c2c66affSColin Finck int TrackPopupMenu(HWND hwnd, POINTS pos, UINT flags=TPM_LEFTBUTTON|TPM_RIGHTBUTTON) {
709*c2c66affSColin Finck POINT pt;
710*c2c66affSColin Finck pt.x = pos.x;
711*c2c66affSColin Finck pt.y = pos.y;
712*c2c66affSColin Finck ClientToScreen(hwnd, &pt);
713*c2c66affSColin Finck return TrackPopupMenuEx(_hmenu, flags, pt.x, pt.y, hwnd, NULL);
714*c2c66affSColin Finck }
715*c2c66affSColin Finck
716*c2c66affSColin Finck int TrackPopupMenuAtCursor(HWND hwnd, UINT flags=TPM_LEFTBUTTON) {
717*c2c66affSColin Finck POINT pt; GetCursorPos(&pt);
718*c2c66affSColin Finck return TrackPopupMenuEx(_hmenu, flags, pt.x, pt.y, hwnd, NULL);
719*c2c66affSColin Finck }
720*c2c66affSColin Finck
721*c2c66affSColin Finck int TrackPopupMenuAtPos(HWND hwnd, DWORD pos, UINT flags=TPM_LEFTBUTTON) {
722*c2c66affSColin Finck return TrackPopupMenuEx(_hmenu, flags, GET_X_LPARAM(pos), GET_Y_LPARAM(pos), hwnd, NULL);
723*c2c66affSColin Finck }
724*c2c66affSColin Finck
725*c2c66affSColin Finck protected:
726*c2c66affSColin Finck HMENU _hmenu;
727*c2c66affSColin Finck };
728*c2c66affSColin Finck
729*c2c66affSColin Finck
730*c2c66affSColin Finck struct Variant : public VARIANT
731*c2c66affSColin Finck {
VariantVariant732*c2c66affSColin Finck Variant() {VariantInit(this);}
733*c2c66affSColin Finck Variant(const VARIANT& var);
734*c2c66affSColin Finck Variant(const VARIANT* var);
735*c2c66affSColin Finck ~Variant();
736*c2c66affSColin Finck
737*c2c66affSColin Finck operator long() const;
738*c2c66affSColin Finck operator bool() const;
739*c2c66affSColin Finck operator VARIANT_BOOL() const;
740*c2c66affSColin Finck operator IDispatch*() const;
741*c2c66affSColin Finck };
742*c2c66affSColin Finck
743*c2c66affSColin Finck
744*c2c66affSColin Finck struct BStr
745*c2c66affSColin Finck {
BStrBStr746*c2c66affSColin Finck BStr()
747*c2c66affSColin Finck {
748*c2c66affSColin Finck _p = NULL;
749*c2c66affSColin Finck }
750*c2c66affSColin Finck
BStrBStr751*c2c66affSColin Finck BStr(const BSTR s)
752*c2c66affSColin Finck {
753*c2c66affSColin Finck _p = SysAllocString(s);
754*c2c66affSColin Finck }
755*c2c66affSColin Finck
BStrBStr756*c2c66affSColin Finck BStr(LPCSTR s)
757*c2c66affSColin Finck {
758*c2c66affSColin Finck WCHAR b[BUFFER_LEN];
759*c2c66affSColin Finck
760*c2c66affSColin Finck if (s)
761*c2c66affSColin Finck _p = SysAllocStringLen(b, MultiByteToWideChar(CP_ACP, 0, s, -1, b, BUFFER_LEN)-1);
762*c2c66affSColin Finck else
763*c2c66affSColin Finck _p = NULL;
764*c2c66affSColin Finck }
765*c2c66affSColin Finck
BStrBStr766*c2c66affSColin Finck BStr(LPCWSTR s)
767*c2c66affSColin Finck {
768*c2c66affSColin Finck _p = SysAllocString(s);
769*c2c66affSColin Finck }
770*c2c66affSColin Finck
BStrBStr771*c2c66affSColin Finck BStr(const VARIANT& var)
772*c2c66affSColin Finck : _p(NULL)
773*c2c66affSColin Finck {
774*c2c66affSColin Finck assign(var);
775*c2c66affSColin Finck }
776*c2c66affSColin Finck
~BStrBStr777*c2c66affSColin Finck ~BStr()
778*c2c66affSColin Finck {
779*c2c66affSColin Finck SysFreeString(_p);
780*c2c66affSColin Finck }
781*c2c66affSColin Finck
782*c2c66affSColin Finck void assign(BSTR s);
783*c2c66affSColin Finck void assign(const VARIANT& var);
784*c2c66affSColin Finck
BSTRBStr785*c2c66affSColin Finck operator BSTR() const
786*c2c66affSColin Finck {
787*c2c66affSColin Finck return _p? _p: (BSTR)L"";
788*c2c66affSColin Finck }
789*c2c66affSColin Finck
lengthBStr790*c2c66affSColin Finck int length() const
791*c2c66affSColin Finck {
792*c2c66affSColin Finck return _p? wcslen(_p): 0;
793*c2c66affSColin Finck }
794*c2c66affSColin Finck
795*c2c66affSColin Finck protected:
796*c2c66affSColin Finck BSTR _p;
797*c2c66affSColin Finck };
798*c2c66affSColin Finck
799*c2c66affSColin Finck
800*c2c66affSColin Finck /// string class for TCHAR strings
801*c2c66affSColin Finck struct String
802*c2c66affSColin Finck #ifdef UNICODE
803*c2c66affSColin Finck : public wstring
804*c2c66affSColin Finck #else
805*c2c66affSColin Finck : public string
806*c2c66affSColin Finck #endif
807*c2c66affSColin Finck {
808*c2c66affSColin Finck #ifdef UNICODE
809*c2c66affSColin Finck typedef wstring super;
810*c2c66affSColin Finck #else
811*c2c66affSColin Finck typedef string super;
812*c2c66affSColin Finck #endif
813*c2c66affSColin Finck
StringString814*c2c66affSColin Finck String() {}
815*c2c66affSColin Finck
StringString816*c2c66affSColin Finck String(LPCTSTR s) {if (s) super::assign(s);}
StringString817*c2c66affSColin Finck String(LPCTSTR s, int l) : super(s, l) {}
818*c2c66affSColin Finck
StringString819*c2c66affSColin Finck String(const super& other) : super(other) {}
StringString820*c2c66affSColin Finck String(const String& other) : super(other) {}
821*c2c66affSColin Finck
822*c2c66affSColin Finck #ifdef UNICODE
StringString823*c2c66affSColin Finck String(LPCSTR s) {assign(s);}
StringString824*c2c66affSColin Finck String(LPCSTR s, int l) {assign(s, l);}
StringString825*c2c66affSColin Finck String(const string& other) {assign(other.c_str());}
826*c2c66affSColin Finck String& operator=(LPCSTR s) {assign(s); return *this;}
assignString827*c2c66affSColin Finck void assign(LPCSTR s) {if (s) {TCHAR b[BUFFER_LEN]; super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, -1, b, BUFFER_LEN)-1);} else erase();}
assignString828*c2c66affSColin Finck void assign(LPCSTR s, int l) {if (s) {TCHAR b[BUFFER_LEN]; super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, l, b, BUFFER_LEN));} else erase();}
assignString829*c2c66affSColin Finck void assign(const BStr& s) {int l = s.length(); super::assign(s, l);}
830*c2c66affSColin Finck #else
StringString831*c2c66affSColin Finck String(LPCWSTR s) {assign(s);}
StringString832*c2c66affSColin Finck String(LPCWSTR s, int l) {assign(s, l);}
StringString833*c2c66affSColin Finck String(const wstring& other) {assign(other.c_str());}
834*c2c66affSColin Finck String& operator=(LPCWSTR s) {assign(s); return *this;}
assignString835*c2c66affSColin Finck void assign(LPCWSTR s) {if (s) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, -1, b, BUFFER_LEN, 0, 0)-1);} else erase();}
assignString836*c2c66affSColin Finck void assign(LPCWSTR s, int l) {if (s) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, l, b, BUFFER_LEN, 0, 0));} else erase();}
assignString837*c2c66affSColin Finck void assign(const BStr& s) {int l = s.length(); if (l) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, l, b, BUFFER_LEN, 0, 0));} else erase();}
838*c2c66affSColin Finck #endif
StringString839*c2c66affSColin Finck String(const BStr& s) {assign(s);}
840*c2c66affSColin Finck String& operator=(const BStr& s) {assign(s); return *this;}
841*c2c66affSColin Finck
842*c2c66affSColin Finck String& operator=(LPCTSTR s) {if (s) super::assign(s); else erase(); return *this;}
843*c2c66affSColin Finck String& operator=(const super& s) {super::assign(s); return *this;}
assignString844*c2c66affSColin Finck void assign(LPCTSTR s) {super::assign(s);}
assignString845*c2c66affSColin Finck void assign(LPCTSTR s, int l) {super::assign(s, l);}
846*c2c66affSColin Finck
LPCTSTRString847*c2c66affSColin Finck operator LPCTSTR() const {return c_str();}
848*c2c66affSColin Finck
849*c2c66affSColin Finck #ifdef UNICODE
stringString850*c2c66affSColin Finck operator string() const {char b[BUFFER_LEN]; return string(b, WideCharToMultiByte(CP_ACP, 0, c_str(), -1, b, BUFFER_LEN, 0, 0)-1);}
851*c2c66affSColin Finck #else
wstringString852*c2c66affSColin Finck operator wstring() const {WCHAR b[BUFFER_LEN]; return wstring(b, MultiByteToWideChar(CP_ACP, 0, c_str(), -1, b, BUFFER_LEN)-1);}
853*c2c66affSColin Finck #endif
854*c2c66affSColin Finck
strString855*c2c66affSColin Finck LPTSTR str() {return (LPTSTR)data();} /// return modifyable character string pointer
856*c2c66affSColin Finck
printfString857*c2c66affSColin Finck String& printf(LPCTSTR fmt, ...)
858*c2c66affSColin Finck {
859*c2c66affSColin Finck va_list l;
860*c2c66affSColin Finck TCHAR b[BUFFER_LEN];
861*c2c66affSColin Finck
862*c2c66affSColin Finck va_start(l, fmt);
863*c2c66affSColin Finck super::assign(b, _vsntprintf(b, COUNTOF(b), fmt, l));
864*c2c66affSColin Finck va_end(l);
865*c2c66affSColin Finck
866*c2c66affSColin Finck return *this;
867*c2c66affSColin Finck }
868*c2c66affSColin Finck
vprintfString869*c2c66affSColin Finck String& vprintf(LPCTSTR fmt, va_list l)
870*c2c66affSColin Finck {
871*c2c66affSColin Finck TCHAR b[BUFFER_LEN];
872*c2c66affSColin Finck
873*c2c66affSColin Finck super::assign(b, _vsntprintf(b, COUNTOF(b), fmt, l));
874*c2c66affSColin Finck
875*c2c66affSColin Finck return *this;
876*c2c66affSColin Finck }
877*c2c66affSColin Finck
appendfString878*c2c66affSColin Finck String& appendf(LPCTSTR fmt, ...)
879*c2c66affSColin Finck {
880*c2c66affSColin Finck va_list l;
881*c2c66affSColin Finck TCHAR b[BUFFER_LEN];
882*c2c66affSColin Finck
883*c2c66affSColin Finck va_start(l, fmt);
884*c2c66affSColin Finck super::append(b, _vsntprintf(b, COUNTOF(b), fmt, l));
885*c2c66affSColin Finck va_end(l);
886*c2c66affSColin Finck
887*c2c66affSColin Finck return *this;
888*c2c66affSColin Finck }
889*c2c66affSColin Finck
vappendfString890*c2c66affSColin Finck String& vappendf(LPCTSTR fmt, va_list l)
891*c2c66affSColin Finck {
892*c2c66affSColin Finck TCHAR b[BUFFER_LEN];
893*c2c66affSColin Finck
894*c2c66affSColin Finck super::append(b, _vsntprintf(b, COUNTOF(b), fmt, l));
895*c2c66affSColin Finck
896*c2c66affSColin Finck return *this;
897*c2c66affSColin Finck }
898*c2c66affSColin Finck
toLowerString899*c2c66affSColin Finck void toLower()
900*c2c66affSColin Finck {
901*c2c66affSColin Finck if (!empty())
902*c2c66affSColin Finck CharLower(str());
903*c2c66affSColin Finck }
904*c2c66affSColin Finck };
905*c2c66affSColin Finck
906*c2c66affSColin Finck #define _STRING_DEFINED
907*c2c66affSColin Finck
908*c2c66affSColin Finck
909*c2c66affSColin Finck struct FmtString : public String
910*c2c66affSColin Finck {
FmtStringFmtString911*c2c66affSColin Finck FmtString(LPCTSTR fmt, ...)
912*c2c66affSColin Finck {
913*c2c66affSColin Finck va_list l;
914*c2c66affSColin Finck
915*c2c66affSColin Finck va_start(l, fmt);
916*c2c66affSColin Finck vprintf(fmt, l);
917*c2c66affSColin Finck va_end(l);
918*c2c66affSColin Finck }
919*c2c66affSColin Finck };
920*c2c66affSColin Finck
921*c2c66affSColin Finck
922*c2c66affSColin Finck #ifdef UNICODE
923*c2c66affSColin Finck
924*c2c66affSColin Finck struct ANS
925*c2c66affSColin Finck {
ANSANS926*c2c66affSColin Finck ANS(LPCWSTR s)
927*c2c66affSColin Finck {
928*c2c66affSColin Finck int l = wcslen(s) + 1;
929*c2c66affSColin Finck _str = (LPSTR) malloc(2*l);
930*c2c66affSColin Finck
931*c2c66affSColin Finck if (WideCharToMultiByte(CP_ACP, 0, s, -1, _str, 2*l, 0, 0) <= 0)
932*c2c66affSColin Finck *_str = '\0';
933*c2c66affSColin Finck }
934*c2c66affSColin Finck
~ANSANS935*c2c66affSColin Finck ~ANS()
936*c2c66affSColin Finck {
937*c2c66affSColin Finck free(_str);
938*c2c66affSColin Finck }
939*c2c66affSColin Finck
LPCSTRANS940*c2c66affSColin Finck operator LPCSTR() {return _str;}
941*c2c66affSColin Finck
942*c2c66affSColin Finck protected:
943*c2c66affSColin Finck LPSTR _str;
944*c2c66affSColin Finck };
945*c2c66affSColin Finck
946*c2c66affSColin Finck #define UNC(x) ((LPCWSTR)(x))
947*c2c66affSColin Finck
948*c2c66affSColin Finck #else
949*c2c66affSColin Finck
950*c2c66affSColin Finck #define ANS(x) ((LPCSTR)(x))
951*c2c66affSColin Finck
952*c2c66affSColin Finck struct UNC
953*c2c66affSColin Finck {
UNCUNC954*c2c66affSColin Finck UNC(LPCSTR s)
955*c2c66affSColin Finck {
956*c2c66affSColin Finck int l = strlen(s) + 1;
957*c2c66affSColin Finck _str = (LPWSTR) malloc(2*l);
958*c2c66affSColin Finck
959*c2c66affSColin Finck if (_str && MultiByteToWideChar(CP_ACP, 0, s, -1, _str, l) <= 0)
960*c2c66affSColin Finck *_str = '\0';
961*c2c66affSColin Finck }
962*c2c66affSColin Finck
~UNCUNC963*c2c66affSColin Finck ~UNC()
964*c2c66affSColin Finck {
965*c2c66affSColin Finck free(_str);
966*c2c66affSColin Finck }
967*c2c66affSColin Finck
LPCWSTRUNC968*c2c66affSColin Finck operator LPCWSTR() {return _str;}
969*c2c66affSColin Finck
970*c2c66affSColin Finck protected:
971*c2c66affSColin Finck LPWSTR _str;
972*c2c66affSColin Finck };
973*c2c66affSColin Finck
974*c2c66affSColin Finck #endif
975*c2c66affSColin Finck
976*c2c66affSColin Finck
977*c2c66affSColin Finck // determine windows version string
978*c2c66affSColin Finck String get_windows_version_str();
979*c2c66affSColin Finck
980*c2c66affSColin Finck
981*c2c66affSColin Finck /// link dynamicly to functions by using GetModuleHandle() and GetProcAddress()
982*c2c66affSColin Finck template<typename FCT> struct DynamicFct
983*c2c66affSColin Finck {
DynamicFctDynamicFct984*c2c66affSColin Finck DynamicFct(LPCTSTR moduleName, UINT ordinal)
985*c2c66affSColin Finck {
986*c2c66affSColin Finck HMODULE hModule = GetModuleHandle(moduleName);
987*c2c66affSColin Finck
988*c2c66affSColin Finck _fct = (FCT) GetProcAddress(hModule, (LPCSTR)ordinal);
989*c2c66affSColin Finck }
990*c2c66affSColin Finck
DynamicFctDynamicFct991*c2c66affSColin Finck DynamicFct(LPCTSTR moduleName, LPCSTR name)
992*c2c66affSColin Finck {
993*c2c66affSColin Finck HMODULE hModule = GetModuleHandle(moduleName);
994*c2c66affSColin Finck
995*c2c66affSColin Finck _fct = (FCT) GetProcAddress(hModule, name);
996*c2c66affSColin Finck }
997*c2c66affSColin Finck
998*c2c66affSColin Finck FCT operator*() const {return _fct;}
999*c2c66affSColin Finck operator bool() const {return _fct? true: false;}
1000*c2c66affSColin Finck
1001*c2c66affSColin Finck protected:
1002*c2c66affSColin Finck FCT _fct;
1003*c2c66affSColin Finck };
1004*c2c66affSColin Finck
1005*c2c66affSColin Finck
1006*c2c66affSColin Finck /// link dynamicly to functions by using LoadLibrary() and GetProcAddress()
1007*c2c66affSColin Finck template<typename FCT> struct DynamicLoadLibFct
1008*c2c66affSColin Finck {
DynamicLoadLibFctDynamicLoadLibFct1009*c2c66affSColin Finck DynamicLoadLibFct(LPCTSTR moduleName, UINT ordinal)
1010*c2c66affSColin Finck {
1011*c2c66affSColin Finck _hModule = LoadLibrary(moduleName);
1012*c2c66affSColin Finck
1013*c2c66affSColin Finck _fct = (FCT) GetProcAddress(_hModule, (LPCSTR)ordinal);
1014*c2c66affSColin Finck }
1015*c2c66affSColin Finck
DynamicLoadLibFctDynamicLoadLibFct1016*c2c66affSColin Finck DynamicLoadLibFct(LPCTSTR moduleName, LPCSTR name)
1017*c2c66affSColin Finck {
1018*c2c66affSColin Finck _hModule = LoadLibrary(moduleName);
1019*c2c66affSColin Finck
1020*c2c66affSColin Finck _fct = (FCT) GetProcAddress(_hModule, name);
1021*c2c66affSColin Finck }
1022*c2c66affSColin Finck
~DynamicLoadLibFctDynamicLoadLibFct1023*c2c66affSColin Finck ~DynamicLoadLibFct()
1024*c2c66affSColin Finck {
1025*c2c66affSColin Finck FreeLibrary(_hModule);
1026*c2c66affSColin Finck }
1027*c2c66affSColin Finck
1028*c2c66affSColin Finck FCT operator*() const {return _fct;}
1029*c2c66affSColin Finck operator bool() const {return _fct? true: false;}
1030*c2c66affSColin Finck
1031*c2c66affSColin Finck protected:
1032*c2c66affSColin Finck HMODULE _hModule;
1033*c2c66affSColin Finck FCT _fct;
1034*c2c66affSColin Finck };
1035*c2c66affSColin Finck
1036*c2c66affSColin Finck
1037*c2c66affSColin Finck struct Context
1038*c2c66affSColin Finck {
ContextContext1039*c2c66affSColin Finck Context(const char* ctx)
1040*c2c66affSColin Finck : _ctx(ctx)
1041*c2c66affSColin Finck {
1042*c2c66affSColin Finck _last = s_current;
1043*c2c66affSColin Finck s_current = this;
1044*c2c66affSColin Finck }
1045*c2c66affSColin Finck
ContextContext1046*c2c66affSColin Finck Context(const char* ctx, LPCSTR obj)
1047*c2c66affSColin Finck : _ctx(ctx),
1048*c2c66affSColin Finck _obj(obj)
1049*c2c66affSColin Finck {
1050*c2c66affSColin Finck _last = s_current;
1051*c2c66affSColin Finck s_current = this;
1052*c2c66affSColin Finck }
1053*c2c66affSColin Finck
ContextContext1054*c2c66affSColin Finck Context(const char* ctx, LPCWSTR obj)
1055*c2c66affSColin Finck : _ctx(ctx),
1056*c2c66affSColin Finck _obj(obj)
1057*c2c66affSColin Finck {
1058*c2c66affSColin Finck _last = s_current;
1059*c2c66affSColin Finck s_current = this;
1060*c2c66affSColin Finck }
1061*c2c66affSColin Finck
ContextContext1062*c2c66affSColin Finck Context(const Context& other)
1063*c2c66affSColin Finck : _ctx(other._ctx),
1064*c2c66affSColin Finck _obj(other._obj)
1065*c2c66affSColin Finck {
1066*c2c66affSColin Finck _last = NULL;
1067*c2c66affSColin Finck }
1068*c2c66affSColin Finck
~ContextContext1069*c2c66affSColin Finck ~Context()
1070*c2c66affSColin Finck {
1071*c2c66affSColin Finck if (_last) {
1072*c2c66affSColin Finck s_current = _last;
1073*c2c66affSColin Finck _last = NULL;
1074*c2c66affSColin Finck }
1075*c2c66affSColin Finck }
1076*c2c66affSColin Finck
1077*c2c66affSColin Finck String toString() const;
1078*c2c66affSColin Finck String getStackTrace() const;
1079*c2c66affSColin Finck
1080*c2c66affSColin Finck const char* _ctx;
1081*c2c66affSColin Finck String _obj;
1082*c2c66affSColin Finck
currentContext1083*c2c66affSColin Finck static Context& current() {return *s_current;}
1084*c2c66affSColin Finck
1085*c2c66affSColin Finck protected:
1086*c2c66affSColin Finck Context* _last;
1087*c2c66affSColin Finck
1088*c2c66affSColin Finck static Context* s_current; ///@todo use TLS
1089*c2c66affSColin Finck static Context s_main;
1090*c2c66affSColin Finck };
1091*c2c66affSColin Finck
1092*c2c66affSColin Finck #define CONTEXT_OBJ __ctx__._obj
1093*c2c66affSColin Finck #define CONTEXT(c) Context __ctx__(c)
1094*c2c66affSColin Finck #define CURRENT_CONTEXT Context::current()
1095*c2c66affSColin Finck #define OBJ_CONTEXT(c, o) Context __ctx__(c, o)
1096*c2c66affSColin Finck
1097*c2c66affSColin Finck
1098*c2c66affSColin Finck extern bool SplitFileSysURL(LPCTSTR url, String& dir_out, String& fname_out);
1099*c2c66affSColin Finck
1100*c2c66affSColin Finck
1101*c2c66affSColin Finck #endif // __cplusplus
1102