add doxygen @todo tags to create a TODO list
[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
60 #ifdef _MSC_VER
61 #pragma warning(disable: 4786) // disable warnings about too long debug information symbols
62 #endif
63
64 // STL headers for strings and streams
65 #include <string>
66 #include <iostream>
67 using namespace std;
68
69 #if _MSC_VER>=1300 // VS.Net
70 #define _NO_COMUTIL //@@
71 #endif
72
73 #if defined(_MSC_VER) && !defined(_NO_COMUTIL)
74
75 // COM utility headers
76 #include <comdef.h>
77 using namespace _com_util;
78
79 #endif // _MSC_VER && !_NO_COMUTIL
80
81
82 #define for if (0) {} else for
83
84
85 #define BUFFER_LEN 1024
86
87
88 struct CommonControlInit
89 {
90 CommonControlInit(DWORD flags=ICC_LISTVIEW_CLASSES|ICC_TREEVIEW_CLASSES|ICC_BAR_CLASSES|ICC_PROGRESS_CLASS|ICC_COOL_CLASSES)
91 {
92 INITCOMMONCONTROLSEX icc = {sizeof(INITCOMMONCONTROLSEX), flags};
93
94 InitCommonControlsEx(&icc);
95 }
96 };
97
98
99 /// wait cursor
100
101 struct WaitCursor ///@todo integrate with WM_SETCURSOR to enable multithreaded background tasks as program launching
102 {
103 WaitCursor()
104 {
105 _old_cursor = SetCursor(LoadCursor(0, IDC_WAIT));
106 }
107
108 ~WaitCursor()
109 {
110 SetCursor(_old_cursor);
111 }
112
113 protected:
114 HCURSOR _old_cursor;
115 };
116
117
118 struct WindowHandle
119 {
120 WindowHandle(HWND hwnd=0)
121 : _hwnd(hwnd) {}
122
123 operator HWND() const {return _hwnd;}
124 HWND* operator&() {return &_hwnd;}
125
126 protected:
127 HWND _hwnd;
128 };
129
130
131 struct HiddenWindow : public WindowHandle
132 {
133 HiddenWindow(HWND hwnd)
134 : WindowHandle(hwnd)
135 {
136 SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW|SWP_NOREDRAW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
137 }
138
139 ~HiddenWindow()
140 {
141 SetWindowPos(_hwnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
142 }
143 };
144
145
146 /// critical section wrapper
147
148 struct CritSect : public CRITICAL_SECTION
149 {
150 CritSect()
151 {
152 InitializeCriticalSection(this);
153 }
154
155 ~CritSect()
156 {
157 DeleteCriticalSection(this);
158 }
159 };
160
161
162 /// Lock protects a code section utilizing a critical section
163
164 struct Lock
165 {
166 Lock(CritSect& crit_sect)
167 : _crit_sect(crit_sect)
168 {
169 EnterCriticalSection(&crit_sect);
170 }
171
172 ~Lock()
173 {
174 LeaveCriticalSection(&_crit_sect);
175 }
176
177 protected:
178 CritSect& _crit_sect;
179 };
180
181
182 /// Thread base class
183
184 struct Thread
185 {
186 Thread()
187 : _alive(false)
188 {
189 _hThread = INVALID_HANDLE_VALUE;
190 }
191
192 virtual ~Thread()
193 {
194 Stop();
195
196 CloseHandle(_hThread);
197 }
198
199 void Start()
200 {
201 if (!_alive) {
202 _alive = true;
203 _hThread = CreateThread(NULL, 0, ThreadProc, this, 0, NULL);
204 }
205 }
206
207 void Stop()
208 {
209 if (_alive) {
210 {
211 Lock lock(_crit_sect);
212 _alive = false;
213 }
214
215 // wait for finishing
216 WaitForSingleObject(_hThread, INFINITE);
217 }
218 }
219
220 virtual int Run() = 0;
221
222 bool is_alive() const {return _alive;}
223
224 CritSect _crit_sect;
225
226 protected:
227 static DWORD WINAPI ThreadProc(void* para);
228
229 HANDLE _hThread;
230 bool _alive;
231 };
232
233
234 // window utilities
235
236 struct ClientRect : public RECT
237 {
238 ClientRect(HWND hwnd)
239 {
240 GetClientRect(hwnd, this);
241 }
242
243 operator LPRECT() {return this;}
244
245 POINT& pos() {return *(LPPOINT)this;}
246 };
247
248 struct WindowRect : public RECT
249 {
250 WindowRect(HWND hwnd)
251 {
252 GetWindowRect(hwnd, this);
253 }
254
255 operator LPRECT() {return this;}
256
257 POINT& pos() {return *(LPPOINT)this;}
258 };
259
260 struct Point : public POINT
261 {
262 Point(LONG x_, LONG y_)
263 {
264 x = x_;
265 y = y_;
266 }
267
268 // constructor for being used in processing WM_MOUSEMOVE, WM_LBUTTONDOWN, ... messages
269 Point(LPARAM lparam)
270 {
271 x = GET_X_LPARAM(lparam);
272 y = GET_Y_LPARAM(lparam);
273 }
274
275 operator LPPOINT() {return this;}
276 };
277
278
279 inline void ClientToScreen(HWND hwnd, RECT* prect)
280 {::ClientToScreen(hwnd,(LPPOINT)&prect->left); ::ClientToScreen(hwnd,(LPPOINT)&prect->right);}
281
282 inline void ScreenToClient(HWND hwnd, RECT* prect)
283 {::ScreenToClient(hwnd,(LPPOINT)&prect->left); ::ScreenToClient(hwnd,(LPPOINT)&prect->right);}
284
285
286 struct FullScreenParameters
287 {
288 FullScreenParameters()
289 : _mode(FALSE)
290 {
291 }
292
293 BOOL _mode;
294 RECT _orgPos;
295 BOOL _wasZoomed;
296 };
297
298
299 // drawing utilities
300
301 struct PaintCanvas : public PAINTSTRUCT
302 {
303 PaintCanvas(HWND hwnd)
304 : _hwnd(hwnd)
305 {
306 BeginPaint(hwnd, this);
307 }
308
309 ~PaintCanvas()
310 {
311 EndPaint(_hwnd, this);
312 }
313
314 operator HDC() const {return hdc;}
315
316 protected:
317 HWND _hwnd;
318 };
319
320 struct Canvas
321 {
322 Canvas(HDC hdc) : _hdc(hdc) {}
323
324 operator HDC() {return _hdc;}
325
326 protected:
327 HDC _hdc;
328 };
329
330 struct WindowCanvas : public Canvas
331 {
332 WindowCanvas(HWND hwnd)
333 : Canvas(GetDC(hwnd)), _hwnd(hwnd) {}
334
335 ~WindowCanvas() {ReleaseDC(_hwnd, _hdc);}
336
337 protected:
338 HWND _hwnd;
339 };
340
341
342 // double buffering classes
343
344 struct MemCanvas : public Canvas
345 {
346 MemCanvas(HDC hdc=0)
347 : Canvas(CreateCompatibleDC(hdc)) {assert(_hdc);}
348
349 ~MemCanvas() {DeleteDC(_hdc);}
350 };
351
352 struct SelectedBitmap
353 {
354 SelectedBitmap(HDC hdc, HBITMAP hbmp)
355 : _hdc(hdc), _old_hbmp(SelectBitmap(hdc, hbmp)) {}
356
357 ~SelectedBitmap() {DeleteObject(SelectBitmap(_hdc, _old_hbmp));}
358
359 protected:
360 HDC _hdc;
361 HBITMAP _old_hbmp;
362 };
363
364 struct BufferCanvas : public MemCanvas
365 {
366 BufferCanvas(HDC hdc, int x, int y, int w, int h)
367 : MemCanvas(hdc), _hdctarg(hdc),
368 _x(x), _y(y), _w(w), _h(h),
369 _bmp(_hdc, CreateCompatibleBitmap(hdc, w, h)) {}
370
371 BufferCanvas(HDC hdc, const RECT& rect)
372 : MemCanvas(hdc), _hdctarg(hdc),
373 _x(rect.left), _y(rect.top), _w(rect.right-rect.left), _h(rect.bottom-rect.top),
374 _bmp(_hdc, CreateCompatibleBitmap(hdc, _w, _h)) {}
375
376 protected:
377 HDC _hdctarg;
378 int _x, _y, _w, _h;
379 SelectedBitmap _bmp;
380 };
381
382 struct BufferedCanvas : public BufferCanvas
383 {
384 BufferedCanvas(HDC hdc, int x, int y, int w, int h, DWORD mode=SRCCOPY)
385 : BufferCanvas(hdc, x, y, w, h), _mode(mode) {}
386
387 BufferedCanvas(HDC hdc, const RECT& rect, DWORD mode=SRCCOPY)
388 : BufferCanvas(hdc, rect), _mode(mode) {}
389
390 ~BufferedCanvas() {BitBlt(_hdctarg, _x, _y, _w, _h, _hdc, 0, 0, _mode);}
391
392 DWORD _mode;
393 };
394
395 struct BufferedPaintCanvas : public PaintCanvas, public BufferedCanvas
396 {
397 BufferedPaintCanvas(HWND hwnd)
398 : PaintCanvas(hwnd),
399 BufferedCanvas(PAINTSTRUCT::hdc, 0, 0, rcPaint.right, rcPaint.bottom)
400 {
401 }
402
403 operator HDC() {return BufferedCanvas::_hdc;}
404 };
405
406
407 struct TextColor
408 {
409 TextColor(HDC hdc, COLORREF color)
410 : _hdc(hdc), _old_color(SetTextColor(hdc, color)) {}
411
412 ~TextColor() {SetTextColor(_hdc, _old_color);}
413
414 protected:
415 HDC _hdc;
416 COLORREF _old_color;
417 };
418
419 struct BkMode
420 {
421 BkMode(HDC hdc, int bkmode)
422 : _hdc(hdc), _old_bkmode(SetBkMode(hdc, bkmode)) {}
423
424 ~BkMode() {SetBkMode(_hdc, _old_bkmode);}
425
426 protected:
427 HDC _hdc;
428 COLORREF _old_bkmode;
429 };
430
431 struct FontSelection
432 {
433 FontSelection(HDC hdc, HFONT hFont)
434 : _hdc(hdc), _old_hFont(SelectFont(hdc, hFont)) {}
435
436 ~FontSelection() {SelectFont(_hdc, _old_hFont);}
437
438 protected:
439 HDC _hdc;
440 HFONT _old_hFont;
441 };
442
443 struct BitmapSelection
444 {
445 BitmapSelection(HDC hdc, HBITMAP hBmp)
446 : _hdc(hdc), _old_hBmp(SelectBitmap(hdc, hBmp)) {}
447
448 ~BitmapSelection() {SelectBitmap(_hdc, _old_hBmp);}
449
450 protected:
451 HDC _hdc;
452 HBITMAP _old_hBmp;
453 };
454
455
456 struct String
457 #ifdef UNICODE
458 : public wstring
459 #else
460 : public string
461 #endif
462 {
463 #ifdef UNICODE
464 typedef wstring super;
465 #else
466 typedef string super;
467 #endif
468
469 String() {}
470 String(LPCTSTR s) : super(s) {}
471 String(const super& other) : super(other) {}
472 String(const String& other) : super(other) {}
473
474 String& operator=(LPCTSTR s) {assign(s); return *this;}
475 String& operator=(const super& s) {assign(s); return *this;}
476
477 operator LPCTSTR() const {return c_str();}
478 };
479
480
481 /// link dynamicly to functions by using GetModuleHandle() and GetProcAddress()
482 template<typename FCT> struct DynamicFct
483 {
484 DynamicFct(LPCTSTR moduleName, UINT ordinal)
485 {
486 HMODULE hModule = GetModuleHandle(moduleName);
487
488 _fct = (FCT) GetProcAddress(hModule, (LPCSTR)ordinal);
489 }
490
491 DynamicFct(LPCTSTR moduleName, LPCSTR name)
492 {
493 HMODULE hModule = GetModuleHandle(moduleName);
494
495 _fct = (FCT) GetProcAddress(hModule, name);
496 }
497
498 FCT operator*() const {return _fct;}
499 operator bool() const {return _fct? true: false;}
500
501 protected:
502 FCT _fct;
503 };
504
505
506 /// link dynamicly to functions by using LoadLibrary() and GetProcAddress()
507 template<typename FCT> struct DynamicLoadLibFct
508 {
509 DynamicLoadLibFct(LPCTSTR moduleName, UINT ordinal)
510 {
511 _hModule = LoadLibrary(moduleName);
512
513 _fct = (FCT) GetProcAddress(_hModule, (LPCSTR)ordinal);
514 }
515
516 DynamicLoadLibFct(LPCTSTR moduleName, LPCSTR name)
517 {
518 _hModule = LoadLibrary(moduleName);
519
520 _fct = (FCT) GetProcAddress(_hModule, name);
521 }
522
523 ~DynamicLoadLibFct()
524 {
525 FreeLibrary(_hModule);
526 }
527
528 FCT operator*() const {return _fct;}
529 operator bool() const {return _fct? true: false;}
530
531 protected:
532 HMODULE _hModule;
533 FCT _fct;
534 };
535
536 #endif // __cplusplus
537
538
539 #ifdef __cplusplus
540 extern "C" {
541 #endif
542
543
544 #ifdef _MSC_VER
545 #define LONGLONGARG TEXT("I64")
546 #else
547 #define LONGLONGARG TEXT("L")
548 #endif
549
550
551 #ifndef _tcsrchr
552 #ifdef UNICODE
553 #define _tcsrchr wcsrchr
554 #else
555 #define _tcsrchr strrchr
556 #endif
557 #endif
558
559 #ifndef _stprintf
560 #ifdef UNICODE
561 #define _stprintf wcsprintf
562 #else
563 #define _stprintf sprintf
564 #endif
565 #endif
566
567
568 #ifdef __WINE__
569 #ifdef UNICODE
570 extern void _wsplitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext);
571 #else
572 extern void _splitpath(const CHAR* path, CHAR* drv, CHAR* dir, CHAR* name, CHAR* ext);
573 #endif
574 #endif
575
576 #ifndef FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
577 #define FILE_ATTRIBUTE_ENCRYPTED 0x00000040
578 #define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
579 #define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
580 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
581 #endif
582
583
584 #define SetDlgCtrlID(hwnd, id) SetWindowLong(hwnd, GWL_ID, id)
585 #define SetWindowStyle(hwnd, val) (DWORD)SetWindowLong(hwnd, GWL_STYLE, val)
586 #define SetWindowExStyle(h, val) (DWORD)SetWindowLong(hwnd, GWL_EXSTYLE, val)
587 #define Window_SetIcon(hwnd, type, hicon) (HICON)SendMessage(hwnd, WM_SETICON, type, (LPARAM)(hicon))
588
589
590
591 // center window in respect to its parent window
592 extern void CenterWindow(HWND hwnd);
593
594 // move window into visibility
595 extern void MoveVisible(HWND hwnd);
596
597 // display error message
598 extern void display_error(HWND hwnd, DWORD error);
599
600 // convert time_t to WIN32 FILETIME
601 extern BOOL time_to_filetime(const time_t* t, FILETIME* ftime);
602
603 // search for windows of a specific classname
604 extern int find_window_class(LPCTSTR classname);
605
606 // create a bitmap from an icon
607 extern HBITMAP create_bitmap_from_icon(HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd);
608
609 // launch a program or document file
610 extern BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow);
611 #ifdef UNICODE
612 extern BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow);
613 #else
614 #define launch_fileA launch_file
615 #endif
616
617 // call an DLL export like rundll32
618 BOOL RunDLL(HWND hwnd, LPCTSTR dllname, LPCSTR procname, LPCTSTR cmdline, UINT nCmdShow);
619
620
621 #ifdef __cplusplus
622 } // extern "C"
623 #endif
624