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