2 * Copyright 2003, 2004 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
, DWORD dwExStyle
,
70 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(HWND hwnd
=0);
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 Class ChildWindow represents MDI child windows.
287 It is used with class MainFrame.
289 struct ChildWindow
: public Window
291 typedef Window super
;
293 ChildWindow(HWND hwnd
, const ChildWndInfo
& info
);
295 static ChildWindow
* create(const ChildWndInfo
& info
, const RECT
& rect
, CREATORFUNC_INFO creator
,
296 LPCTSTR classname
, LPCTSTR title
=NULL
, DWORD style
=0);
298 bool go_to(LPCTSTR url
);
301 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
303 virtual void resize_children(int cx
, int cy
);
304 virtual String
jump_to_int(LPCTSTR url
) = 0;
309 WindowHandle _left_hwnd
;
310 WindowHandle _right_hwnd
;
311 int _focus_pane
; // 0: left 1: right
320 stack
<String
> _url_history
;
322 void set_url(LPCTSTR url
);
325 #define PM_SETSTATUSTEXT (WM_APP+0x1E)
329 PreTranslateWindow is used to register windows to be called by Window::pretranslate_msg().
330 This way you get PM_TRANSLATE_MSG messages before the message loop dispatches messages.
331 You can then for example use TranslateAccelerator() to implement key shortcuts.
333 struct PreTranslateWindow
: public Window
335 typedef Window super
;
337 PreTranslateWindow(HWND
);
338 ~PreTranslateWindow();
343 The class DialogWindow implements modeless dialogs, which are managed by
344 Window::dispatch_dialog_msg() in Window::MessageLoop().
345 A DialogWindow object should be constructed by calling Window::Create()
346 and specifying the class using the WINDOW_CREATOR() macro.
348 struct DialogWindow
: public Window
350 typedef Window super
;
352 DialogWindow(HWND hwnd
)
355 register_dialog(hwnd
);
360 unregister_dialog(_hwnd
);
366 The class Dialog implements modal dialogs.
367 A Dialog object should be constructed by calling Dialog::DoModal()
368 and specifying the class using the WINDOW_CREATOR() macro.
370 struct Dialog
: public Window
372 typedef Window super
;
377 static int DoModal(UINT nid
, CREATORFUNC creator
, HWND hwndParent
=0);
378 static int DoModal(UINT nid
, CREATORFUNC_INFO creator
, const void* info
, HWND hwndParent
=0);
381 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
382 int Command(int id
, int code
);
386 #define PM_FRM_CALC_CLIENT (WM_APP+0x03)
387 #define Frame_CalcFrameClient(hwnd, prt) ((BOOL)SNDMSG(hwnd, PM_FRM_CALC_CLIENT, 0, (LPARAM)(PRECT)prt))
389 #define PM_JUMP_TO_URL (WM_APP+0x25)
390 #define PM_URL_CHANGED (WM_APP+0x26)
393 struct PropSheetPage
: public PROPSHEETPAGE
395 PropSheetPage(UINT nid
, Window::CREATORFUNC dlg_creator
);
397 void init(struct PropertySheetDialog
*);
400 friend struct PropSheetPageDlg
;
402 Window::CREATORFUNC _dlg_creator
;
406 /// Property Sheet dialog
407 struct PropertySheetDialog
: public PROPSHEETHEADER
409 PropertySheetDialog(HWND owner
);
411 void add(PropSheetPage
& psp
);
412 int DoModal(int start_page
=0);
414 HWND
GetCurrentPage();
417 typedef vector
<PROPSHEETPAGE
> Vector
;
423 /// Property Sheet Page (inner dialog)
424 struct PropSheetPageDlg
: public Dialog
426 typedef Dialog super
;
428 PropSheetPageDlg(HWND
);
431 friend struct PropertySheetDialog
;
432 friend struct PropSheetPage
;
434 static INT_PTR CALLBACK
DialogProc(HWND hwnd
, UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
436 int Command(int id
, int code
);
441 /// Property Sheet Dialog (outer dialog)
442 struct PropertySheetDlg : public SubclassedWindow
444 typedef SubclassedWindow super;
446 PropertySheetDlg(HWND hwnd) : super(hwnd) {}
451 // Layouting of resizable windows
453 /// Flags to specify how to move and resize controls when resizing their parent window
460 MOVE_X
= MOVE_LEFT
| MOVE_RIGHT
,
461 MOVE_Y
= MOVE_TOP
| MOVE_BOTTOM
,
462 RESIZE_X
= MOVE_RIGHT
,
463 RESIZE_Y
= MOVE_BOTTOM
,
465 MOVE
= MOVE_X
| MOVE_Y
,
466 RESIZE
= RESIZE_X
| RESIZE_Y
469 /// structure to assign RESIZE_FLAGS to dialogs control
472 ResizeEntry(UINT id
, int flags
)
473 : _id(id
), _flags(flags
) {}
475 ResizeEntry(HWND hwnd
, int flags
)
476 : _id(GetDlgCtrlID(hwnd
)), _flags(flags
) {}
483 /// Management of controls in resizable dialogs
484 struct ResizeManager
: public std::list
<ResizeEntry
>
486 typedef std::list
<ResizeEntry
> super
;
488 ResizeManager(HWND hwnd
);
490 void Add(UINT id
, int flags
)
491 {push_back(ResizeEntry(id
, flags
));}
493 void Add(HWND hwnd
, int flags
)
494 {push_back(ResizeEntry(hwnd
, flags
));}
496 void HandleSize(int cx
, int cy
);
497 void Resize(int dx
, int dy
);
499 void SetMinMaxInfo(LPMINMAXINFO lpmmi
)
501 lpmmi
->ptMinTrackSize
.x
= _min_wnd_size
.cx
;
502 lpmmi
->ptMinTrackSize
.y
= _min_wnd_size
.cy
;
513 /// Controller base template class for resizable dialogs
514 template<typename BASE
> struct ResizeController
: public BASE
518 ResizeController(HWND hwnd
)
524 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
527 case PM_FRM_CALC_CLIENT
:
528 GetClientSpace((PRECT
)lparam
);
532 if (wparam
!= SIZE_MINIMIZED
)
533 _resize_mgr
.HandleSize(LOWORD(lparam
), HIWORD(lparam
));
536 case WM_GETMINMAXINFO
:
537 _resize_mgr
.SetMinMaxInfo((LPMINMAXINFO
)lparam
);
541 return super::WndProc(nmsg
, wparam
, lparam
);
545 virtual void GetClientSpace(PRECT prect
)
547 if (!IsIconic(this->_hwnd
)) {
548 GetClientRect(this->_hwnd
, prect
);
551 GetWindowPlacement(this->_hwnd
, &wp
);
552 prect
->left
= prect
->top
= 0;
553 prect
->right
= wp
.rcNormalPosition
.right
-wp
.rcNormalPosition
.left
-
554 2*(GetSystemMetrics(SM_CXSIZEFRAME
)+GetSystemMetrics(SM_CXEDGE
));
555 prect
->bottom
= wp
.rcNormalPosition
.bottom
-wp
.rcNormalPosition
.top
-
556 2*(GetSystemMetrics(SM_CYSIZEFRAME
)+GetSystemMetrics(SM_CYEDGE
))-
557 GetSystemMetrics(SM_CYCAPTION
)-GetSystemMetrics(SM_CYMENUSIZE
);
562 ResizeManager _resize_mgr
;
567 This class constructs button controls.
568 The button will remain existent when the C++ Button object is destroyed.
569 There is no conjunction between C++ object and windows control life time.
571 struct Button
: public WindowHandle
573 Button(HWND parent
, LPCTSTR text
, int left
, int top
, int width
, int height
,
574 int id
, DWORD flags
=WS_VISIBLE
|WS_CHILD
|BS_PUSHBUTTON
, DWORD exStyle
=0);
579 This class constructs static controls.
580 The control will remain existent when the C++ object is destroyed.
581 There is no conjunction between C++ object and windows control life time.
583 struct Static
: public WindowHandle
585 Static(HWND parent
, LPCTSTR text
, int left
, int top
, int width
, int height
,
586 int id
, DWORD flags
=WS_VISIBLE
|WS_CHILD
|SS_SIMPLE
, DWORD ex_flags
=0);
590 // control color message routing for ColorStatic and HyperlinkCtrl
592 #define PM_DISPATCH_CTLCOLOR (WM_APP+0x08)
594 template<typename BASE
> struct CtlColorParent
: public BASE
598 CtlColorParent(HWND hwnd
)
601 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
607 case WM_CTLCOLORSCROLLBAR
:
608 case WM_CTLCOLORSTATIC
: {
609 HWND hctl
= (HWND
) lparam
;
610 return SendMessage(hctl
, PM_DISPATCH_CTLCOLOR
, wparam
, nmsg
);
614 return super::WndProc(nmsg
, wparam
, lparam
);
620 #define PM_DISPATCH_DRAWITEM (WM_APP+0x09)
622 /// draw message routing for ColorButton and PictureButton
623 template<typename BASE
> struct OwnerDrawParent
: public BASE
627 OwnerDrawParent(HWND hwnd
)
630 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
634 if (wparam
) { // should there be drawn a control?
635 HWND hctl
= GetDlgItem(this->_hwnd
, wparam
);
638 return SendMessage(hctl
, PM_DISPATCH_DRAWITEM
, wparam
, lparam
);
639 } /*else // or is it a menu entry?
645 return super::WndProc(nmsg
, wparam
, lparam
);
652 Subclass button controls to draw them by using PM_DISPATCH_DRAWITEM
653 The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
655 struct OwnerdrawnButton
: public SubclassedWindow
657 typedef SubclassedWindow super
;
659 OwnerdrawnButton(HWND hwnd
)
663 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
665 virtual void DrawItem(LPDRAWITEMSTRUCT dis
) = 0;
668 extern void DrawGrayText(HDC hdc
, LPRECT pRect
, LPCTSTR text
, int dt_flags
);
672 Subclass button controls to paint colored text labels.
673 The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
676 struct ColorButton : public OwnerdrawnButton
678 typedef OwnerdrawnButton super;
680 ColorButton(HWND hwnd, COLORREF textColor)
681 : super(hwnd), _textColor(textColor) {}
684 virtual void DrawItem(LPDRAWITEMSTRUCT dis);
691 struct FlatButton
: public OwnerdrawnButton
693 typedef OwnerdrawnButton super
;
695 FlatButton(HWND hwnd
)
696 : super(hwnd
), _active(false) {}
698 FlatButton(HWND owner
, int id
)
699 : super(GetDlgItem(owner
, IDOK
)), _active(false) {}
702 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
703 virtual void DrawItem(LPDRAWITEMSTRUCT dis
);
706 COLORREF _activeColor
;
712 Subclass button controls to paint pictures left to the labels.
713 The buttons should have set the style bit BS_OWNERDRAW.
714 The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
716 struct PictureButton
: public OwnerdrawnButton
718 typedef OwnerdrawnButton super
;
720 PictureButton(HWND hwnd
, HICON hIcon
, HBRUSH hbrush
=GetSysColorBrush(COLOR_BTNFACE
), bool flat
=false)
721 : super(hwnd
), _hIcon(hIcon
), _hBmp(0), _hBrush(hbrush
), _flat(flat
)
727 PictureButton(HWND hparent
, int id
, HICON hIcon
, HBRUSH hbrush
=GetSysColorBrush(COLOR_BTNFACE
), bool flat
=false)
728 : super(GetDlgItem(hparent
, id
)), _hIcon(hIcon
), _hBmp(0), _hBrush(hbrush
), _flat(flat
)
734 PictureButton(HWND hwnd
, HBITMAP hBmp
, HBRUSH hbrush
=GetSysColorBrush(COLOR_BTNFACE
), bool flat
=false)
735 : super(hwnd
), _hIcon(0), _hBmp(hBmp
), _hBrush(hbrush
), _flat(flat
)
738 GetObject(hBmp
, sizeof(bmp
), &bmp
);
743 PictureButton(HWND hparent
, int id
, HBITMAP hBmp
, HBRUSH hbrush
=GetSysColorBrush(COLOR_BTNFACE
), bool flat
=false)
744 : super(GetDlgItem(hparent
, id
)), _hIcon(0), _hBmp(hBmp
), _hBrush(hbrush
), _flat(flat
)
747 GetObject(hBmp
, sizeof(bmp
), &bmp
);
753 virtual void DrawItem(LPDRAWITEMSTRUCT dis
);
766 struct ColorStatic
: public SubclassedWindow
768 typedef SubclassedWindow super
;
770 ColorStatic(HWND hwnd
, COLORREF textColor
=RGB(255,0,0), HBRUSH hbrush_bkgnd
=0, HFONT hfont
=0)
772 _textColor(textColor
),
773 _hbrush_bkgnd(hbrush_bkgnd
),
778 ColorStatic(HWND owner
, int id
, COLORREF textColor
=RGB(255,0,0), HBRUSH hbrush_bkgnd
=0, HFONT hfont
=0)
779 : super(GetDlgItem(owner
, id
)),
780 _textColor(textColor
),
781 _hbrush_bkgnd(hbrush_bkgnd
),
787 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
789 if (nmsg
== PM_DISPATCH_CTLCOLOR
) {
790 HDC hdc
= (HDC
) wparam
;
792 SetTextColor(hdc
, _textColor
);
795 SelectFont(hdc
, _hfont
);
798 return (LRESULT
)_hbrush_bkgnd
;
800 SetBkMode(hdc
, TRANSPARENT
);
801 return (LRESULT
)GetStockBrush(HOLLOW_BRUSH
);
804 return super::WndProc(nmsg
, wparam
, lparam
);
808 HBRUSH _hbrush_bkgnd
;
813 /// Hyperlink Controls
815 struct HyperlinkCtrl
: public SubclassedWindow
817 typedef SubclassedWindow super
;
819 HyperlinkCtrl(HWND hwnd
, COLORREF colorLink
=RGB(0,0,255), COLORREF colorVisited
=RGB(128,0,128));
820 HyperlinkCtrl(HWND owner
, int id
, COLORREF colorLink
=RGB(0,0,255), COLORREF colorVisited
=RGB(128,0,128));
828 COLORREF _colorVisited
;
832 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
839 HINSTANCE hinst
= ShellExecute(GetParent(_hwnd
), _T("open"), _cmd
, 0, 0, SW_SHOWNORMAL
);
840 return (int)hinst
> HINSTANCE_ERROR
;
848 /// encapsulation of tool tip controls
849 struct ToolTip
: public WindowHandle
851 typedef WindowHandle super
;
855 void activate(BOOL active
=TRUE
)
857 SendMessage(_hwnd
, TTM_ACTIVATE
, active
, 0);
860 void add(HWND hparent
, HWND htool
, LPCTSTR txt
=LPSTR_TEXTCALLBACK
, LPARAM lparam
=0)
863 sizeof(TOOLINFO
), TTF_SUBCLASS
|TTF_IDISHWND
|TTF_TRANSPARENT
, hparent
, (UINT
)htool
,
864 {0,0,0,0}, 0, (LPTSTR
)txt
, lparam
867 #ifdef UNICODE ///@todo Why is it neccesary to try both TTM_ADDTOOLW and TTM_ADDTOOLW ?!
868 if (!SendMessage(_hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&ti
))
869 SendMessage(_hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
871 if (!SendMessage(_hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
))
872 SendMessage(_hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&ti
);
876 void add(HWND hparent
, UINT id
, const RECT
& rect
, LPCTSTR txt
=LPSTR_TEXTCALLBACK
, LPARAM lparam
=0)
879 sizeof(TOOLINFO
), TTF_SUBCLASS
|TTF_TRANSPARENT
, hparent
, id
,
880 {rect
.left
,rect
.top
,rect
.right
,rect
.bottom
}, 0, (LPTSTR
)txt
, lparam
884 if (!SendMessage(_hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&ti
))
885 SendMessage(_hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
887 if (!SendMessage(_hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
))
888 SendMessage(_hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&ti
);
892 void remove(HWND hparent
, HWND htool
)
895 sizeof(TOOLINFO
), TTF_IDISHWND
, hparent
, (UINT
)htool
,
899 SendMessage(_hwnd
, TTM_DELTOOL
, 0, (LPARAM
)&ti
);
902 void remove(HWND hparent
, UINT id
)
905 sizeof(TOOLINFO
), 0, hparent
, id
,
909 SendMessage(_hwnd
, TTM_DELTOOL
, 0, (LPARAM
)&ti
);
914 inline int ListView_GetItemData(HWND list_ctrl
, int idx
)
918 item
.mask
= LVIF_PARAM
;
921 if (!ListView_GetItem(list_ctrl
, &item
))
927 inline int ListView_FindItemPara(HWND list_ctrl
, LPARAM param
)
931 fi
.flags
= LVFI_PARAM
;
934 return ListView_FindItem(list_ctrl
, (unsigned)-1, &fi
);
937 inline int ListView_GetFocusedItem(HWND list_ctrl
)
939 int idx
= ListView_GetItemCount(list_ctrl
);
942 if (ListView_GetItemState(list_ctrl
, idx
, LVIS_FOCUSED
))
949 /// sorting of list controls
950 struct ListSort
: public WindowHandle
952 ListSort(HWND hwndListview
, PFNLVCOMPARE compare_fct
);
954 void toggle_sort(int idx
);
961 PFNLVCOMPARE _compare_fct
;
963 static int CALLBACK
CompareFunc(LPARAM lparam1
, LPARAM lparam2
, LPARAM lparamSort
);
967 inline LPARAM
TreeView_GetItemData(HWND hwndTreeView
, HTREEITEM hItem
)
971 tvItem
.mask
= TVIF_PARAM
;
972 tvItem
.hItem
= hItem
;
974 if (!TreeView_GetItem(hwndTreeView
, &tvItem
))
977 return tvItem
.lParam
;
981 enum {TRAYBUTTON_LEFT
=0, TRAYBUTTON_RIGHT
, TRAYBUTTON_MIDDLE
};
983 #define PM_TRAYICON (WM_APP+0x20)
985 #define WINMSG_TASKBARCREATED TEXT("TaskbarCreated")
987 #define WINMSG_SHELLHOOK TEXT("SHELLHOOK")
992 TrayIcon(HWND hparent
, UINT id
)
993 : _hparent(hparent
), _id(id
) {}
998 void Add(HICON hIcon
, LPCTSTR tooltip
=NULL
)
999 {Set(NIM_ADD
, _id
, hIcon
, tooltip
);}
1001 void Modify(HICON hIcon
, LPCTSTR tooltip
=NULL
)
1002 {Set(NIM_MODIFY
, _id
, hIcon
, tooltip
);}
1006 NOTIFYICONDATA nid
= {
1007 sizeof(NOTIFYICONDATA
), // cbSize
1012 Shell_NotifyIcon(NIM_DELETE
, &nid
);
1019 void Set(DWORD dwMessage
, UINT id
, HICON hIcon
, LPCTSTR tooltip
=NULL
)
1021 NOTIFYICONDATA nid
= {
1022 sizeof(NOTIFYICONDATA
), // cbSize
1025 NIF_MESSAGE
|NIF_ICON
, // uFlags
1026 PM_TRAYICON
, // uCallbackMessage
1031 lstrcpyn(nid
.szTip
, tooltip
, COUNTOF(nid
.szTip
));
1034 nid
.uFlags
|= NIF_TIP
;
1036 Shell_NotifyIcon(dwMessage
, &nid
);
1041 template<typename BASE
> struct TrayIconControllerTemplate
: public BASE
1045 TrayIconControllerTemplate(HWND hwnd
) : BASE(hwnd
),
1046 WM_TASKBARCREATED(RegisterWindowMessage(WINMSG_TASKBARCREATED
))
1050 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
1052 if (nmsg
== PM_TRAYICON
) {
1055 TrayMouseOver(wparam
);
1058 case WM_LBUTTONDOWN
:
1059 TrayClick(wparam
, TRAYBUTTON_LEFT
);
1062 case WM_LBUTTONDBLCLK
:
1063 TrayDblClick(wparam
, TRAYBUTTON_LEFT
);
1066 case WM_RBUTTONDOWN
:
1067 TrayClick(wparam
, TRAYBUTTON_RIGHT
);
1070 case WM_RBUTTONDBLCLK
:
1071 TrayDblClick(wparam
, TRAYBUTTON_RIGHT
);
1074 case WM_MBUTTONDOWN
:
1075 TrayClick(wparam
, TRAYBUTTON_MIDDLE
);
1078 case WM_MBUTTONDBLCLK
:
1079 TrayDblClick(wparam
, TRAYBUTTON_MIDDLE
);
1084 } else if (nmsg
== WM_TASKBARCREATED
) {
1088 return super::WndProc(nmsg
, wparam
, lparam
);
1091 virtual void AddTrayIcons() = 0;
1092 virtual void TrayMouseOver(UINT id
) {}
1093 virtual void TrayClick(UINT id
, int btn
) {}
1094 virtual void TrayDblClick(UINT id
, int btn
) {}
1097 const UINT WM_TASKBARCREATED
;
1101 struct EditController
: public SubclassedWindow
1103 typedef SubclassedWindow super
;
1105 EditController(HWND hwnd
)
1111 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
1113 if (nmsg
==WM_KEYDOWN
&& wparam
==VK_RETURN
) {
1114 SendParent(WM_COMMAND
, MAKEWPARAM(GetDlgCtrlID(_hwnd
),1), (LPARAM
)_hwnd
);
1117 return super::WndProc(nmsg
, wparam
, lparam
);