lean version comments
[reactos.git] / reactos / subsys / system / explorer / utility / utility.h
1 /*
2 * Copyright 2003, 2004 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, lean version
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
47 #include <malloc.h> // for alloca()
48 #include <assert.h>
49 #include <stdlib.h> // for _MAX_DIR, ...
50 #include <stdio.h> // for sprintf()
51 #include <time.h>
52
53 #ifndef _MAX_PATH
54 #define _MAX_DRIVE 3
55 #define _MAX_FNAME 256
56 #define _MAX_DIR _MAX_FNAME
57 #define _MAX_EXT _MAX_FNAME
58 #define _MAX_PATH 260
59 #endif
60
61
62 #ifdef __cplusplus
63 extern "C" {
64 #endif
65
66
67 #define for if (0) {} else for
68
69 #define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
70
71
72 #define BUFFER_LEN 1024
73
74
75 extern void _log_(LPCTSTR txt);
76
77 #define LOG(txt) _log_(txt)
78
79
80 #ifdef _MSC_VER
81 #define LONGLONGARG TEXT("I64")
82 #else
83 #define LONGLONGARG TEXT("L")
84 #endif
85
86
87 #ifndef _tcsrchr
88 #ifdef UNICODE
89 #define _tcsrchr wcsrchr
90 #else
91 #define _tcsrchr strrchr
92 #endif
93 #endif
94
95 #ifndef _stprintf
96 #ifdef UNICODE
97 #define _stprintf wcsprintf
98 #else
99 #define _stprintf sprintf
100 #endif
101 #endif
102
103 #define U2A(s, d, l) WideCharToMultiByte(CP_ACP, 0, s, -1, d, l, NULL, NULL)
104 #define U2nA(s, d, l) WideCharToMultiByte(CP_ACP, 0, s, l, d, l, NULL, NULL)
105 #define A2U(s, d, l) MultiByteToWideChar(CP_ACP, 0, s, -1, d, l)
106 #define A2nU(s, d, l) MultiByteToWideChar(CP_ACP, 0, s, l, d, l)
107
108
109 #ifndef FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
110 #define FILE_ATTRIBUTE_ENCRYPTED 0x00000040
111 #define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
112 #define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
113 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
114 #endif
115
116
117 #define SetDlgCtrlID(hwnd, id) SetWindowLong(hwnd, GWL_ID, id)
118 #define SetWindowStyle(hwnd, val) (DWORD)SetWindowLong(hwnd, GWL_STYLE, val)
119 #define SetWindowExStyle(h, val) (DWORD)SetWindowLong(hwnd, GWL_EXSTYLE, val)
120 #define Window_SetIcon(hwnd, type, hicon) (HICON)SendMessage(hwnd, WM_SETICON, type, (LPARAM)(hicon))
121
122
123 // center window in respect to its parent window
124 extern void CenterWindow(HWND hwnd);
125
126 // move window into visibility
127 extern void MoveVisible(HWND hwnd);
128
129 // display error message
130 extern void display_error(HWND hwnd, DWORD error);
131
132 // convert time_t to WIN32 FILETIME
133 extern BOOL time_to_filetime(const time_t* t, FILETIME* ftime);
134
135 // search for windows of a specific classname
136 extern int find_window_class(LPCTSTR classname);
137
138 // launch a program or document file
139 extern BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow);
140 #ifdef UNICODE
141 extern BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow);
142 #else
143 #define launch_fileA launch_file
144 #endif
145
146 // call an DLL export like rundll32
147 BOOL RunDLL(HWND hwnd, LPCTSTR dllname, LPCSTR procname, LPCTSTR cmdline, UINT nCmdShow);
148
149 // create a directory with all missing parent directories
150 BOOL RecursiveCreateDirectory(LPCTSTR path_in);
151
152
153 #ifdef __cplusplus
154 } // extern "C"
155 #endif
156
157
158 #ifdef __cplusplus
159
160 #ifdef _MSC_VER
161 #pragma warning(disable: 4786) // disable warnings about too long debug information symbols
162 #endif
163
164 // STL headers for strings and streams
165 #include <string>
166 #include <iostream>
167 using namespace std;
168
169 // containers
170 #include <map>
171 #include <set>
172 #include <list>
173 #include <vector>
174
175
176 #if _MSC_VER>=1300 // VS.Net
177 #define _NO_COMUTIL //@@
178 #endif
179
180 #if defined(_MSC_VER) && !defined(_NO_COMUTIL)
181
182 // COM utility headers
183 #include <comdef.h>
184 using namespace _com_util;
185
186 #endif // _MSC_VER && !_NO_COMUTIL
187
188
189 /// initialization of windows common controls
190 struct CommonControlInit
191 {
192 CommonControlInit(DWORD flags=ICC_LISTVIEW_CLASSES|ICC_TREEVIEW_CLASSES|ICC_BAR_CLASSES|ICC_PROGRESS_CLASS|ICC_COOL_CLASSES)
193 {
194 INITCOMMONCONTROLSEX icc = {sizeof(INITCOMMONCONTROLSEX), flags};
195
196 InitCommonControlsEx(&icc);
197 }
198 };
199
200
201 /// wait cursor
202
203 struct WaitCursor ///@todo integrate with WM_SETCURSOR to enable multithreaded background tasks as program launching
204 {
205 WaitCursor()
206 {
207 _old_cursor = SetCursor(LoadCursor(0, IDC_WAIT));
208 }
209
210 ~WaitCursor()
211 {
212 SetCursor(_old_cursor);
213 }
214
215 protected:
216 HCURSOR _old_cursor;
217 };
218
219
220 /// base of all structures storing a window handle
221 struct WindowHandle
222 {
223 WindowHandle(HWND hwnd=0)
224 : _hwnd(hwnd) {}
225
226 operator HWND() const {return _hwnd;}
227 HWND* operator&() {return &_hwnd;}
228
229 protected:
230 HWND _hwnd;
231 };
232
233
234 /// locally hide a window
235 struct HiddenWindow : public WindowHandle
236 {
237 HiddenWindow(HWND hwnd)
238 : WindowHandle(hwnd)
239 {
240 SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW|SWP_NOREDRAW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
241 }
242
243 ~HiddenWindow()
244 {
245 SetWindowPos(_hwnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
246 }
247 };
248
249
250 /// critical section wrapper
251
252 struct CritSect : public CRITICAL_SECTION
253 {
254 CritSect()
255 {
256 InitializeCriticalSection(this);
257 }
258
259 ~CritSect()
260 {
261 DeleteCriticalSection(this);
262 }
263 };
264
265
266 /// Lock protects a code section utilizing a critical section
267
268 struct Lock
269 {
270 Lock(CritSect& crit_sect)
271 : _crit_sect(crit_sect)
272 {
273 EnterCriticalSection(&crit_sect);
274 }
275
276 ~Lock()
277 {
278 LeaveCriticalSection(&_crit_sect);
279 }
280
281 protected:
282 CritSect& _crit_sect;
283 };
284
285
286 /// Thread base class
287
288 struct Thread
289 {
290 Thread()
291 : _alive(false)
292 {
293 _hThread = INVALID_HANDLE_VALUE;
294 }
295
296 virtual ~Thread()
297 {
298 Stop();
299
300 CloseHandle(_hThread);
301 }
302
303 void Start()
304 {
305 if (!_alive) {
306 _alive = true;
307 _hThread = CreateThread(NULL, 0, ThreadProc, this, 0, NULL);
308 }
309 }
310
311 void Stop()
312 {
313 if (_alive) {
314 {
315 Lock lock(_crit_sect);
316 _alive = false;
317 }
318
319 // wait for finishing
320 WaitForSingleObject(_hThread, INFINITE);
321 }
322 }
323
324 virtual int Run() = 0;
325
326 bool is_alive() const {return _alive;}
327
328 CritSect _crit_sect;
329
330 protected:
331 static DWORD WINAPI ThreadProc(void* para);
332
333 HANDLE _hThread;
334 bool _alive;
335 };
336
337
338 // window utilities
339
340 /// ClientRect retreives the client area rectangle of a window.
341 struct ClientRect : public RECT
342 {
343 ClientRect(HWND hwnd)
344 {
345 GetClientRect(hwnd, this);
346 }
347
348 operator LPRECT() {return this;}
349
350 POINT& pos() {return *(LPPOINT)this;}
351 };
352
353 /// ClientRect retreives the window rectangle of a window.
354 struct WindowRect : public RECT
355 {
356 WindowRect(HWND hwnd)
357 {
358 GetWindowRect(hwnd, this);
359 }
360
361 operator LPRECT() {return this;}
362
363 POINT& pos() {return *(LPPOINT)this;}
364 };
365
366 /// PointL encapsulates the POINT structure into a C++ object.
367 struct Point : public POINT
368 {
369 Point(LONG x_, LONG y_)
370 {
371 x = x_;
372 y = y_;
373 }
374
375 // constructor for being used in processing WM_MOUSEMOVE, WM_LBUTTONDOWN, ... messages
376 Point(LPARAM lparam)
377 {
378 x = GET_X_LPARAM(lparam);
379 y = GET_Y_LPARAM(lparam);
380 }
381
382 operator LPPOINT() {return this;}
383 };
384
385
386 /// transform coordinates in a RECT from client to screen coordiantes
387 inline void ClientToScreen(HWND hwnd, RECT* prect)
388 {::ClientToScreen(hwnd,(LPPOINT)&prect->left); ::ClientToScreen(hwnd,(LPPOINT)&prect->right);}
389
390 /// transform coordinates in a RECT from screen to client coordiantes
391 inline void ScreenToClient(HWND hwnd, RECT* prect)
392 {::ScreenToClient(hwnd,(LPPOINT)&prect->left); ::ScreenToClient(hwnd,(LPPOINT)&prect->right);}
393
394
395 // drawing utilities
396
397 /// PaintCanvas is a encapsulation of device contexts managed by BeginPaint()/EndPaint().
398 struct PaintCanvas : public PAINTSTRUCT
399 {
400 PaintCanvas(HWND hwnd)
401 : _hwnd(hwnd)
402 {
403 BeginPaint(hwnd, this);
404 }
405
406 ~PaintCanvas()
407 {
408 EndPaint(_hwnd, this);
409 }
410
411 operator HDC() const {return hdc;}
412
413 protected:
414 HWND _hwnd;
415 };
416
417 /// Canvas is a encapsulation of device contexts.
418 struct Canvas
419 {
420 Canvas(HDC hdc) : _hdc(hdc) {}
421
422 operator HDC() {return _hdc;}
423
424 protected:
425 HDC _hdc;
426 };
427
428 /// WindowCanvas is a encapsulation of client area device contexts.
429 struct WindowCanvas : public Canvas
430 {
431 WindowCanvas(HWND hwnd)
432 : Canvas(GetDC(hwnd)), _hwnd(hwnd) {}
433
434 ~WindowCanvas() {ReleaseDC(_hwnd, _hdc);}
435
436 protected:
437 HWND _hwnd;
438 };
439
440
441 // double buffering classes
442
443 /// Memory Canvas creates and destroys memory devoce contexts.
444 struct MemCanvas : public Canvas
445 {
446 MemCanvas(HDC hdc=0)
447 : Canvas(CreateCompatibleDC(hdc)) {assert(_hdc);}
448
449 ~MemCanvas() {DeleteDC(_hdc);}
450 };
451
452 /// SelectedBitmap is used to localy select bitmaps into device contexts.
453 struct SelectedBitmap
454 {
455 SelectedBitmap(HDC hdc, HBITMAP hbmp)
456 : _hdc(hdc), _old_hbmp(SelectBitmap(hdc, hbmp)) {}
457
458 ~SelectedBitmap() {DeleteObject(SelectBitmap(_hdc, _old_hbmp));}
459
460 protected:
461 HDC _hdc;
462 HBITMAP _old_hbmp;
463 };
464
465 /// BufferCanvas manages offscreen bitmaps selected into memory device contexts.
466 struct BufferCanvas : public MemCanvas
467 {
468 BufferCanvas(HDC hdc, int x, int y, int w, int h)
469 : MemCanvas(hdc), _hdctarg(hdc),
470 _x(x), _y(y), _w(w), _h(h),
471 _bmp(_hdc, CreateCompatibleBitmap(hdc, w, h)) {}
472
473 BufferCanvas(HDC hdc, const RECT& rect)
474 : MemCanvas(hdc), _hdctarg(hdc),
475 _x(rect.left), _y(rect.top), _w(rect.right-rect.left), _h(rect.bottom-rect.top),
476 _bmp(_hdc, CreateCompatibleBitmap(hdc, _w, _h)) {}
477
478 protected:
479 HDC _hdctarg;
480 int _x, _y, _w, _h;
481 SelectedBitmap _bmp;
482 };
483
484 /// BufferedCanvas enables double buffering for a device context.
485 struct BufferedCanvas : public BufferCanvas
486 {
487 BufferedCanvas(HDC hdc, int x, int y, int w, int h, DWORD mode=SRCCOPY)
488 : BufferCanvas(hdc, x, y, w, h), _mode(mode) {}
489
490 BufferedCanvas(HDC hdc, const RECT& rect, DWORD mode=SRCCOPY)
491 : BufferCanvas(hdc, rect), _mode(mode) {}
492
493 ~BufferedCanvas() {BitBlt(_hdctarg, _x, _y, _w, _h, _hdc, 0, 0, _mode);}
494
495 DWORD _mode;
496 };
497
498 /// BufferedPaintCanvas extends PaintCanvas for double buffering.
499 struct BufferedPaintCanvas : public PaintCanvas, public BufferedCanvas
500 {
501 BufferedPaintCanvas(HWND hwnd)
502 : PaintCanvas(hwnd),
503 BufferedCanvas(PAINTSTRUCT::hdc, 0, 0, rcPaint.right, rcPaint.bottom)
504 {
505 }
506
507 operator HDC() {return BufferedCanvas::_hdc;}
508 };
509
510
511 /// TextColor locally selects a text color for drawing.
512 struct TextColor
513 {
514 TextColor(HDC hdc, COLORREF color)
515 : _hdc(hdc), _old_color(SetTextColor(hdc, color)) {}
516
517 ~TextColor() {SetTextColor(_hdc, _old_color);}
518
519 protected:
520 HDC _hdc;
521 COLORREF _old_color;
522 };
523
524 /// BkMode locally sets the background mode for drawing.
525 struct BkMode
526 {
527 BkMode(HDC hdc, int bkmode)
528 : _hdc(hdc), _old_bkmode(SetBkMode(hdc, bkmode)) {}
529
530 ~BkMode() {SetBkMode(_hdc, _old_bkmode);}
531
532 protected:
533 HDC _hdc;
534 COLORREF _old_bkmode;
535 };
536
537 /// FontSelection locally selects a font for drawing.
538 struct FontSelection
539 {
540 FontSelection(HDC hdc, HFONT hFont)
541 : _hdc(hdc), _old_hFont(SelectFont(hdc, hFont)) {}
542
543 ~FontSelection() {SelectFont(_hdc, _old_hFont);}
544
545 protected:
546 HDC _hdc;
547 HFONT _old_hFont;
548 };
549
550 /// BitmapSelection locally selects a bitmap into a device context.
551 struct BitmapSelection
552 {
553 BitmapSelection(HDC hdc, HBITMAP hBmp)
554 : _hdc(hdc), _old_hBmp(SelectBitmap(hdc, hBmp)) {}
555
556 ~BitmapSelection() {SelectBitmap(_hdc, _old_hBmp);}
557
558 protected:
559 HDC _hdc;
560 HBITMAP _old_hBmp;
561 };
562
563 /// BrushSelection locally selects a brush into a device context.
564 struct BrushSelection
565 {
566 BrushSelection(HDC hdc, HBRUSH hBrush)
567 : _hdc(hdc), _old_hBrush(SelectBrush(hdc, hBrush)) {}
568
569 ~BrushSelection() {SelectBrush(_hdc, _old_hBrush);}
570
571 protected:
572 HDC _hdc;
573 HBRUSH _old_hBrush;
574 };
575
576
577 /// Popup Menus
578 struct PopupMenu
579 {
580 PopupMenu()
581 : _hmenu(CreatePopupMenu())
582 {
583 }
584
585 PopupMenu(UINT nid);
586
587 operator HMENU() {return _hmenu;}
588
589 void Append(UINT id, LPCTSTR str, UINT flags=MF_STRING)
590 {
591 AppendMenu(_hmenu, flags, id, str);
592 }
593
594 int TrackPopupMenu(HWND hwnd, const POINT& pt, UINT flags=TPM_LEFTBUTTON|TPM_RIGHTBUTTON, LPTPMPARAMS tpm=NULL) {
595 return TrackPopupMenuEx(_hmenu, flags, pt.x, pt.y, hwnd, tpm);
596 }
597
598 int PopupContextMenu(HWND hwnd, POINTS pos, UINT flags=TPM_LEFTBUTTON|TPM_RIGHTBUTTON) {
599 POINT pt; POINTSTOPOINT(pt, pos);
600 return TrackPopupMenuEx(_hmenu, flags, pt.x, pt.y, hwnd, NULL);
601 }
602
603 int TrackPopupMenu(HWND hwnd, POINTS pos, UINT flags=TPM_LEFTBUTTON|TPM_RIGHTBUTTON) {
604 POINT pt; POINTSTOPOINT(pt, pos);
605 ClientToScreen(hwnd, &pt);
606 return TrackPopupMenuEx(_hmenu, flags, pt.x, pt.y, hwnd, NULL);
607 }
608
609 int TrackPopupMenuAtCursor(HWND hwnd, UINT flags=TPM_LEFTBUTTON) {
610 POINT pt; GetCursorPos(&pt);
611 return TrackPopupMenuEx(_hmenu, flags, pt.x, pt.y, hwnd, NULL);
612 }
613
614 int TrackPopupMenuAtPos(HWND hwnd, DWORD pos, UINT flags=TPM_LEFTBUTTON) {
615 return TrackPopupMenuEx(_hmenu, flags, GET_X_LPARAM(pos), GET_Y_LPARAM(pos), hwnd, NULL);
616 }
617
618 protected:
619 HMENU _hmenu;
620 };
621
622
623 /// string class for convenience
624 struct String
625 #ifdef UNICODE
626 : public wstring
627 #else
628 : public string
629 #endif
630 {
631 #ifdef UNICODE
632 typedef wstring super;
633 #else
634 typedef string super;
635 #endif
636
637 String() {}
638 String(LPCTSTR s) {if (s) super::assign(s);}
639 String(LPCTSTR s, int l) : super(s, l) {}
640 String(const super& other) : super(other) {}
641 String(const String& other) : super(other) {}
642
643 #ifdef UNICODE
644 String(LPCSTR s) {assign(s);}
645 String(LPCSTR s, int l) {assign(s, l);}
646 String(const string& other) {assign(other.c_str());}
647 String& operator=(LPCSTR s) {assign(s); return *this;}
648 void assign(LPCSTR s) {if (s) {TCHAR b[BUFFER_LEN]; super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, -1, b, BUFFER_LEN));} else erase();}
649 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();}
650 #else
651 String(LPCWSTR s) {assign(s);}
652 String(LPCWSTR s, int l) {assign(s, l);}
653 String(const wstring& other) {assign(other.c_str());}
654 String& operator=(LPCWSTR s) {assign(s); return *this;}
655 void assign(LPCWSTR s) {if (s) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, -1, b, BUFFER_LEN, 0, 0));} else erase();}
656 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();}
657 #endif
658
659 String& operator=(LPCTSTR s) {if (s) super::assign(s); else erase(); return *this;}
660 String& operator=(const super& s) {super::assign(s); return *this;}
661 void assign(LPCTSTR s) {super::assign(s);}
662 void assign(LPCTSTR s, int l) {super::assign(s, l);}
663
664 operator LPCTSTR() const {return c_str();}
665
666 String& printf(LPCTSTR fmt, ...)
667 {
668 va_list l;
669 TCHAR b[BUFFER_LEN];
670
671 va_start(l, fmt);
672 super::assign(b, _vstprintf(b, fmt, l));
673 va_end(l);
674
675 return *this;
676 }
677
678 String& vprintf(LPCTSTR fmt, va_list l)
679 {
680 TCHAR b[BUFFER_LEN];
681
682 super::assign(b, _vstprintf(b, fmt, l));
683
684 return *this;
685 }
686
687 String& appendf(LPCTSTR fmt, ...)
688 {
689 va_list l;
690 TCHAR b[BUFFER_LEN];
691
692 va_start(l, fmt);
693 super::append(b, _vstprintf(b, fmt, l));
694 va_end(l);
695
696 return *this;
697 }
698
699 String& vappendf(LPCTSTR fmt, va_list l)
700 {
701 TCHAR b[BUFFER_LEN];
702
703 super::append(b, _vstprintf(b, fmt, l));
704
705 return *this;
706 }
707 };
708
709
710 struct FmtString : public String
711 {
712 FmtString(LPCTSTR fmt, ...)
713 {
714 va_list l;
715
716 va_start(l, fmt);
717 vprintf(fmt, l);
718 va_end(l);
719 }
720 };
721
722
723 #ifdef UNICODE
724
725 struct ANS
726 {
727 ANS(LPCWSTR s)
728 {
729 int l = wcslen(s) + 1;
730 _str = (LPSTR) malloc(2*l);
731
732 if (WideCharToMultiByte(CP_ACP, 0, s, -1, _str, 2*l, 0, 0) <= 0)
733 *_str = '\0';
734 }
735
736 ~ANS()
737 {
738 free(_str);
739 }
740
741 operator LPCSTR() {return _str;}
742
743 protected:
744 LPSTR _str;
745 };
746
747 #define UNC(x) ((LPCWSTR)(x))
748
749 #else
750
751 #define ANS(x) ((LPCSTR)(x))
752
753 struct UNC
754 {
755 UNC(LPCSTR s)
756 {
757 int l = strlen(s) + 1;
758 _str = (LPWSTR) malloc(2*l);
759
760 if (MultiByteToWideChar(CP_ACP, 0, s, -1, _str, l) <= 0)
761 *_str = '\0';
762 }
763
764 ~UNC()
765 {
766 free(_str);
767 }
768
769 operator LPCWSTR() {return _str;}
770
771 protected:
772 LPWSTR _str;
773 };
774
775 #endif
776
777
778 /// link dynamicly to functions by using GetModuleHandle() and GetProcAddress()
779 template<typename FCT> struct DynamicFct
780 {
781 DynamicFct(LPCTSTR moduleName, UINT ordinal)
782 {
783 HMODULE hModule = GetModuleHandle(moduleName);
784
785 _fct = (FCT) GetProcAddress(hModule, (LPCSTR)ordinal);
786 }
787
788 DynamicFct(LPCTSTR moduleName, LPCSTR name)
789 {
790 HMODULE hModule = GetModuleHandle(moduleName);
791
792 _fct = (FCT) GetProcAddress(hModule, name);
793 }
794
795 FCT operator*() const {return _fct;}
796 operator bool() const {return _fct? true: false;}
797
798 protected:
799 FCT _fct;
800 };
801
802
803 /// link dynamicly to functions by using LoadLibrary() and GetProcAddress()
804 template<typename FCT> struct DynamicLoadLibFct
805 {
806 DynamicLoadLibFct(LPCTSTR moduleName, UINT ordinal)
807 {
808 _hModule = LoadLibrary(moduleName);
809
810 _fct = (FCT) GetProcAddress(_hModule, (LPCSTR)ordinal);
811 }
812
813 DynamicLoadLibFct(LPCTSTR moduleName, LPCSTR name)
814 {
815 _hModule = LoadLibrary(moduleName);
816
817 _fct = (FCT) GetProcAddress(_hModule, name);
818 }
819
820 ~DynamicLoadLibFct()
821 {
822 FreeLibrary(_hModule);
823 }
824
825 FCT operator*() const {return _fct;}
826 operator bool() const {return _fct? true: false;}
827
828 protected:
829 HMODULE _hModule;
830 FCT _fct;
831 };
832
833
834 #ifndef _NO_CONTEXT
835
836 struct Context
837 {
838 Context(const char* ctx)
839 : _ctx(ctx)
840 {
841 _last = s_current;
842 s_current = this;
843 }
844
845 Context(const char* ctx, LPCSTR obj)
846 : _ctx(ctx),
847 _obj(obj)
848 {
849 _last = s_current;
850 s_current = this;
851 }
852
853 Context(const char* ctx, LPCWSTR obj)
854 : _ctx(ctx),
855 _obj(obj)
856 {
857 _last = s_current;
858 s_current = this;
859 }
860
861 Context(const Context& other)
862 : _ctx(other._ctx),
863 _obj(other._obj)
864 {
865 _last = NULL;
866 }
867
868 ~Context()
869 {
870 if (_last) {
871 s_current = _last;
872 _last = NULL;
873 }
874 }
875
876 String toString() const;
877 String getStackTrace() const;
878
879 const char* _ctx;
880 String _obj;
881
882 static Context& current() {return *s_current;}
883
884 protected:
885 Context* _last;
886
887 static Context* s_current; ///@todo use TLS
888 static Context s_main;
889 };
890
891 #define CONTEXT_OBJ __ctx__._obj
892 #define CONTEXT(c) Context __ctx__(c)
893 #define CURRENT_CONTEXT Context::current()
894 #define OBJ_CONTEXT(c, o) Context __ctx__(c, o);
895
896 #else
897
898 #define CONTEXT(c)
899 #define OBJ_CONTEXT(c, o) ;
900
901 #endif
902
903
904 #endif // __cplusplus