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