2 * Copyright 2003, 2004, 2005 Martin Fuchs
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 // Martin Fuchs, 23.07.2003
29 typedef set
<HWND
> WindowSet
;
33 Classes are declared using "struct", not "class" because the default
34 access mode is "public". This way we can list the member functions in a
35 natural order without explicitly specifying any access mode at the begin
37 First are public constructors and destructor, then public member functions.
38 After that we list protected member varibables and functions. If needed,
39 private implemenation varibales and functions are positioned at the end.
43 /// information structure for creation of a MDI child window
46 ChildWndInfo(HWND hmdiclient
)
47 : _hmdiclient(hmdiclient
) {}
54 Class Window is the base class for several C++ window wrapper classes.
55 Window objects are allocated from the heap. They are automatically freed
56 when the window gets destroyed.
58 struct Window
: public WindowHandle
64 typedef map
<HWND
,Window
*> WindowMap
;
66 typedef Window
* (*CREATORFUNC
)(HWND
);
67 typedef Window
* (*CREATORFUNC_INFO
)(HWND
, const void*);
69 static HWND
Create(CREATORFUNC creator
,
70 DWORD dwExStyle
, LPCTSTR lpClassName
, LPCTSTR lpWindowName
,
71 DWORD dwStyle
, int x
, int y
, int w
, int h
,
72 HWND hwndParent
=0, HMENU hMenu
=0/*, LPVOID lpParam=0*/);
74 static HWND
Create(CREATORFUNC_INFO creator
, const void* info
,
75 DWORD dwExStyle
, LPCTSTR lpClassName
, LPCTSTR lpWindowName
,
76 DWORD dwStyle
, int x
, int y
, int w
, int h
,
77 HWND hwndParent
=0, HMENU hMenu
=0/*, LPVOID lpParam=0*/);
79 static Window
* create_mdi_child(const ChildWndInfo
& info
, const MDICREATESTRUCT
& mcs
, CREATORFUNC_INFO creator
);
80 // static Window* create_property_sheet(struct PropertySheetDialog* ppsd, CREATORFUNC creator, const void* info);
82 static LRESULT CALLBACK
WindowWndProc(HWND hwnd
, UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
83 static INT_PTR CALLBACK
DialogProc(HWND hwnd
, UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
85 static Window
* get_window(HWND hwnd
);
87 template<typename CLASS
> static CLASS
* get_window(HWND hwnd
) {return static_cast<CLASS
*>(get_window(hwnd
));}
88 #define GET_WINDOW(CLASS, hwnd) Window::get_window<CLASS>(hwnd)
91 static void register_pretranslate(HWND hwnd
);
92 static void unregister_pretranslate(HWND hwnd
);
93 static BOOL
pretranslate_msg(LPMSG pmsg
);
95 static void register_dialog(HWND hwnd
);
96 static void unregister_dialog(HWND hwnd
);
97 static BOOL
dispatch_dialog_msg(LPMSG pmsg
);
99 static int MessageLoop();
102 LRESULT
SendParent(UINT nmsg
, WPARAM wparam
=0, LPARAM lparam
=0);
103 LRESULT
PostParent(UINT nmsg
, WPARAM wparam
=0, LPARAM lparam
=0);
105 static void CancelModes();
109 virtual LRESULT
Init(LPCREATESTRUCT pcs
); // WM_CREATE processing
110 virtual LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
111 virtual int Command(int id
, int code
); // WM_COMMAND processing
112 virtual int Notify(int id
, NMHDR
* pnmh
); // WM_NOTIFY processing
114 static Window
* create_controller(HWND hwnd
);
117 static WindowMap s_wnd_map
;
119 static const void* s_new_info
;
120 static CREATORFUNC s_window_creator
;
123 /// structure for managing critical sections as static class information in struct Window
124 struct StaticWindowData
{
125 CritSect _map_crit_sect
;
126 CritSect _create_crit_sect
;
129 static StaticWindowData
& GetStaticWindowData();
132 // MDI child creation
133 static HHOOK s_hcbtHook
;
134 static LRESULT CALLBACK
MDICBTHookProc(int code
, WPARAM wparam
, LPARAM lparam
);
135 static LRESULT CALLBACK
PropSheetCBTHookProc(int code
, WPARAM wparam
, LPARAM lparam
);
137 static WindowSet s_pretranslate_windows
;
138 static WindowSet s_dialogs
;
142 #define NFR_CURRENT NFR_UNICODE
144 #define NFR_CURRENT NFR_ANSI
149 template<typename CLASS
> struct GetWindowHelper
151 static CLASS
* get_window(HWND hwnd
) {
152 return static_cast<CLASS
*>(Window::get_window(hwnd
));
155 #define GET_WINDOW(CLASS, hwnd) GetWindowHelper<CLASS>::get_window(hwnd)
159 /// dynamic casting of Window pointers
160 template<typename CLASS
> struct TypeCheck
162 static CLASS
* dyn_cast(Window
* wnd
)
163 {return dynamic_cast<CLASS
*>(wnd
);}
166 #define WINDOW_DYNAMIC_CAST(CLASS, hwnd) \
167 TypeCheck<CLASS>::dyn_cast(Window::get_window(hwnd))
171 SubclassedWindow is used to wrap already existing window handles
172 into C++ Window objects. To construct a object, use the "new" operator
173 to put it in the heap. It is automatically freed, when the window
176 struct SubclassedWindow
: public Window
178 typedef Window super
;
180 SubclassedWindow(HWND
);
185 static LRESULT CALLBACK
SubclassedWndProc(HWND hwnd
, UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
187 virtual LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
188 virtual int Command(int id
, int code
);
189 virtual int Notify(int id
, NMHDR
* pnmh
);
193 /// template class used in macro WINDOW_CREATOR to define the creater functions for Window objects
194 template<typename WND_CLASS
> struct WindowCreator
196 static WND_CLASS
* window_creator(HWND hwnd
)
198 return new WND_CLASS(hwnd
);
202 #define WINDOW_CREATOR(WND_CLASS) \
203 ((Window::CREATORFUNC) WindowCreator<WND_CLASS>::window_creator)
206 /// template class used in macro WINDOW_CREATOR_INFO to the define creater functions for Window objects with additional creation information
207 template<typename WND_CLASS
, typename INFO_CLASS
> struct WindowCreatorInfo
209 static WND_CLASS
* window_creator(HWND hwnd
, const void* info
)
211 return new WND_CLASS(hwnd
, *static_cast<const INFO_CLASS
*>(info
));
215 #define WINDOW_CREATOR_INFO(WND_CLASS, INFO_CLASS) \
216 ((Window::CREATORFUNC_INFO) WindowCreatorInfo<WND_CLASS, INFO_CLASS>::window_creator)
220 WindowClass is a neat wrapper for RegisterClassEx().
221 Just construct a WindowClass object, override the attributes you want
222 to change, then call Register() or simply request the ATOM value to
223 register the window class. You don't have to worry calling Register()
224 more than once. It checks if, the class has already been registered.
226 struct WindowClass
: public WNDCLASSEX
228 WindowClass(LPCTSTR classname
, UINT style
=0, WNDPROC wndproc
=Window::WindowWndProc
);
233 _atomClass
= RegisterClassEx(this);
238 operator ATOM() {return Register();}
240 // return LPCTSTR for the CreateWindowEx() parameter
241 operator LPCTSTR() {return (LPCTSTR
)(int)Register();}
247 /// window class with gray background color
248 struct BtnWindowClass
: public WindowClass
250 BtnWindowClass(LPCTSTR classname
, UINT style
=0, WNDPROC wndproc
=Window::WindowWndProc
)
251 : WindowClass(classname
, style
, wndproc
)
253 hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+1);
257 /// window class with specified icon from resources
258 struct IconWindowClass
: public WindowClass
260 IconWindowClass(LPCTSTR classname
, UINT nid
, UINT style
=0, WNDPROC wndproc
=Window::WindowWndProc
);
264 // private message constants
265 #define PM_DISPATCH_COMMAND (WM_APP+0x00)
266 #define PM_TRANSLATE_MSG (WM_APP+0x01)
269 #define SPLIT_WIDTH 5
270 #define DEFAULT_SPLIT_POS 300
271 #define COLOR_SPLITBAR LTGRAY_BRUSH
274 /// menu info structure
280 #define PM_FRM_GET_MENUINFO (WM_APP+0x02)
282 #define Frame_GetMenuInfo(hwnd) ((MenuInfo*)SNDMSG(hwnd, PM_FRM_GET_MENUINFO, 0, 0))
286 PreTranslateWindow is used to register windows to be called by Window::pretranslate_msg().
287 This way you get PM_TRANSLATE_MSG messages before the message loop dispatches messages.
288 You can then for example use TranslateAccelerator() to implement key shortcuts.
290 struct PreTranslateWindow
: public Window
292 typedef Window super
;
294 PreTranslateWindow(HWND
);
295 ~PreTranslateWindow();
301 Class ChildWindow represents MDI child windows.
302 It is used with class MainFrame.
304 struct ChildWindow
: public PreTranslateWindow
306 typedef PreTranslateWindow super
;
308 ChildWindow(HWND hwnd
, const ChildWndInfo
& info
);
310 static ChildWindow
* create(const ChildWndInfo
& info
, const RECT
& rect
, CREATORFUNC_INFO creator
,
311 LPCTSTR classname
, LPCTSTR title
=NULL
, DWORD style
=0);
313 bool go_to(LPCTSTR url
);
316 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
318 virtual void resize_children(int cx
, int cy
);
319 virtual String
jump_to_int(LPCTSTR url
) = 0;
324 WindowHandle _left_hwnd
;
325 WindowHandle _right_hwnd
;
326 int _focus_pane
; // 0: left 1: right
335 stack
<String
> _url_history
;
337 void set_url(LPCTSTR url
);
340 #define PM_SETSTATUSTEXT (WM_APP+0x1E)
344 The class DialogWindow implements modeless dialogs, which are managed by
345 Window::dispatch_dialog_msg() in Window::MessageLoop().
346 A DialogWindow object should be constructed by calling Window::Create()
347 and specifying the class using the WINDOW_CREATOR() macro.
349 struct DialogWindow
: public Window
351 typedef Window super
;
353 DialogWindow(HWND hwnd
)
356 register_dialog(hwnd
);
361 unregister_dialog(_hwnd
);
367 The class Dialog implements modal dialogs.
368 A Dialog object should be constructed by calling Dialog::DoModal()
369 and specifying the class using the WINDOW_CREATOR() macro.
371 struct Dialog
: public Window
373 typedef Window super
;
378 static int DoModal(UINT nid
, CREATORFUNC creator
, HWND hwndParent
=0);
379 static int DoModal(UINT nid
, CREATORFUNC_INFO creator
, const void* info
, HWND hwndParent
=0);
382 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
383 int Command(int id
, int code
);
387 #define PM_FRM_CALC_CLIENT (WM_APP+0x03)
388 #define Frame_CalcFrameClient(hwnd, prt) ((BOOL)SNDMSG(hwnd, PM_FRM_CALC_CLIENT, 0, (LPARAM)(PRECT)prt))
390 #define PM_JUMP_TO_URL (WM_APP+0x25)
391 #define PM_URL_CHANGED (WM_APP+0x26)
394 struct PropSheetPage
: public PROPSHEETPAGE
396 PropSheetPage(UINT nid
, Window::CREATORFUNC dlg_creator
);
398 void init(struct PropertySheetDialog
*);
401 friend struct PropSheetPageDlg
;
403 Window::CREATORFUNC _dlg_creator
;
407 /// Property Sheet dialog
408 struct PropertySheetDialog
: public PROPSHEETHEADER
410 PropertySheetDialog(HWND owner
);
412 void add(PropSheetPage
& psp
);
413 int DoModal(int start_page
=0);
415 HWND
GetCurrentPage();
418 typedef vector
<PROPSHEETPAGE
> Vector
;
424 /// Property Sheet Page (inner dialog)
425 struct PropSheetPageDlg
: public Dialog
427 typedef Dialog super
;
429 PropSheetPageDlg(HWND
);
432 friend struct PropertySheetDialog
;
433 friend struct PropSheetPage
;
435 static INT_PTR CALLBACK
DialogProc(HWND hwnd
, UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
437 int Command(int id
, int code
);
442 /// Property Sheet Dialog (outer dialog)
443 struct PropertySheetDlg : public SubclassedWindow
445 typedef SubclassedWindow super;
447 PropertySheetDlg(HWND hwnd) : super(hwnd) {}
452 // Layouting of resizable windows
454 /// Flags to specify how to move and resize controls when resizing their parent window
461 MOVE_X
= MOVE_LEFT
| MOVE_RIGHT
,
462 MOVE_Y
= MOVE_TOP
| MOVE_BOTTOM
,
463 RESIZE_X
= MOVE_RIGHT
,
464 RESIZE_Y
= MOVE_BOTTOM
,
466 MOVE
= MOVE_X
| MOVE_Y
,
467 RESIZE
= RESIZE_X
| RESIZE_Y
470 /// structure to assign RESIZE_FLAGS to dialogs control
473 ResizeEntry(UINT id
, int flags
)
474 : _id(id
), _flags(flags
) {}
476 ResizeEntry(HWND hwnd
, int flags
)
477 : _id(GetDlgCtrlID(hwnd
)), _flags(flags
) {}
484 /// Management of controls in resizable dialogs
485 struct ResizeManager
: public std::list
<ResizeEntry
>
487 typedef std::list
<ResizeEntry
> super
;
489 ResizeManager(HWND hwnd
);
491 void Add(UINT id
, int flags
)
492 {push_back(ResizeEntry(id
, flags
));}
494 void Add(HWND hwnd
, int flags
)
495 {push_back(ResizeEntry(hwnd
, flags
));}
497 void HandleSize(int cx
, int cy
);
498 void Resize(int dx
, int dy
);
500 void SetMinMaxInfo(LPMINMAXINFO lpmmi
)
502 lpmmi
->ptMinTrackSize
.x
= _min_wnd_size
.cx
;
503 lpmmi
->ptMinTrackSize
.y
= _min_wnd_size
.cy
;
514 /// Controller base template class for resizable dialogs
515 template<typename BASE
> struct ResizeController
: public BASE
519 ResizeController(HWND hwnd
)
525 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
528 case PM_FRM_CALC_CLIENT
:
529 GetClientSpace((PRECT
)lparam
);
533 if (wparam
!= SIZE_MINIMIZED
)
534 _resize_mgr
.HandleSize(LOWORD(lparam
), HIWORD(lparam
));
537 case WM_GETMINMAXINFO
:
538 _resize_mgr
.SetMinMaxInfo((LPMINMAXINFO
)lparam
);
542 return super::WndProc(nmsg
, wparam
, lparam
);
546 virtual void GetClientSpace(PRECT prect
)
548 if (!IsIconic(this->_hwnd
)) {
549 GetClientRect(this->_hwnd
, prect
);
552 GetWindowPlacement(this->_hwnd
, &wp
);
553 prect
->left
= prect
->top
= 0;
554 prect
->right
= wp
.rcNormalPosition
.right
-wp
.rcNormalPosition
.left
-
555 2*(GetSystemMetrics(SM_CXSIZEFRAME
)+GetSystemMetrics(SM_CXEDGE
));
556 prect
->bottom
= wp
.rcNormalPosition
.bottom
-wp
.rcNormalPosition
.top
-
557 2*(GetSystemMetrics(SM_CYSIZEFRAME
)+GetSystemMetrics(SM_CYEDGE
))-
558 GetSystemMetrics(SM_CYCAPTION
)-GetSystemMetrics(SM_CYMENUSIZE
);
563 ResizeManager _resize_mgr
;
568 This class constructs button controls.
569 The button will remain existent when the C++ Button object is destroyed.
570 There is no conjunction between C++ object and windows control life time.
572 struct Button
: public WindowHandle
574 Button(HWND parent
, LPCTSTR text
, int left
, int top
, int width
, int height
,
575 int id
, DWORD flags
=WS_VISIBLE
|WS_CHILD
|BS_PUSHBUTTON
, DWORD exStyle
=0);
580 This class constructs static controls.
581 The control will remain existent when the C++ object is destroyed.
582 There is no conjunction between C++ object and windows control life time.
584 struct Static
: public WindowHandle
586 Static(HWND parent
, LPCTSTR text
, int left
, int top
, int width
, int height
,
587 int id
, DWORD flags
=WS_VISIBLE
|WS_CHILD
|SS_SIMPLE
, DWORD ex_flags
=0);
591 // control color message routing for ColorStatic and HyperlinkCtrl
593 #define PM_DISPATCH_CTLCOLOR (WM_APP+0x08)
595 template<typename BASE
> struct CtlColorParent
: public BASE
599 CtlColorParent(HWND hwnd
)
602 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
608 case WM_CTLCOLORSCROLLBAR
:
609 case WM_CTLCOLORSTATIC
: {
610 HWND hctl
= (HWND
) lparam
;
611 return SendMessage(hctl
, PM_DISPATCH_CTLCOLOR
, wparam
, nmsg
);
615 return super::WndProc(nmsg
, wparam
, lparam
);
621 #define PM_DISPATCH_DRAWITEM (WM_APP+0x09)
623 /// draw message routing for ColorButton and PictureButton
624 template<typename BASE
> struct OwnerDrawParent
: public BASE
628 OwnerDrawParent(HWND hwnd
)
631 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
635 if (wparam
) { // should there be drawn a control?
636 HWND hctl
= GetDlgItem(this->_hwnd
, wparam
);
639 return SendMessage(hctl
, PM_DISPATCH_DRAWITEM
, wparam
, lparam
);
640 } /*else // or is it a menu entry?
646 return super::WndProc(nmsg
, wparam
, lparam
);
653 Subclass button controls to draw them by using PM_DISPATCH_DRAWITEM
654 The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
656 struct OwnerdrawnButton
: public SubclassedWindow
658 typedef SubclassedWindow super
;
660 OwnerdrawnButton(HWND hwnd
)
664 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
666 virtual void DrawItem(LPDRAWITEMSTRUCT dis
) = 0;
669 extern void DrawGrayText(HDC hdc
, LPRECT pRect
, LPCTSTR text
, int dt_flags
);
673 Subclass button controls to paint colored text labels.
674 The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
677 struct ColorButton : public OwnerdrawnButton
679 typedef OwnerdrawnButton super;
681 ColorButton(HWND hwnd, COLORREF textColor)
682 : super(hwnd), _textColor(textColor) {}
685 virtual void DrawItem(LPDRAWITEMSTRUCT dis);
692 struct FlatButton
: public OwnerdrawnButton
694 typedef OwnerdrawnButton super
;
696 FlatButton(HWND hwnd
)
697 : super(hwnd
), _active(false) {}
699 FlatButton(HWND owner
, int id
)
700 : super(GetDlgItem(owner
, IDOK
)), _active(false) {}
703 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
704 virtual void DrawItem(LPDRAWITEMSTRUCT dis
);
707 COLORREF _activeColor
;
713 Subclass button controls to paint pictures left to the labels.
714 The buttons should have set the style bit BS_OWNERDRAW.
715 The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
717 struct PictureButton
: public OwnerdrawnButton
719 typedef OwnerdrawnButton super
;
721 PictureButton(HWND hwnd
, HICON hIcon
, HBRUSH hbrush
=GetSysColorBrush(COLOR_BTNFACE
), bool flat
=false)
722 : super(hwnd
), _hIcon(hIcon
), _hBmp(0), _hBrush(hbrush
), _flat(flat
)
728 PictureButton(HWND hparent
, int id
, HICON hIcon
, HBRUSH hbrush
=GetSysColorBrush(COLOR_BTNFACE
), bool flat
=false)
729 : super(GetDlgItem(hparent
, id
)), _hIcon(hIcon
), _hBmp(0), _hBrush(hbrush
), _flat(flat
)
735 PictureButton(HWND hwnd
, HBITMAP hBmp
, HBRUSH hbrush
=GetSysColorBrush(COLOR_BTNFACE
), bool flat
=false)
736 : super(hwnd
), _hIcon(0), _hBmp(hBmp
), _hBrush(hbrush
), _flat(flat
)
739 GetObject(hBmp
, sizeof(bmp
), &bmp
);
744 PictureButton(HWND hparent
, int id
, HBITMAP hBmp
, HBRUSH hbrush
=GetSysColorBrush(COLOR_BTNFACE
), bool flat
=false)
745 : super(GetDlgItem(hparent
, id
)), _hIcon(0), _hBmp(hBmp
), _hBrush(hbrush
), _flat(flat
)
748 GetObject(hBmp
, sizeof(bmp
), &bmp
);
754 virtual void DrawItem(LPDRAWITEMSTRUCT dis
);
767 struct ColorStatic
: public SubclassedWindow
769 typedef SubclassedWindow super
;
771 ColorStatic(HWND hwnd
, COLORREF textColor
=RGB(255,0,0), HBRUSH hbrush_bkgnd
=0, HFONT hfont
=0)
773 _textColor(textColor
),
774 _hbrush_bkgnd(hbrush_bkgnd
),
779 ColorStatic(HWND owner
, int id
, COLORREF textColor
=RGB(255,0,0), HBRUSH hbrush_bkgnd
=0, HFONT hfont
=0)
780 : super(GetDlgItem(owner
, id
)),
781 _textColor(textColor
),
782 _hbrush_bkgnd(hbrush_bkgnd
),
788 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
790 if (nmsg
== PM_DISPATCH_CTLCOLOR
) {
791 HDC hdc
= (HDC
) wparam
;
793 SetTextColor(hdc
, _textColor
);
796 SelectFont(hdc
, _hfont
);
799 return (LRESULT
)_hbrush_bkgnd
;
801 SetBkMode(hdc
, TRANSPARENT
);
802 return (LRESULT
)GetStockBrush(HOLLOW_BRUSH
);
805 return super::WndProc(nmsg
, wparam
, lparam
);
809 HBRUSH _hbrush_bkgnd
;
814 /// Hyperlink Controls
816 struct HyperlinkCtrl
: public SubclassedWindow
818 typedef SubclassedWindow super
;
820 HyperlinkCtrl(HWND hwnd
, COLORREF colorLink
=RGB(0,0,255), COLORREF colorVisited
=RGB(128,0,128));
821 HyperlinkCtrl(HWND owner
, int id
, COLORREF colorLink
=RGB(0,0,255), COLORREF colorVisited
=RGB(128,0,128));
829 COLORREF _colorVisited
;
833 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
840 HINSTANCE hinst
= ShellExecute(GetParent(_hwnd
), _T("open"), _cmd
, 0, 0, SW_SHOWNORMAL
);
841 return (int)hinst
> HINSTANCE_ERROR
;
849 /// encapsulation of tool tip controls
850 struct ToolTip
: public WindowHandle
852 typedef WindowHandle super
;
856 void activate(BOOL active
=TRUE
)
858 SendMessage(_hwnd
, TTM_ACTIVATE
, active
, 0);
861 void add(HWND hparent
, HWND htool
, LPCTSTR txt
=LPSTR_TEXTCALLBACK
, LPARAM lparam
=0)
864 sizeof(TOOLINFO
), TTF_SUBCLASS
|TTF_IDISHWND
|TTF_TRANSPARENT
, hparent
, (UINT
)htool
,
865 {0,0,0,0}, 0, (LPTSTR
)txt
, lparam
868 #ifdef UNICODE ///@todo Why is it neccesary to try both TTM_ADDTOOLW and TTM_ADDTOOLW ?!
869 if (!SendMessage(_hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&ti
))
870 SendMessage(_hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
872 if (!SendMessage(_hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
))
873 SendMessage(_hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&ti
);
877 void add(HWND hparent
, UINT id
, const RECT
& rect
, LPCTSTR txt
=LPSTR_TEXTCALLBACK
, LPARAM lparam
=0)
880 sizeof(TOOLINFO
), TTF_SUBCLASS
|TTF_TRANSPARENT
, hparent
, id
,
881 {rect
.left
,rect
.top
,rect
.right
,rect
.bottom
}, 0, (LPTSTR
)txt
, lparam
885 if (!SendMessage(_hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&ti
))
886 SendMessage(_hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
888 if (!SendMessage(_hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
))
889 SendMessage(_hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&ti
);
893 void remove(HWND hparent
, HWND htool
)
896 sizeof(TOOLINFO
), TTF_IDISHWND
, hparent
, (UINT
)htool
,
900 SendMessage(_hwnd
, TTM_DELTOOL
, 0, (LPARAM
)&ti
);
903 void remove(HWND hparent
, UINT id
)
906 sizeof(TOOLINFO
), 0, hparent
, id
,
910 SendMessage(_hwnd
, TTM_DELTOOL
, 0, (LPARAM
)&ti
);
915 inline int ListView_GetItemData(HWND list_ctrl
, int idx
)
919 item
.mask
= LVIF_PARAM
;
922 if (!ListView_GetItem(list_ctrl
, &item
))
928 inline int ListView_FindItemPara(HWND list_ctrl
, LPARAM param
)
932 fi
.flags
= LVFI_PARAM
;
935 return ListView_FindItem(list_ctrl
, (unsigned)-1, &fi
);
938 inline int ListView_GetFocusedItem(HWND list_ctrl
)
940 int idx
= ListView_GetItemCount(list_ctrl
);
943 if (ListView_GetItemState(list_ctrl
, idx
, LVIS_FOCUSED
))
950 /// sorting of list controls
951 struct ListSort
: public WindowHandle
953 ListSort(HWND hwndListview
, PFNLVCOMPARE compare_fct
);
955 void toggle_sort(int idx
);
962 PFNLVCOMPARE _compare_fct
;
964 static int CALLBACK
CompareFunc(LPARAM lparam1
, LPARAM lparam2
, LPARAM lparamSort
);
968 inline LPARAM
TreeView_GetItemData(HWND hwndTreeView
, HTREEITEM hItem
)
972 tvItem
.mask
= TVIF_PARAM
;
973 tvItem
.hItem
= hItem
;
975 if (!TreeView_GetItem(hwndTreeView
, &tvItem
))
978 return tvItem
.lParam
;
982 enum {TRAYBUTTON_LEFT
=0, TRAYBUTTON_RIGHT
, TRAYBUTTON_MIDDLE
};
984 #define PM_TRAYICON (WM_APP+0x20)
986 #define WINMSG_TASKBARCREATED TEXT("TaskbarCreated")
988 #define WINMSG_SHELLHOOK TEXT("SHELLHOOK")
993 TrayIcon(HWND hparent
, UINT id
)
994 : _hparent(hparent
), _id(id
) {}
999 void Add(HICON hIcon
, LPCTSTR tooltip
=NULL
)
1000 {Set(NIM_ADD
, _id
, hIcon
, tooltip
);}
1002 void Modify(HICON hIcon
, LPCTSTR tooltip
=NULL
)
1003 {Set(NIM_MODIFY
, _id
, hIcon
, tooltip
);}
1007 NOTIFYICONDATA nid
= {
1008 sizeof(NOTIFYICONDATA
), // cbSize
1013 Shell_NotifyIcon(NIM_DELETE
, &nid
);
1020 void Set(DWORD dwMessage
, UINT id
, HICON hIcon
, LPCTSTR tooltip
=NULL
)
1022 NOTIFYICONDATA nid
= {
1023 sizeof(NOTIFYICONDATA
), // cbSize
1026 NIF_MESSAGE
|NIF_ICON
, // uFlags
1027 PM_TRAYICON
, // uCallbackMessage
1032 lstrcpyn(nid
.szTip
, tooltip
, COUNTOF(nid
.szTip
));
1035 nid
.uFlags
|= NIF_TIP
;
1037 Shell_NotifyIcon(dwMessage
, &nid
);
1042 template<typename BASE
> struct TrayIconControllerTemplate
: public BASE
1046 TrayIconControllerTemplate(HWND hwnd
) : BASE(hwnd
),
1047 WM_TASKBARCREATED(RegisterWindowMessage(WINMSG_TASKBARCREATED
))
1051 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
1053 if (nmsg
== PM_TRAYICON
) {
1056 TrayMouseOver(wparam
);
1059 case WM_LBUTTONDOWN
:
1060 TrayClick(wparam
, TRAYBUTTON_LEFT
);
1063 case WM_LBUTTONDBLCLK
:
1064 TrayDblClick(wparam
, TRAYBUTTON_LEFT
);
1067 case WM_RBUTTONDOWN
:
1068 TrayClick(wparam
, TRAYBUTTON_RIGHT
);
1071 case WM_RBUTTONDBLCLK
:
1072 TrayDblClick(wparam
, TRAYBUTTON_RIGHT
);
1075 case WM_MBUTTONDOWN
:
1076 TrayClick(wparam
, TRAYBUTTON_MIDDLE
);
1079 case WM_MBUTTONDBLCLK
:
1080 TrayDblClick(wparam
, TRAYBUTTON_MIDDLE
);
1085 } else if (nmsg
== WM_TASKBARCREATED
) {
1089 return super::WndProc(nmsg
, wparam
, lparam
);
1092 virtual void AddTrayIcons() = 0;
1093 virtual void TrayMouseOver(UINT id
) {}
1094 virtual void TrayClick(UINT id
, int btn
) {}
1095 virtual void TrayDblClick(UINT id
, int btn
) {}
1098 const UINT WM_TASKBARCREATED
;
1102 struct EditController
: public SubclassedWindow
1104 typedef SubclassedWindow super
;
1106 EditController(HWND hwnd
)
1112 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
1114 if (nmsg
==WM_KEYDOWN
&& wparam
==VK_RETURN
) {
1115 SendParent(WM_COMMAND
, MAKEWPARAM(GetDlgCtrlID(_hwnd
),1), (LPARAM
)_hwnd
);
1118 return super::WndProc(nmsg
, wparam
, lparam
);