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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 // ROS Internet Web Browser
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 child window
46 ChildWndInfo(HWND hwndFrame
)
47 : _hwndFrame(hwndFrame
) {}
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 LRESULT CALLBACK
WindowWndProc(HWND hwnd
, UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
80 static INT_PTR CALLBACK
DialogProc(HWND hwnd
, UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
82 static Window
* get_window(HWND hwnd
);
84 template<typename CLASS
> static CLASS
* get_window(HWND hwnd
) {return static_cast<CLASS
*>(get_window(hwnd
));}
85 #define GET_WINDOW(CLASS, hwnd) Window::get_window<CLASS>(hwnd)
88 static void register_pretranslate(HWND hwnd
);
89 static void unregister_pretranslate(HWND hwnd
);
90 static BOOL
pretranslate_msg(LPMSG pmsg
);
92 static void register_dialog(HWND hwnd
);
93 static void unregister_dialog(HWND hwnd
);
94 static BOOL
dispatch_dialog_msg(LPMSG pmsg
);
96 static int MessageLoop();
99 LRESULT
SendParent(UINT nmsg
, WPARAM wparam
=0, LPARAM lparam
=0);
100 LRESULT
PostParent(UINT nmsg
, WPARAM wparam
=0, LPARAM lparam
=0);
102 static void CancelModes(HWND hwnd
=0);
106 virtual LRESULT
Init(LPCREATESTRUCT pcs
); // WM_CREATE processing
107 virtual LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
108 virtual int Command(int id
, int code
); // WM_COMMAND processing
109 virtual int Notify(int id
, NMHDR
* pnmh
); // WM_NOTIFY processing
111 static Window
* create_controller(HWND hwnd
);
114 static WindowMap s_wnd_map
;
116 static const void* s_new_info
;
117 static CREATORFUNC s_window_creator
;
120 /// structure for managing critical sections as static class information in struct Window
121 struct StaticWindowData
{
122 CritSect _map_crit_sect
;
123 CritSect _create_crit_sect
;
126 static StaticWindowData
& GetStaticWindowData();
129 static WindowSet s_pretranslate_windows
;
130 static WindowSet s_dialogs
;
134 #define NFR_CURRENT NFR_UNICODE
136 #define NFR_CURRENT NFR_ANSI
141 template<typename CLASS
> struct GetWindowHelper
143 static CLASS
* get_window(HWND hwnd
) {
144 return static_cast<CLASS
*>(Window::get_window(hwnd
));
147 #define GET_WINDOW(CLASS, hwnd) GetWindowHelper<CLASS>::get_window(hwnd)
151 /// dynamic casting of Window pointers
152 template<typename CLASS
> struct TypeCheck
154 static CLASS
* dyn_cast(Window
* wnd
)
155 {return dynamic_cast<CLASS
*>(wnd
);}
158 #define WINDOW_DYNAMIC_CAST(CLASS, hwnd) \
159 TypeCheck<CLASS>::dyn_cast(Window::get_window(hwnd))
163 SubclassedWindow is used to wrap already existing window handles
164 into C++ Window objects. To construct a object, use the "new" operator
165 to put it in the heap. It is automatically freed, when the window
168 struct SubclassedWindow
: public Window
170 typedef Window super
;
172 SubclassedWindow(HWND
);
177 static LRESULT CALLBACK
SubclassedWndProc(HWND hwnd
, UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
179 virtual LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
180 virtual int Command(int id
, int code
);
181 virtual int Notify(int id
, NMHDR
* pnmh
);
185 /// template class used in macro WINDOW_CREATOR to define the creater functions for Window objects
186 template<typename WND_CLASS
> struct WindowCreator
188 static WND_CLASS
* window_creator(HWND hwnd
)
190 return new WND_CLASS(hwnd
);
194 #define WINDOW_CREATOR(WND_CLASS) \
195 ((Window::CREATORFUNC) WindowCreator<WND_CLASS>::window_creator)
198 /// template class used in macro WINDOW_CREATOR_INFO to the define creater functions for Window objects with additional creation information
199 template<typename WND_CLASS
, typename INFO_CLASS
> struct WindowCreatorInfo
201 static WND_CLASS
* window_creator(HWND hwnd
, const void* info
)
203 return new WND_CLASS(hwnd
, *static_cast<const INFO_CLASS
*>(info
));
207 #define WINDOW_CREATOR_INFO(WND_CLASS, INFO_CLASS) \
208 ((Window::CREATORFUNC_INFO) WindowCreatorInfo<WND_CLASS, INFO_CLASS>::window_creator)
212 WindowClass is a neat wrapper for RegisterClassEx().
213 Just construct a WindowClass object, override the attributes you want
214 to change, then call Register() or simply request the ATOM value to
215 register the window class. You don't have to worry calling Register()
216 more than once. It checks if, the class has already been registered.
218 struct WindowClass
: public WNDCLASSEX
220 WindowClass(LPCTSTR classname
, UINT style
=0, WNDPROC wndproc
=Window::WindowWndProc
);
225 _atomClass
= RegisterClassEx(this);
230 operator ATOM() {return Register();}
232 // return LPCTSTR for the CreateWindowEx() parameter
233 operator LPCTSTR() {return (LPCTSTR
)(int)Register();}
239 /// window class with gray background color
240 struct BtnWindowClass
: public WindowClass
242 BtnWindowClass(LPCTSTR classname
, UINT style
=0, WNDPROC wndproc
=Window::WindowWndProc
)
243 : WindowClass(classname
, style
, wndproc
)
245 hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+1);
249 /// window class with specified icon from resources
250 struct IconWindowClass
: public WindowClass
252 IconWindowClass(LPCTSTR classname
, UINT nid
, UINT style
=0, WNDPROC wndproc
=Window::WindowWndProc
);
256 // private message constants
257 #define PM_DISPATCH_COMMAND (WM_APP+0x00)
258 #define PM_TRANSLATE_MSG (WM_APP+0x01)
261 #define SPLIT_WIDTH 5
262 #define DEFAULT_SPLIT_POS 300
263 #define COLOR_SPLITBAR LTGRAY_BRUSH
266 /// menu info structure
272 #define PM_FRM_GET_MENUINFO (WM_APP+0x02)
274 #define Frame_GetMenuInfo(hwnd) ((MenuInfo*)SNDMSG(hwnd, PM_FRM_GET_MENUINFO, 0, 0))
278 Class ChildWindow is used with class MainFrame.
280 struct ChildWindow
: public Window
282 typedef Window super
;
284 ChildWindow(HWND hwnd
, HWND hwndFrame
);
286 static ChildWindow
* create(const ChildWndInfo
& info
, CREATORFUNC_INFO creator
,
287 LPCTSTR classname
, LPCTSTR title
=NULL
, DWORD style
=0);
289 bool go_to(LPCTSTR url
);
292 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
294 virtual String
jump_to_int(LPCTSTR url
) = 0;
303 stack
<String
> _url_history
;
305 void set_url(LPCTSTR url
);
308 #define PM_SETSTATUSTEXT (WM_APP+0x1E)
312 PreTranslateWindow is used to register windows to be called by Window::pretranslate_msg().
313 This way you get PM_TRANSLATE_MSG messages before the message loop dispatches messages.
314 You can then for example use TranslateAccelerator() to implement key shortcuts.
316 struct PreTranslateWindow
: public Window
318 typedef Window super
;
320 PreTranslateWindow(HWND
);
321 ~PreTranslateWindow();
326 The class DialogWindow implements modeless dialogs, which are managed by
327 Window::dispatch_dialog_msg() in Window::MessageLoop().
328 A DialogWindow object should be constructed by calling Window::Create()
329 and specifying the class using the WINDOW_CREATOR() macro.
331 struct DialogWindow
: public Window
333 typedef Window super
;
335 DialogWindow(HWND hwnd
)
338 register_dialog(hwnd
);
343 unregister_dialog(_hwnd
);
349 The class Dialog implements modal dialogs.
350 A Dialog object should be constructed by calling Dialog::DoModal()
351 and specifying the class using the WINDOW_CREATOR() macro.
353 struct Dialog
: public Window
355 typedef Window super
;
360 static int DoModal(UINT nid
, CREATORFUNC creator
, HWND hwndParent
=0);
361 static int DoModal(UINT nid
, CREATORFUNC_INFO creator
, const void* info
, HWND hwndParent
=0);
364 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
365 int Command(int id
, int code
);
369 #define PM_FRM_CALC_CLIENT (WM_APP+0x03)
370 #define Frame_CalcFrameClient(hwnd, prt) ((BOOL)SNDMSG(hwnd, PM_FRM_CALC_CLIENT, 0, (LPARAM)(PRECT)prt))
372 #define PM_JUMP_TO_URL (WM_APP+0x25)
373 #define PM_URL_CHANGED (WM_APP+0x26)
376 struct PropSheetPage
: public PROPSHEETPAGE
378 PropSheetPage(UINT nid
, Window::CREATORFUNC dlg_creator
);
380 void init(struct PropertySheetDialog
*);
383 friend struct PropSheetPageDlg
;
385 Window::CREATORFUNC _dlg_creator
;
389 /// Property Sheet dialog
390 struct PropertySheetDialog
: public PROPSHEETHEADER
392 PropertySheetDialog(HWND owner
);
394 void add(PropSheetPage
& psp
);
395 int DoModal(int start_page
=0);
397 HWND
GetCurrentPage();
400 typedef vector
<PROPSHEETPAGE
> Vector
;
406 /// Property Sheet Page (inner dialog)
407 struct PropSheetPageDlg
: public Dialog
409 typedef Dialog super
;
411 PropSheetPageDlg(HWND
);
414 friend struct PropertySheetDialog
;
415 friend struct PropSheetPage
;
417 static INT_PTR CALLBACK
DialogProc(HWND hwnd
, UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
419 int Command(int id
, int code
);
424 /// Property Sheet Dialog (outer dialog)
425 struct PropertySheetDlg : public SubclassedWindow
427 typedef SubclassedWindow super;
429 PropertySheetDlg(HWND hwnd) : super(hwnd) {}
434 // Layouting of resizable windows
436 /// Flags to specify how to move and resize controls when resizing their parent window
443 MOVE_X
= MOVE_LEFT
| MOVE_RIGHT
,
444 MOVE_Y
= MOVE_TOP
| MOVE_BOTTOM
,
445 RESIZE_X
= MOVE_RIGHT
,
446 RESIZE_Y
= MOVE_BOTTOM
,
448 MOVE
= MOVE_X
| MOVE_Y
,
449 RESIZE
= RESIZE_X
| RESIZE_Y
452 /// structure to assign RESIZE_FLAGS to dialogs control
455 ResizeEntry(UINT id
, int flags
)
456 : _id(id
), _flags(flags
) {}
458 ResizeEntry(HWND hwnd
, int flags
)
459 : _id(GetDlgCtrlID(hwnd
)), _flags(flags
) {}
466 /// Management of controls in resizable dialogs
467 struct ResizeManager
: public std::list
<ResizeEntry
>
469 typedef std::list
<ResizeEntry
> super
;
471 ResizeManager(HWND hwnd
);
473 void Add(UINT id
, int flags
)
474 {push_back(ResizeEntry(id
, flags
));}
476 void Add(HWND hwnd
, int flags
)
477 {push_back(ResizeEntry(hwnd
, flags
));}
479 void HandleSize(int cx
, int cy
);
480 void Resize(int dx
, int dy
);
482 void SetMinMaxInfo(LPMINMAXINFO lpmmi
)
484 lpmmi
->ptMinTrackSize
.x
= _min_wnd_size
.cx
;
485 lpmmi
->ptMinTrackSize
.y
= _min_wnd_size
.cy
;
496 /// Controller base template class for resizable dialogs
497 template<typename BASE
> struct ResizeController
: public BASE
501 ResizeController(HWND hwnd
)
507 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
510 case PM_FRM_CALC_CLIENT
:
511 GetClientSpace((PRECT
)lparam
);
515 if (wparam
!= SIZE_MINIMIZED
)
516 _resize_mgr
.HandleSize(LOWORD(lparam
), HIWORD(lparam
));
519 case WM_GETMINMAXINFO
:
520 _resize_mgr
.SetMinMaxInfo((LPMINMAXINFO
)lparam
);
524 return super::WndProc(nmsg
, wparam
, lparam
);
528 virtual void GetClientSpace(PRECT prect
)
530 if (!IsIconic(this->_hwnd
)) {
531 GetClientRect(this->_hwnd
, prect
);
534 GetWindowPlacement(this->_hwnd
, &wp
);
535 prect
->left
= prect
->top
= 0;
536 prect
->right
= wp
.rcNormalPosition
.right
-wp
.rcNormalPosition
.left
-
537 2*(GetSystemMetrics(SM_CXSIZEFRAME
)+GetSystemMetrics(SM_CXEDGE
));
538 prect
->bottom
= wp
.rcNormalPosition
.bottom
-wp
.rcNormalPosition
.top
-
539 2*(GetSystemMetrics(SM_CYSIZEFRAME
)+GetSystemMetrics(SM_CYEDGE
))-
540 GetSystemMetrics(SM_CYCAPTION
)-GetSystemMetrics(SM_CYMENUSIZE
);
545 ResizeManager _resize_mgr
;
550 This class constructs button controls.
551 The button will remain existent when the C++ Button object is destroyed.
552 There is no conjunction between C++ object and windows control life time.
554 struct Button
: public WindowHandle
556 Button(HWND parent
, LPCTSTR text
, int left
, int top
, int width
, int height
,
557 int id
, DWORD flags
=WS_VISIBLE
|WS_CHILD
|BS_PUSHBUTTON
, DWORD exStyle
=0);
562 This class constructs static controls.
563 The control will remain existent when the C++ object is destroyed.
564 There is no conjunction between C++ object and windows control life time.
566 struct Static
: public WindowHandle
568 Static(HWND parent
, LPCTSTR text
, int left
, int top
, int width
, int height
,
569 int id
, DWORD flags
=WS_VISIBLE
|WS_CHILD
|SS_SIMPLE
, DWORD ex_flags
=0);
573 // control color message routing for ColorStatic and HyperlinkCtrl
575 #define PM_DISPATCH_CTLCOLOR (WM_APP+0x08)
577 template<typename BASE
> struct CtlColorParent
: public BASE
581 CtlColorParent(HWND hwnd
)
584 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
590 case WM_CTLCOLORSCROLLBAR
:
591 case WM_CTLCOLORSTATIC
: {
592 HWND hctl
= (HWND
) lparam
;
593 return SendMessage(hctl
, PM_DISPATCH_CTLCOLOR
, wparam
, nmsg
);
597 return super::WndProc(nmsg
, wparam
, lparam
);
603 #define PM_DISPATCH_DRAWITEM (WM_APP+0x09)
605 /// draw message routing for ColorButton and PictureButton
606 template<typename BASE
> struct OwnerDrawParent
: public BASE
610 OwnerDrawParent(HWND hwnd
)
613 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
617 if (wparam
) { // should there be drawn a control?
618 HWND hctl
= GetDlgItem(this->_hwnd
, wparam
);
621 return SendMessage(hctl
, PM_DISPATCH_DRAWITEM
, wparam
, lparam
);
622 } /*else // or is it a menu entry?
628 return super::WndProc(nmsg
, wparam
, lparam
);
635 Subclass button controls to draw them by using PM_DISPATCH_DRAWITEM
636 The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
638 struct OwnerdrawnButton
: public SubclassedWindow
640 typedef SubclassedWindow super
;
642 OwnerdrawnButton(HWND hwnd
)
646 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
648 virtual void DrawItem(LPDRAWITEMSTRUCT dis
) = 0;
651 extern void DrawGrayText(HDC hdc
, LPRECT pRect
, LPCTSTR text
, int dt_flags
);
655 Subclass button controls to paint colored text labels.
656 The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
659 struct ColorButton : public OwnerdrawnButton
661 typedef OwnerdrawnButton super;
663 ColorButton(HWND hwnd, COLORREF textColor)
664 : super(hwnd), _textColor(textColor) {}
667 virtual void DrawItem(LPDRAWITEMSTRUCT dis);
674 struct FlatButton
: public OwnerdrawnButton
676 typedef OwnerdrawnButton super
;
678 FlatButton(HWND hwnd
)
679 : super(hwnd
), _active(false) {}
681 FlatButton(HWND owner
, int id
)
682 : super(GetDlgItem(owner
, IDOK
)), _active(false) {}
685 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
686 virtual void DrawItem(LPDRAWITEMSTRUCT dis
);
689 COLORREF _activeColor
;
695 Subclass button controls to paint pictures left to the labels.
696 The buttons should have set the style bit BS_OWNERDRAW.
697 The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
699 struct PictureButton
: public OwnerdrawnButton
701 typedef OwnerdrawnButton super
;
703 PictureButton(HWND hwnd
, HICON hIcon
, HBRUSH hbrush
=GetSysColorBrush(COLOR_BTNFACE
), bool flat
=false)
704 : super(hwnd
), _hIcon(hIcon
), _hBmp(0), _hBrush(hbrush
), _flat(flat
)
710 PictureButton(HWND hparent
, int id
, HICON hIcon
, HBRUSH hbrush
=GetSysColorBrush(COLOR_BTNFACE
), bool flat
=false)
711 : super(GetDlgItem(hparent
, id
)), _hIcon(hIcon
), _hBmp(0), _hBrush(hbrush
), _flat(flat
)
717 PictureButton(HWND hwnd
, HBITMAP hBmp
, HBRUSH hbrush
=GetSysColorBrush(COLOR_BTNFACE
), bool flat
=false)
718 : super(hwnd
), _hIcon(0), _hBmp(hBmp
), _hBrush(hbrush
), _flat(flat
)
721 GetObject(hBmp
, sizeof(bmp
), &bmp
);
726 PictureButton(HWND hparent
, int id
, HBITMAP hBmp
, HBRUSH hbrush
=GetSysColorBrush(COLOR_BTNFACE
), bool flat
=false)
727 : super(GetDlgItem(hparent
, id
)), _hIcon(0), _hBmp(hBmp
), _hBrush(hbrush
), _flat(flat
)
730 GetObject(hBmp
, sizeof(bmp
), &bmp
);
736 virtual void DrawItem(LPDRAWITEMSTRUCT dis
);
749 struct ColorStatic
: public SubclassedWindow
751 typedef SubclassedWindow super
;
753 ColorStatic(HWND hwnd
, COLORREF textColor
=RGB(255,0,0), HBRUSH hbrush_bkgnd
=0, HFONT hfont
=0)
755 _textColor(textColor
),
756 _hbrush_bkgnd(hbrush_bkgnd
),
761 ColorStatic(HWND owner
, int id
, COLORREF textColor
=RGB(255,0,0), HBRUSH hbrush_bkgnd
=0, HFONT hfont
=0)
762 : super(GetDlgItem(owner
, id
)),
763 _textColor(textColor
),
764 _hbrush_bkgnd(hbrush_bkgnd
),
770 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
772 if (nmsg
== PM_DISPATCH_CTLCOLOR
) {
773 HDC hdc
= (HDC
) wparam
;
775 SetTextColor(hdc
, _textColor
);
778 SelectFont(hdc
, _hfont
);
781 return (LRESULT
)_hbrush_bkgnd
;
783 SetBkMode(hdc
, TRANSPARENT
);
784 return (LRESULT
)GetStockBrush(HOLLOW_BRUSH
);
787 return super::WndProc(nmsg
, wparam
, lparam
);
791 HBRUSH _hbrush_bkgnd
;
796 /// Hyperlink Controls
798 struct HyperlinkCtrl
: public SubclassedWindow
800 typedef SubclassedWindow super
;
802 HyperlinkCtrl(HWND hwnd
, COLORREF colorLink
=RGB(0,0,255), COLORREF colorVisited
=RGB(128,0,128));
803 HyperlinkCtrl(HWND owner
, int id
, COLORREF colorLink
=RGB(0,0,255), COLORREF colorVisited
=RGB(128,0,128));
811 COLORREF _colorVisited
;
815 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
822 HINSTANCE hinst
= ShellExecute(GetParent(_hwnd
), _T("open"), _cmd
, 0, 0, SW_SHOWNORMAL
);
823 return (int)hinst
> HINSTANCE_ERROR
;
831 /// encapsulation of tool tip controls
832 struct ToolTip
: public WindowHandle
834 typedef WindowHandle super
;
838 void activate(BOOL active
=TRUE
)
840 SendMessage(_hwnd
, TTM_ACTIVATE
, active
, 0);
843 void add(HWND hparent
, HWND htool
, LPCTSTR txt
=LPSTR_TEXTCALLBACK
, LPARAM lparam
=0)
846 sizeof(TOOLINFO
), TTF_SUBCLASS
|TTF_IDISHWND
|TTF_TRANSPARENT
, hparent
, (UINT
)htool
,
847 {0,0,0,0}, 0, (LPTSTR
)txt
, lparam
850 #ifdef UNICODE ///@todo Why is it neccesary to try both TTM_ADDTOOLW and TTM_ADDTOOLW ?!
851 if (!SendMessage(_hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&ti
))
852 SendMessage(_hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
854 if (!SendMessage(_hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
))
855 SendMessage(_hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&ti
);
859 void add(HWND hparent
, UINT id
, const RECT
& rect
, LPCTSTR txt
=LPSTR_TEXTCALLBACK
, LPARAM lparam
=0)
862 sizeof(TOOLINFO
), TTF_SUBCLASS
|TTF_TRANSPARENT
, hparent
, id
,
863 {rect
.left
,rect
.top
,rect
.right
,rect
.bottom
}, 0, (LPTSTR
)txt
, lparam
867 if (!SendMessage(_hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&ti
))
868 SendMessage(_hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
870 if (!SendMessage(_hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
))
871 SendMessage(_hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&ti
);
875 void remove(HWND hparent
, HWND htool
)
878 sizeof(TOOLINFO
), TTF_IDISHWND
, hparent
, (UINT
)htool
,
882 SendMessage(_hwnd
, TTM_DELTOOL
, 0, (LPARAM
)&ti
);
885 void remove(HWND hparent
, UINT id
)
888 sizeof(TOOLINFO
), 0, hparent
, id
,
892 SendMessage(_hwnd
, TTM_DELTOOL
, 0, (LPARAM
)&ti
);
897 inline int ListView_GetItemData(HWND list_ctrl
, int idx
)
901 item
.mask
= LVIF_PARAM
;
904 if (!ListView_GetItem(list_ctrl
, &item
))
910 inline int ListView_FindItemPara(HWND list_ctrl
, LPARAM param
)
914 fi
.flags
= LVFI_PARAM
;
917 return ListView_FindItem(list_ctrl
, (unsigned)-1, &fi
);
920 inline int ListView_GetFocusedItem(HWND list_ctrl
)
922 int idx
= ListView_GetItemCount(list_ctrl
);
925 if (ListView_GetItemState(list_ctrl
, idx
, LVIS_FOCUSED
))
932 /// sorting of list controls
933 struct ListSort
: public WindowHandle
935 ListSort(HWND hwndListview
, PFNLVCOMPARE compare_fct
);
937 void toggle_sort(int idx
);
944 PFNLVCOMPARE _compare_fct
;
946 static int CALLBACK
CompareFunc(LPARAM lparam1
, LPARAM lparam2
, LPARAM lparamSort
);
950 inline LPARAM
TreeView_GetItemData(HWND hwndTreeView
, HTREEITEM hItem
)
954 tvItem
.mask
= TVIF_PARAM
;
955 tvItem
.hItem
= hItem
;
957 if (!TreeView_GetItem(hwndTreeView
, &tvItem
))
960 return tvItem
.lParam
;
964 enum {TRAYBUTTON_LEFT
=0, TRAYBUTTON_RIGHT
, TRAYBUTTON_MIDDLE
};
966 #define PM_TRAYICON (WM_APP+0x20)
968 #define WINMSG_TASKBARCREATED TEXT("TaskbarCreated")
973 TrayIcon(HWND hparent
, UINT id
)
974 : _hparent(hparent
), _id(id
) {}
979 void Add(HICON hIcon
, LPCTSTR tooltip
=NULL
)
980 {Set(NIM_ADD
, _id
, hIcon
, tooltip
);}
982 void Modify(HICON hIcon
, LPCTSTR tooltip
=NULL
)
983 {Set(NIM_MODIFY
, _id
, hIcon
, tooltip
);}
987 NOTIFYICONDATA nid
= {
988 sizeof(NOTIFYICONDATA
), // cbSize
993 Shell_NotifyIcon(NIM_DELETE
, &nid
);
1000 void Set(DWORD dwMessage
, UINT id
, HICON hIcon
, LPCTSTR tooltip
=NULL
)
1002 NOTIFYICONDATA nid
= {
1003 sizeof(NOTIFYICONDATA
), // cbSize
1006 NIF_MESSAGE
|NIF_ICON
, // uFlags
1007 PM_TRAYICON
, // uCallbackMessage
1012 lstrcpyn(nid
.szTip
, tooltip
, COUNTOF(nid
.szTip
));
1015 nid
.uFlags
|= NIF_TIP
;
1017 Shell_NotifyIcon(dwMessage
, &nid
);
1022 template<typename BASE
> struct TrayIconControllerTemplate
: public BASE
1026 TrayIconControllerTemplate(HWND hwnd
) : BASE(hwnd
),
1027 WM_TASKBARCREATED(RegisterWindowMessage(WINMSG_TASKBARCREATED
))
1031 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
1033 if (nmsg
== PM_TRAYICON
) {
1036 TrayMouseOver(wparam
);
1039 case WM_LBUTTONDOWN
:
1040 TrayClick(wparam
, TRAYBUTTON_LEFT
);
1043 case WM_LBUTTONDBLCLK
:
1044 TrayDblClick(wparam
, TRAYBUTTON_LEFT
);
1047 case WM_RBUTTONDOWN
:
1048 TrayClick(wparam
, TRAYBUTTON_RIGHT
);
1051 case WM_RBUTTONDBLCLK
:
1052 TrayDblClick(wparam
, TRAYBUTTON_RIGHT
);
1055 case WM_MBUTTONDOWN
:
1056 TrayClick(wparam
, TRAYBUTTON_MIDDLE
);
1059 case WM_MBUTTONDBLCLK
:
1060 TrayDblClick(wparam
, TRAYBUTTON_MIDDLE
);
1065 } else if (nmsg
== WM_TASKBARCREATED
) {
1069 return super::WndProc(nmsg
, wparam
, lparam
);
1072 virtual void AddTrayIcons() = 0;
1073 virtual void TrayMouseOver(UINT id
) {}
1074 virtual void TrayClick(UINT id
, int btn
) {}
1075 virtual void TrayDblClick(UINT id
, int btn
) {}
1078 const UINT WM_TASKBARCREATED
;
1082 struct EditController
: public SubclassedWindow
1084 typedef SubclassedWindow super
;
1086 EditController(HWND hwnd
)
1092 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
1094 if (nmsg
==WM_KEYDOWN
&& wparam
==VK_RETURN
) {
1095 SendParent(WM_COMMAND
, MAKEWPARAM(GetDlgCtrlID(_hwnd
),1), (LPARAM
)_hwnd
);
1098 return super::WndProc(nmsg
, wparam
, lparam
);