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