1c2c66affSColin Finck /*
2c2c66affSColin Finck * Copyright 2003, 2004, 2005 Martin Fuchs
3c2c66affSColin Finck *
4c2c66affSColin Finck * This library is free software; you can redistribute it and/or
5c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
6c2c66affSColin Finck * License as published by the Free Software Foundation; either
7c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
8c2c66affSColin Finck *
9c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
10c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12c2c66affSColin Finck * Lesser General Public License for more details.
13c2c66affSColin Finck *
14c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
15c2c66affSColin Finck * License along with this library; if not, write to the Free Software
16c2c66affSColin Finck * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17c2c66affSColin Finck */
18c2c66affSColin Finck
19c2c66affSColin Finck
20c2c66affSColin Finck //
21c2c66affSColin Finck // Explorer clone
22c2c66affSColin Finck //
23c2c66affSColin Finck // window.h
24c2c66affSColin Finck //
25c2c66affSColin Finck // Martin Fuchs, 23.07.2003
26c2c66affSColin Finck //
27c2c66affSColin Finck
28c2c66affSColin Finck
29c2c66affSColin Finck typedef set<HWND> WindowSet;
30c2c66affSColin Finck
31c2c66affSColin Finck
32c2c66affSColin Finck /*
33c2c66affSColin Finck Classes are declared using "struct", not "class" because the default
34c2c66affSColin Finck access mode is "public". This way we can list the member functions in a
35c2c66affSColin Finck natural order without explicitly specifying any access mode at the begin
36c2c66affSColin Finck of the definition.
37c2c66affSColin Finck First are public constructors and destructor, then public member functions.
38c2c66affSColin Finck After that we list protected member varibables and functions. If needed,
39c2c66affSColin Finck private implemenation varibales and functions are positioned at the end.
40c2c66affSColin Finck */
41c2c66affSColin Finck
42c2c66affSColin Finck
43c2c66affSColin Finck /// information structure for creation of a MDI child window
44c2c66affSColin Finck struct ChildWndInfo
45c2c66affSColin Finck {
ChildWndInfoChildWndInfo46c2c66affSColin Finck ChildWndInfo(HWND hmdiclient)
47c2c66affSColin Finck : _hmdiclient(hmdiclient) {}
48c2c66affSColin Finck
49c2c66affSColin Finck HWND _hmdiclient;
50c2c66affSColin Finck };
51c2c66affSColin Finck
52c2c66affSColin Finck
53c2c66affSColin Finck /**
54c2c66affSColin Finck Class Window is the base class for several C++ window wrapper classes.
55c2c66affSColin Finck Window objects are allocated from the heap. They are automatically freed
56c2c66affSColin Finck when the window gets destroyed.
57c2c66affSColin Finck */
58c2c66affSColin Finck struct Window : public WindowHandle
59c2c66affSColin Finck {
60c2c66affSColin Finck Window(HWND hwnd);
61c2c66affSColin Finck virtual ~Window();
62c2c66affSColin Finck
63c2c66affSColin Finck
64c2c66affSColin Finck typedef map<HWND,Window*> WindowMap;
65c2c66affSColin Finck
66c2c66affSColin Finck typedef Window* (*CREATORFUNC)(HWND);
67c2c66affSColin Finck typedef Window* (*CREATORFUNC_INFO)(HWND, const void*);
68c2c66affSColin Finck
69c2c66affSColin Finck static HWND Create(CREATORFUNC creator,
70c2c66affSColin Finck DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName,
71c2c66affSColin Finck DWORD dwStyle, int x, int y, int w, int h,
72c2c66affSColin Finck HWND hwndParent=0, HMENU hMenu=0/*, LPVOID lpParam=0*/);
73c2c66affSColin Finck
74c2c66affSColin Finck static HWND Create(CREATORFUNC_INFO creator, const void* info,
75c2c66affSColin Finck DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName,
76c2c66affSColin Finck DWORD dwStyle, int x, int y, int w, int h,
77c2c66affSColin Finck HWND hwndParent=0, HMENU hMenu=0/*, LPVOID lpParam=0*/);
78c2c66affSColin Finck
79c2c66affSColin Finck static Window* create_mdi_child(const ChildWndInfo& info, const MDICREATESTRUCT& mcs, CREATORFUNC_INFO creator);
80c2c66affSColin Finck // static Window* create_property_sheet(struct PropertySheetDialog* ppsd, CREATORFUNC creator, const void* info);
81c2c66affSColin Finck
82c2c66affSColin Finck static LRESULT CALLBACK WindowWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
83c2c66affSColin Finck static INT_PTR CALLBACK DialogProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
84c2c66affSColin Finck
85c2c66affSColin Finck static Window* get_window(HWND hwnd);
86c2c66affSColin Finck #ifndef _MSC_VER
get_windowWindow87c2c66affSColin Finck template<typename CLASS> static CLASS* get_window(HWND hwnd) {return static_cast<CLASS*>(get_window(hwnd));}
88c2c66affSColin Finck #define GET_WINDOW(CLASS, hwnd) Window::get_window<CLASS>(hwnd)
89c2c66affSColin Finck #endif
90c2c66affSColin Finck
91c2c66affSColin Finck static void register_pretranslate(HWND hwnd);
92c2c66affSColin Finck static void unregister_pretranslate(HWND hwnd);
93c2c66affSColin Finck static BOOL pretranslate_msg(LPMSG pmsg);
94c2c66affSColin Finck
95c2c66affSColin Finck static void register_dialog(HWND hwnd);
96c2c66affSColin Finck static void unregister_dialog(HWND hwnd);
97c2c66affSColin Finck static BOOL dispatch_dialog_msg(LPMSG pmsg);
98c2c66affSColin Finck
99c2c66affSColin Finck static int MessageLoop();
100c2c66affSColin Finck
101c2c66affSColin Finck
102c2c66affSColin Finck LRESULT SendParent(UINT nmsg, WPARAM wparam=0, LPARAM lparam=0);
103c2c66affSColin Finck LRESULT PostParent(UINT nmsg, WPARAM wparam=0, LPARAM lparam=0);
104c2c66affSColin Finck
105c2c66affSColin Finck static void CancelModes();
106c2c66affSColin Finck
107c2c66affSColin Finck
108c2c66affSColin Finck protected:
109c2c66affSColin Finck virtual LRESULT Init(LPCREATESTRUCT pcs); // WM_CREATE processing
110c2c66affSColin Finck virtual LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
111c2c66affSColin Finck virtual int Command(int id, int code); // WM_COMMAND processing
112c2c66affSColin Finck virtual int Notify(int id, NMHDR* pnmh); // WM_NOTIFY processing
113c2c66affSColin Finck
114c2c66affSColin Finck static Window* create_controller(HWND hwnd);
115c2c66affSColin Finck
116c2c66affSColin Finck
117c2c66affSColin Finck static WindowMap s_wnd_map;
118c2c66affSColin Finck
119c2c66affSColin Finck static const void* s_new_info;
120c2c66affSColin Finck static CREATORFUNC s_window_creator;
121c2c66affSColin Finck
122c2c66affSColin Finck
123c2c66affSColin Finck /// structure for managing critical sections as static class information in struct Window
124c2c66affSColin Finck struct StaticWindowData {
125c2c66affSColin Finck CritSect _map_crit_sect;
126c2c66affSColin Finck CritSect _create_crit_sect;
127c2c66affSColin Finck };
128c2c66affSColin Finck
129c2c66affSColin Finck static StaticWindowData& GetStaticWindowData();
130c2c66affSColin Finck
131c2c66affSColin Finck
132c2c66affSColin Finck // MDI child creation
133c2c66affSColin Finck static HHOOK s_hcbtHook;
134c2c66affSColin Finck static LRESULT CALLBACK MDICBTHookProc(int code, WPARAM wparam, LPARAM lparam);
135c2c66affSColin Finck static LRESULT CALLBACK PropSheetCBTHookProc(int code, WPARAM wparam, LPARAM lparam);
136c2c66affSColin Finck
137c2c66affSColin Finck static WindowSet s_pretranslate_windows;
138c2c66affSColin Finck static WindowSet s_dialogs;
139c2c66affSColin Finck };
140c2c66affSColin Finck
141c2c66affSColin Finck #ifdef UNICODE
142c2c66affSColin Finck #define NFR_CURRENT NFR_UNICODE
143c2c66affSColin Finck #else
144c2c66affSColin Finck #define NFR_CURRENT NFR_ANSI
145c2c66affSColin Finck #endif
146c2c66affSColin Finck
147c2c66affSColin Finck
148c2c66affSColin Finck #ifdef _MSC_VER
149c2c66affSColin Finck template<typename CLASS> struct GetWindowHelper
150c2c66affSColin Finck {
get_windowGetWindowHelper151c2c66affSColin Finck static CLASS* get_window(HWND hwnd) {
152c2c66affSColin Finck return static_cast<CLASS*>(Window::get_window(hwnd));
153c2c66affSColin Finck }
154c2c66affSColin Finck };
155c2c66affSColin Finck #define GET_WINDOW(CLASS, hwnd) GetWindowHelper<CLASS>::get_window(hwnd)
156c2c66affSColin Finck #endif
157c2c66affSColin Finck
158c2c66affSColin Finck
159c2c66affSColin Finck /// dynamic casting of Window pointers
160c2c66affSColin Finck template<typename CLASS> struct TypeCheck
161c2c66affSColin Finck {
dyn_castTypeCheck162c2c66affSColin Finck static CLASS* dyn_cast(Window* wnd)
163c2c66affSColin Finck {return dynamic_cast<CLASS*>(wnd);}
164c2c66affSColin Finck };
165c2c66affSColin Finck
166c2c66affSColin Finck #define WINDOW_DYNAMIC_CAST(CLASS, hwnd) \
167c2c66affSColin Finck TypeCheck<CLASS>::dyn_cast(Window::get_window(hwnd))
168c2c66affSColin Finck
169c2c66affSColin Finck
170c2c66affSColin Finck /**
171c2c66affSColin Finck SubclassedWindow is used to wrap already existing window handles
172c2c66affSColin Finck into C++ Window objects. To construct a object, use the "new" operator
173c2c66affSColin Finck to put it in the heap. It is automatically freed, when the window
174c2c66affSColin Finck gets destroyed.
175c2c66affSColin Finck */
176c2c66affSColin Finck struct SubclassedWindow : public Window
177c2c66affSColin Finck {
178c2c66affSColin Finck typedef Window super;
179c2c66affSColin Finck
180c2c66affSColin Finck SubclassedWindow(HWND);
181c2c66affSColin Finck
182c2c66affSColin Finck protected:
183c2c66affSColin Finck WNDPROC _orgWndProc;
184c2c66affSColin Finck
185c2c66affSColin Finck static LRESULT CALLBACK SubclassedWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
186c2c66affSColin Finck
187c2c66affSColin Finck virtual LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
188c2c66affSColin Finck virtual int Command(int id, int code);
189c2c66affSColin Finck virtual int Notify(int id, NMHDR* pnmh);
190c2c66affSColin Finck };
191c2c66affSColin Finck
192c2c66affSColin Finck
193c2c66affSColin Finck /// template class used in macro WINDOW_CREATOR to define the creater functions for Window objects
194c2c66affSColin Finck template<typename WND_CLASS> struct WindowCreator
195c2c66affSColin Finck {
window_creatorWindowCreator196c2c66affSColin Finck static WND_CLASS* window_creator(HWND hwnd)
197c2c66affSColin Finck {
198c2c66affSColin Finck return new WND_CLASS(hwnd);
199c2c66affSColin Finck }
200c2c66affSColin Finck };
201c2c66affSColin Finck
202c2c66affSColin Finck #define WINDOW_CREATOR(WND_CLASS) \
203c2c66affSColin Finck ((Window::CREATORFUNC) WindowCreator<WND_CLASS>::window_creator)
204c2c66affSColin Finck
205c2c66affSColin Finck
206c2c66affSColin Finck /// template class used in macro WINDOW_CREATOR_INFO to the define creater functions for Window objects with additional creation information
207c2c66affSColin Finck template<typename WND_CLASS, typename INFO_CLASS> struct WindowCreatorInfo
208c2c66affSColin Finck {
window_creatorWindowCreatorInfo209c2c66affSColin Finck static WND_CLASS* window_creator(HWND hwnd, const void* info)
210c2c66affSColin Finck {
211c2c66affSColin Finck return new WND_CLASS(hwnd, *static_cast<const INFO_CLASS*>(info));
212c2c66affSColin Finck }
213c2c66affSColin Finck };
214c2c66affSColin Finck
215c2c66affSColin Finck #define WINDOW_CREATOR_INFO(WND_CLASS, INFO_CLASS) \
216c2c66affSColin Finck ((Window::CREATORFUNC_INFO) WindowCreatorInfo<WND_CLASS, INFO_CLASS>::window_creator)
217c2c66affSColin Finck
218c2c66affSColin Finck
219c2c66affSColin Finck /**
220c2c66affSColin Finck WindowClass is a neat wrapper for RegisterClassEx().
221c2c66affSColin Finck Just construct a WindowClass object, override the attributes you want
222c2c66affSColin Finck to change, then call Register() or simply request the ATOM value to
223c2c66affSColin Finck register the window class. You don't have to worry calling Register()
224c2c66affSColin Finck more than once. It checks if, the class has already been registered.
225c2c66affSColin Finck */
226c2c66affSColin Finck struct WindowClass : public WNDCLASSEX
227c2c66affSColin Finck {
228c2c66affSColin Finck WindowClass(LPCTSTR classname, UINT style=0, WNDPROC wndproc=Window::WindowWndProc);
229c2c66affSColin Finck
RegisterWindowClass230c2c66affSColin Finck ATOM Register()
231c2c66affSColin Finck {
232c2c66affSColin Finck if (!_atomClass)
233c2c66affSColin Finck _atomClass = RegisterClassEx(this);
234c2c66affSColin Finck
235c2c66affSColin Finck return _atomClass;
236c2c66affSColin Finck }
237c2c66affSColin Finck
ATOMWindowClass238c2c66affSColin Finck operator ATOM() {return Register();}
239c2c66affSColin Finck
240c2c66affSColin Finck // return LPCTSTR for the CreateWindowEx() parameter
LPCTSTRWindowClass241c2c66affSColin Finck operator LPCTSTR() {return (LPCTSTR)(int)Register();}
242c2c66affSColin Finck
243c2c66affSColin Finck protected:
244c2c66affSColin Finck ATOM _atomClass;
245c2c66affSColin Finck };
246c2c66affSColin Finck
247c2c66affSColin Finck /// window class with gray background color
248c2c66affSColin Finck struct BtnWindowClass : public WindowClass
249c2c66affSColin Finck {
250c2c66affSColin Finck BtnWindowClass(LPCTSTR classname, UINT style=0, WNDPROC wndproc=Window::WindowWndProc)
WindowClassBtnWindowClass251c2c66affSColin Finck : WindowClass(classname, style, wndproc)
252c2c66affSColin Finck {
253c2c66affSColin Finck hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
254c2c66affSColin Finck }
255c2c66affSColin Finck };
256c2c66affSColin Finck
257c2c66affSColin Finck /// window class with specified icon from resources
258c2c66affSColin Finck struct IconWindowClass : public WindowClass
259c2c66affSColin Finck {
260c2c66affSColin Finck IconWindowClass(LPCTSTR classname, UINT nid, UINT style=0, WNDPROC wndproc=Window::WindowWndProc);
261c2c66affSColin Finck };
262c2c66affSColin Finck
263c2c66affSColin Finck
264c2c66affSColin Finck // private message constants
265c2c66affSColin Finck #define PM_DISPATCH_COMMAND (WM_APP+0x00)
266c2c66affSColin Finck #define PM_TRANSLATE_MSG (WM_APP+0x01)
267c2c66affSColin Finck
268c2c66affSColin Finck
269c2c66affSColin Finck #define SPLIT_WIDTH 5
270c2c66affSColin Finck #define DEFAULT_SPLIT_POS 300
271c2c66affSColin Finck #define COLOR_SPLITBAR LTGRAY_BRUSH
272c2c66affSColin Finck
273c2c66affSColin Finck
274c2c66affSColin Finck /// menu info structure
275c2c66affSColin Finck struct MenuInfo
276c2c66affSColin Finck {
277c2c66affSColin Finck HMENU _hMenuView;
278c2c66affSColin Finck };
279c2c66affSColin Finck
280c2c66affSColin Finck #define PM_FRM_GET_MENUINFO (WM_APP+0x02)
281c2c66affSColin Finck
282c2c66affSColin Finck #define Frame_GetMenuInfo(hwnd) ((MenuInfo*)SNDMSG(hwnd, PM_FRM_GET_MENUINFO, 0, 0))
283c2c66affSColin Finck
284c2c66affSColin Finck
285c2c66affSColin Finck /**
286c2c66affSColin Finck PreTranslateWindow is used to register windows to be called by Window::pretranslate_msg().
287c2c66affSColin Finck This way you get PM_TRANSLATE_MSG messages before the message loop dispatches messages.
288c2c66affSColin Finck You can then for example use TranslateAccelerator() to implement key shortcuts.
289c2c66affSColin Finck */
290c2c66affSColin Finck struct PreTranslateWindow : public Window
291c2c66affSColin Finck {
292c2c66affSColin Finck typedef Window super;
293c2c66affSColin Finck
294c2c66affSColin Finck PreTranslateWindow(HWND);
295c2c66affSColin Finck ~PreTranslateWindow();
296c2c66affSColin Finck };
297c2c66affSColin Finck
298c2c66affSColin Finck
299c2c66affSColin Finck
300c2c66affSColin Finck /**
301c2c66affSColin Finck Class ChildWindow represents MDI child windows.
302c2c66affSColin Finck It is used with class MainFrame.
303c2c66affSColin Finck */
304c2c66affSColin Finck struct ChildWindow : public PreTranslateWindow
305c2c66affSColin Finck {
306c2c66affSColin Finck typedef PreTranslateWindow super;
307c2c66affSColin Finck
308c2c66affSColin Finck ChildWindow(HWND hwnd, const ChildWndInfo& info);
309c2c66affSColin Finck
310c2c66affSColin Finck static ChildWindow* create(const ChildWndInfo& info, const RECT& rect, CREATORFUNC_INFO creator,
311c2c66affSColin Finck LPCTSTR classname, LPCTSTR title=NULL, DWORD style=0);
312c2c66affSColin Finck
313c2c66affSColin Finck bool go_to(LPCTSTR url);
314c2c66affSColin Finck
315c2c66affSColin Finck protected:
316c2c66affSColin Finck LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
317c2c66affSColin Finck
318c2c66affSColin Finck virtual void resize_children(int cx, int cy);
319c2c66affSColin Finck virtual String jump_to_int(LPCTSTR url) = 0;
320c2c66affSColin Finck
321c2c66affSColin Finck protected:
322c2c66affSColin Finck MenuInfo*_menu_info;
323c2c66affSColin Finck
324c2c66affSColin Finck WindowHandle _left_hwnd;
325c2c66affSColin Finck WindowHandle _right_hwnd;
326c2c66affSColin Finck int _focus_pane; // 0: left 1: right
327c2c66affSColin Finck
328c2c66affSColin Finck int _split_pos;
329c2c66affSColin Finck int _last_split;
330c2c66affSColin Finck
331c2c66affSColin Finck HWND _hwndFrame;
332c2c66affSColin Finck String _statusText;
333c2c66affSColin Finck String _url;
334c2c66affSColin Finck
335c2c66affSColin Finck stack<String> _url_history;
336c2c66affSColin Finck
337c2c66affSColin Finck void set_url(LPCTSTR url);
338c2c66affSColin Finck };
339c2c66affSColin Finck
340c2c66affSColin Finck #define PM_SETSTATUSTEXT (WM_APP+0x1E)
341c2c66affSColin Finck
342c2c66affSColin Finck
343c2c66affSColin Finck /**
344c2c66affSColin Finck The class DialogWindow implements modeless dialogs, which are managed by
345c2c66affSColin Finck Window::dispatch_dialog_msg() in Window::MessageLoop().
346c2c66affSColin Finck A DialogWindow object should be constructed by calling Window::Create()
347c2c66affSColin Finck and specifying the class using the WINDOW_CREATOR() macro.
348c2c66affSColin Finck */
349c2c66affSColin Finck struct DialogWindow : public Window
350c2c66affSColin Finck {
351c2c66affSColin Finck typedef Window super;
352c2c66affSColin Finck
DialogWindowDialogWindow353c2c66affSColin Finck DialogWindow(HWND hwnd)
354c2c66affSColin Finck : super(hwnd)
355c2c66affSColin Finck {
356c2c66affSColin Finck register_dialog(hwnd);
357c2c66affSColin Finck }
358c2c66affSColin Finck
~DialogWindowDialogWindow359c2c66affSColin Finck ~DialogWindow()
360c2c66affSColin Finck {
361c2c66affSColin Finck unregister_dialog(_hwnd);
362c2c66affSColin Finck }
363c2c66affSColin Finck };
364c2c66affSColin Finck
365c2c66affSColin Finck
366c2c66affSColin Finck /**
367c2c66affSColin Finck The class Dialog implements modal dialogs.
368c2c66affSColin Finck A Dialog object should be constructed by calling Dialog::DoModal()
369c2c66affSColin Finck and specifying the class using the WINDOW_CREATOR() macro.
370c2c66affSColin Finck */
371c2c66affSColin Finck struct Dialog : public Window
372c2c66affSColin Finck {
373c2c66affSColin Finck typedef Window super;
374c2c66affSColin Finck
375c2c66affSColin Finck Dialog(HWND);
376c2c66affSColin Finck ~Dialog();
377c2c66affSColin Finck
378c2c66affSColin Finck static int DoModal(UINT nid, CREATORFUNC creator, HWND hwndParent=0);
379c2c66affSColin Finck static int DoModal(UINT nid, CREATORFUNC_INFO creator, const void* info, HWND hwndParent=0);
380c2c66affSColin Finck
381c2c66affSColin Finck protected:
382c2c66affSColin Finck LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
383c2c66affSColin Finck int Command(int id, int code);
384c2c66affSColin Finck };
385c2c66affSColin Finck
386c2c66affSColin Finck
387c2c66affSColin Finck #define PM_FRM_CALC_CLIENT (WM_APP+0x03)
388c2c66affSColin Finck #define Frame_CalcFrameClient(hwnd, prt) ((BOOL)SNDMSG(hwnd, PM_FRM_CALC_CLIENT, 0, (LPARAM)(PRECT)prt))
389c2c66affSColin Finck
390c2c66affSColin Finck #define PM_JUMP_TO_URL (WM_APP+0x25)
391c2c66affSColin Finck #define PM_URL_CHANGED (WM_APP+0x26)
392c2c66affSColin Finck
393c2c66affSColin Finck
394c2c66affSColin Finck struct PropSheetPage : public PROPSHEETPAGE
395c2c66affSColin Finck {
396c2c66affSColin Finck PropSheetPage(UINT nid, Window::CREATORFUNC dlg_creator);
397c2c66affSColin Finck
398c2c66affSColin Finck void init(struct PropertySheetDialog*);
399c2c66affSColin Finck
400c2c66affSColin Finck protected:
401c2c66affSColin Finck friend struct PropSheetPageDlg;
402c2c66affSColin Finck
403c2c66affSColin Finck Window::CREATORFUNC _dlg_creator;
404c2c66affSColin Finck };
405c2c66affSColin Finck
406c2c66affSColin Finck
407c2c66affSColin Finck /// Property Sheet dialog
408c2c66affSColin Finck struct PropertySheetDialog : public PROPSHEETHEADER
409c2c66affSColin Finck {
410c2c66affSColin Finck PropertySheetDialog(HWND owner);
411c2c66affSColin Finck
412c2c66affSColin Finck void add(PropSheetPage& psp);
413c2c66affSColin Finck int DoModal(int start_page=0);
414c2c66affSColin Finck
415c2c66affSColin Finck HWND GetCurrentPage();
416c2c66affSColin Finck
417c2c66affSColin Finck protected:
418c2c66affSColin Finck typedef vector<PROPSHEETPAGE> Vector;
419c2c66affSColin Finck Vector _pages;
420c2c66affSColin Finck HWND _hwnd;
421c2c66affSColin Finck };
422c2c66affSColin Finck
423c2c66affSColin Finck
424c2c66affSColin Finck /// Property Sheet Page (inner dialog)
425c2c66affSColin Finck struct PropSheetPageDlg : public Dialog
426c2c66affSColin Finck {
427c2c66affSColin Finck typedef Dialog super;
428c2c66affSColin Finck
429c2c66affSColin Finck PropSheetPageDlg(HWND);
430c2c66affSColin Finck
431c2c66affSColin Finck protected:
432c2c66affSColin Finck friend struct PropertySheetDialog;
433c2c66affSColin Finck friend struct PropSheetPage;
434c2c66affSColin Finck
435c2c66affSColin Finck static INT_PTR CALLBACK DialogProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
436c2c66affSColin Finck
437c2c66affSColin Finck int Command(int id, int code);
438c2c66affSColin Finck };
439c2c66affSColin Finck
440c2c66affSColin Finck
441c2c66affSColin Finck /*
442c2c66affSColin Finck /// Property Sheet Dialog (outer dialog)
443c2c66affSColin Finck struct PropertySheetDlg : public SubclassedWindow
444c2c66affSColin Finck {
445c2c66affSColin Finck typedef SubclassedWindow super;
446c2c66affSColin Finck
447c2c66affSColin Finck PropertySheetDlg(HWND hwnd) : super(hwnd) {}
448c2c66affSColin Finck };
449c2c66affSColin Finck */
450c2c66affSColin Finck
451c2c66affSColin Finck
452c2c66affSColin Finck // Layouting of resizable windows
453c2c66affSColin Finck
454c2c66affSColin Finck /// Flags to specify how to move and resize controls when resizing their parent window
455c2c66affSColin Finck enum RESIZE_FLAGS {
456c2c66affSColin Finck MOVE_LEFT = 0x1,
457c2c66affSColin Finck MOVE_RIGHT = 0x2,
458c2c66affSColin Finck MOVE_TOP = 0x4,
459c2c66affSColin Finck MOVE_BOTTOM = 0x8,
460c2c66affSColin Finck
461c2c66affSColin Finck MOVE_X = MOVE_LEFT | MOVE_RIGHT,
462c2c66affSColin Finck MOVE_Y = MOVE_TOP | MOVE_BOTTOM,
463c2c66affSColin Finck RESIZE_X= MOVE_RIGHT,
464c2c66affSColin Finck RESIZE_Y= MOVE_BOTTOM,
465c2c66affSColin Finck
466c2c66affSColin Finck MOVE = MOVE_X | MOVE_Y,
467c2c66affSColin Finck RESIZE = RESIZE_X | RESIZE_Y
468c2c66affSColin Finck };
469c2c66affSColin Finck
470c2c66affSColin Finck /// structure to assign RESIZE_FLAGS to dialogs control
471c2c66affSColin Finck struct ResizeEntry
472c2c66affSColin Finck {
ResizeEntryResizeEntry473c2c66affSColin Finck ResizeEntry(UINT id, int flags)
474c2c66affSColin Finck : _id(id), _flags(flags) {}
475c2c66affSColin Finck
ResizeEntryResizeEntry476c2c66affSColin Finck ResizeEntry(HWND hwnd, int flags)
477c2c66affSColin Finck : _id(GetDlgCtrlID(hwnd)), _flags(flags) {}
478c2c66affSColin Finck
479c2c66affSColin Finck UINT _id;
480c2c66affSColin Finck int _flags;
481c2c66affSColin Finck };
482c2c66affSColin Finck
483c2c66affSColin Finck
484c2c66affSColin Finck /// Management of controls in resizable dialogs
485c2c66affSColin Finck struct ResizeManager : public std::list<ResizeEntry>
486c2c66affSColin Finck {
487c2c66affSColin Finck typedef std::list<ResizeEntry> super;
488c2c66affSColin Finck
489c2c66affSColin Finck ResizeManager(HWND hwnd);
490c2c66affSColin Finck
AddResizeManager491c2c66affSColin Finck void Add(UINT id, int flags)
492c2c66affSColin Finck {push_back(ResizeEntry(id, flags));}
493c2c66affSColin Finck
AddResizeManager494c2c66affSColin Finck void Add(HWND hwnd, int flags)
495c2c66affSColin Finck {push_back(ResizeEntry(hwnd, flags));}
496c2c66affSColin Finck
497c2c66affSColin Finck void HandleSize(int cx, int cy);
498c2c66affSColin Finck void Resize(int dx, int dy);
499c2c66affSColin Finck
SetMinMaxInfoResizeManager500c2c66affSColin Finck void SetMinMaxInfo(LPMINMAXINFO lpmmi)
501c2c66affSColin Finck {
502c2c66affSColin Finck lpmmi->ptMinTrackSize.x = _min_wnd_size.cx;
503c2c66affSColin Finck lpmmi->ptMinTrackSize.y = _min_wnd_size.cy;
504c2c66affSColin Finck }
505c2c66affSColin Finck
506c2c66affSColin Finck SIZE _min_wnd_size;
507c2c66affSColin Finck
508c2c66affSColin Finck protected:
509c2c66affSColin Finck HWND _hwnd;
510c2c66affSColin Finck SIZE _last_size;
511c2c66affSColin Finck };
512c2c66affSColin Finck
513c2c66affSColin Finck
514c2c66affSColin Finck /// Controller base template class for resizable dialogs
515c2c66affSColin Finck template<typename BASE> struct ResizeController : public BASE
516c2c66affSColin Finck {
517c2c66affSColin Finck typedef BASE super;
518c2c66affSColin Finck
ResizeControllerResizeController519c2c66affSColin Finck ResizeController(HWND hwnd)
520c2c66affSColin Finck : super(hwnd),
521c2c66affSColin Finck _resize_mgr(hwnd)
522c2c66affSColin Finck {
523c2c66affSColin Finck }
524c2c66affSColin Finck
WndProcResizeController525c2c66affSColin Finck LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
526c2c66affSColin Finck {
527c2c66affSColin Finck switch(nmsg) {
528c2c66affSColin Finck case PM_FRM_CALC_CLIENT:
529c2c66affSColin Finck GetClientSpace((PRECT)lparam);
530c2c66affSColin Finck return TRUE;
531c2c66affSColin Finck
532c2c66affSColin Finck case WM_SIZE:
533c2c66affSColin Finck if (wparam != SIZE_MINIMIZED)
534c2c66affSColin Finck _resize_mgr.HandleSize(LOWORD(lparam), HIWORD(lparam));
535c2c66affSColin Finck goto def;
536c2c66affSColin Finck
537c2c66affSColin Finck case WM_GETMINMAXINFO:
538c2c66affSColin Finck _resize_mgr.SetMinMaxInfo((LPMINMAXINFO)lparam);
539c2c66affSColin Finck goto def;
540c2c66affSColin Finck
541c2c66affSColin Finck default: def:
542c2c66affSColin Finck return super::WndProc(nmsg, wparam, lparam);
543c2c66affSColin Finck }
544c2c66affSColin Finck }
545c2c66affSColin Finck
GetClientSpaceResizeController546c2c66affSColin Finck virtual void GetClientSpace(PRECT prect)
547c2c66affSColin Finck {
548c2c66affSColin Finck if (!IsIconic(this->_hwnd)) {
549c2c66affSColin Finck GetClientRect(this->_hwnd, prect);
550c2c66affSColin Finck } else {
551c2c66affSColin Finck WINDOWPLACEMENT wp;
552c2c66affSColin Finck GetWindowPlacement(this->_hwnd, &wp);
553c2c66affSColin Finck prect->left = prect->top = 0;
554c2c66affSColin Finck prect->right = wp.rcNormalPosition.right-wp.rcNormalPosition.left-
555c2c66affSColin Finck 2*(GetSystemMetrics(SM_CXSIZEFRAME)+GetSystemMetrics(SM_CXEDGE));
556c2c66affSColin Finck prect->bottom = wp.rcNormalPosition.bottom-wp.rcNormalPosition.top-
557c2c66affSColin Finck 2*(GetSystemMetrics(SM_CYSIZEFRAME)+GetSystemMetrics(SM_CYEDGE))-
558c2c66affSColin Finck GetSystemMetrics(SM_CYCAPTION)-GetSystemMetrics(SM_CYMENUSIZE);
559c2c66affSColin Finck }
560c2c66affSColin Finck }
561c2c66affSColin Finck
562c2c66affSColin Finck protected:
563c2c66affSColin Finck ResizeManager _resize_mgr;
564c2c66affSColin Finck };
565c2c66affSColin Finck
566c2c66affSColin Finck
567c2c66affSColin Finck /**
568c2c66affSColin Finck This class constructs button controls.
569c2c66affSColin Finck The button will remain existent when the C++ Button object is destroyed.
570c2c66affSColin Finck There is no conjunction between C++ object and windows control life time.
571c2c66affSColin Finck */
572c2c66affSColin Finck struct Button : public WindowHandle
573c2c66affSColin Finck {
574c2c66affSColin Finck Button(HWND parent, LPCTSTR text, int left, int top, int width, int height,
575c2c66affSColin Finck int id, DWORD flags=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON, DWORD exStyle=0);
576c2c66affSColin Finck };
577c2c66affSColin Finck
578c2c66affSColin Finck
579c2c66affSColin Finck /**
580c2c66affSColin Finck This class constructs static controls.
581c2c66affSColin Finck The control will remain existent when the C++ object is destroyed.
582c2c66affSColin Finck There is no conjunction between C++ object and windows control life time.
583c2c66affSColin Finck */
584c2c66affSColin Finck struct Static : public WindowHandle
585c2c66affSColin Finck {
586c2c66affSColin Finck Static(HWND parent, LPCTSTR text, int left, int top, int width, int height,
587c2c66affSColin Finck int id, DWORD flags=WS_VISIBLE|WS_CHILD|SS_SIMPLE, DWORD ex_flags=0);
588c2c66affSColin Finck };
589c2c66affSColin Finck
590c2c66affSColin Finck
591c2c66affSColin Finck // control color message routing for ColorStatic and HyperlinkCtrl
592c2c66affSColin Finck
593c2c66affSColin Finck #define PM_DISPATCH_CTLCOLOR (WM_APP+0x08)
594c2c66affSColin Finck
595c2c66affSColin Finck template<typename BASE> struct CtlColorParent : public BASE
596c2c66affSColin Finck {
597c2c66affSColin Finck typedef BASE super;
598c2c66affSColin Finck
CtlColorParentCtlColorParent599c2c66affSColin Finck CtlColorParent(HWND hwnd)
600c2c66affSColin Finck : super(hwnd) {}
601c2c66affSColin Finck
WndProcCtlColorParent602c2c66affSColin Finck LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
603c2c66affSColin Finck {
604c2c66affSColin Finck switch(nmsg) {
605c2c66affSColin Finck case WM_CTLCOLOR:
606c2c66affSColin Finck case WM_CTLCOLORBTN:
607c2c66affSColin Finck case WM_CTLCOLORDLG:
608c2c66affSColin Finck case WM_CTLCOLORSCROLLBAR:
609c2c66affSColin Finck case WM_CTLCOLORSTATIC: {
610c2c66affSColin Finck HWND hctl = (HWND) lparam;
611c2c66affSColin Finck return SendMessage(hctl, PM_DISPATCH_CTLCOLOR, wparam, nmsg);
612c2c66affSColin Finck }
613c2c66affSColin Finck
614c2c66affSColin Finck default:
615c2c66affSColin Finck return super::WndProc(nmsg, wparam, lparam);
616c2c66affSColin Finck }
617c2c66affSColin Finck }
618c2c66affSColin Finck };
619c2c66affSColin Finck
620c2c66affSColin Finck
621c2c66affSColin Finck #define PM_DISPATCH_DRAWITEM (WM_APP+0x09)
622c2c66affSColin Finck
623c2c66affSColin Finck /// draw message routing for ColorButton and PictureButton
624c2c66affSColin Finck template<typename BASE> struct OwnerDrawParent : public BASE
625c2c66affSColin Finck {
626c2c66affSColin Finck typedef BASE super;
627c2c66affSColin Finck
OwnerDrawParentOwnerDrawParent628c2c66affSColin Finck OwnerDrawParent(HWND hwnd)
629c2c66affSColin Finck : super(hwnd) {}
630c2c66affSColin Finck
WndProcOwnerDrawParent631c2c66affSColin Finck LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
632c2c66affSColin Finck {
633c2c66affSColin Finck switch(nmsg) {
634c2c66affSColin Finck case WM_DRAWITEM:
635c2c66affSColin Finck if (wparam) { // should there be drawn a control?
636c2c66affSColin Finck HWND hctl = GetDlgItem(this->_hwnd, wparam);
637c2c66affSColin Finck
638c2c66affSColin Finck if (hctl)
639c2c66affSColin Finck return SendMessage(hctl, PM_DISPATCH_DRAWITEM, wparam, lparam);
640c2c66affSColin Finck } /*else // or is it a menu entry?
641c2c66affSColin Finck ; */
642c2c66affSColin Finck
643c2c66affSColin Finck return 0;
644c2c66affSColin Finck
645c2c66affSColin Finck default:
646c2c66affSColin Finck return super::WndProc(nmsg, wparam, lparam);
647c2c66affSColin Finck }
648c2c66affSColin Finck }
649c2c66affSColin Finck };
650c2c66affSColin Finck
651c2c66affSColin Finck
652c2c66affSColin Finck /**
653c2c66affSColin Finck Subclass button controls to draw them by using PM_DISPATCH_DRAWITEM
654c2c66affSColin Finck The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
655c2c66affSColin Finck */
656c2c66affSColin Finck struct OwnerdrawnButton : public SubclassedWindow
657c2c66affSColin Finck {
658c2c66affSColin Finck typedef SubclassedWindow super;
659c2c66affSColin Finck
OwnerdrawnButtonOwnerdrawnButton660c2c66affSColin Finck OwnerdrawnButton(HWND hwnd)
661c2c66affSColin Finck : super(hwnd) {}
662c2c66affSColin Finck
663c2c66affSColin Finck protected:
664c2c66affSColin Finck LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
665c2c66affSColin Finck
666c2c66affSColin Finck virtual void DrawItem(LPDRAWITEMSTRUCT dis) = 0;
667c2c66affSColin Finck };
668c2c66affSColin Finck
669c2c66affSColin Finck extern void DrawGrayText(HDC hdc, LPRECT pRect, LPCTSTR text, int dt_flags);
670c2c66affSColin Finck
671c2c66affSColin Finck
672c2c66affSColin Finck /**
673c2c66affSColin Finck Subclass button controls to paint colored text labels.
674c2c66affSColin Finck The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
675c2c66affSColin Finck */
676c2c66affSColin Finck /* not yet used
677c2c66affSColin Finck struct ColorButton : public OwnerdrawnButton
678c2c66affSColin Finck {
679c2c66affSColin Finck typedef OwnerdrawnButton super;
680c2c66affSColin Finck
681c2c66affSColin Finck ColorButton(HWND hwnd, COLORREF textColor)
682c2c66affSColin Finck : super(hwnd), _textColor(textColor) {}
683c2c66affSColin Finck
684c2c66affSColin Finck protected:
685c2c66affSColin Finck virtual void DrawItem(LPDRAWITEMSTRUCT dis);
686c2c66affSColin Finck
687c2c66affSColin Finck COLORREF _textColor;
688c2c66affSColin Finck };
689c2c66affSColin Finck */
690c2c66affSColin Finck
691c2c66affSColin Finck
692c2c66affSColin Finck struct FlatButton : public OwnerdrawnButton
693c2c66affSColin Finck {
694c2c66affSColin Finck typedef OwnerdrawnButton super;
695c2c66affSColin Finck
FlatButtonFlatButton696c2c66affSColin Finck FlatButton(HWND hwnd)
697c2c66affSColin Finck : super(hwnd), _active(false) {}
698c2c66affSColin Finck
FlatButtonFlatButton699c2c66affSColin Finck FlatButton(HWND owner, int id)
700c2c66affSColin Finck : super(GetDlgItem(owner, IDOK)), _active(false) {}
701c2c66affSColin Finck
702c2c66affSColin Finck protected:
703c2c66affSColin Finck LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
704c2c66affSColin Finck virtual void DrawItem(LPDRAWITEMSTRUCT dis);
705c2c66affSColin Finck
706c2c66affSColin Finck COLORREF _textColor;
707c2c66affSColin Finck COLORREF _activeColor;
708c2c66affSColin Finck bool _active;
709c2c66affSColin Finck };
710c2c66affSColin Finck
711c2c66affSColin Finck
712c2c66affSColin Finck /**
713c2c66affSColin Finck Subclass button controls to paint pictures left to the labels.
714c2c66affSColin Finck The buttons should have set the style bit BS_OWNERDRAW.
715c2c66affSColin Finck The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
716c2c66affSColin Finck */
717c2c66affSColin Finck struct PictureButton : public OwnerdrawnButton
718c2c66affSColin Finck {
719c2c66affSColin Finck typedef OwnerdrawnButton super;
720c2c66affSColin Finck
721c2c66affSColin Finck PictureButton(HWND hwnd, HICON hIcon, HBRUSH hbrush=GetSysColorBrush(COLOR_BTNFACE), bool flat=false)
superPictureButton722c2c66affSColin Finck : super(hwnd), _hIcon(hIcon), _hBmp(0), _hBrush(hbrush), _flat(flat)
723c2c66affSColin Finck {
724c2c66affSColin Finck _cx = 16;
725c2c66affSColin Finck _cy = 16;
726c2c66affSColin Finck }
727c2c66affSColin Finck
728c2c66affSColin Finck PictureButton(HWND hparent, int id, HICON hIcon, HBRUSH hbrush=GetSysColorBrush(COLOR_BTNFACE), bool flat=false)
superPictureButton729c2c66affSColin Finck : super(GetDlgItem(hparent, id)), _hIcon(hIcon), _hBmp(0), _hBrush(hbrush), _flat(flat)
730c2c66affSColin Finck {
731c2c66affSColin Finck _cx = 16;
732c2c66affSColin Finck _cy = 16;
733c2c66affSColin Finck }
734c2c66affSColin Finck
735c2c66affSColin Finck PictureButton(HWND hwnd, HBITMAP hBmp, HBRUSH hbrush=GetSysColorBrush(COLOR_BTNFACE), bool flat=false)
superPictureButton736c2c66affSColin Finck : super(hwnd), _hIcon(0), _hBmp(hBmp), _hBrush(hbrush), _flat(flat)
737c2c66affSColin Finck {
738c2c66affSColin Finck BITMAP bmp;
739c2c66affSColin Finck GetObject(hBmp, sizeof(bmp), &bmp);
740c2c66affSColin Finck _cx = bmp.bmWidth;
741c2c66affSColin Finck _cy = bmp.bmHeight;
742c2c66affSColin Finck }
743c2c66affSColin Finck
744c2c66affSColin Finck PictureButton(HWND hparent, int id, HBITMAP hBmp, HBRUSH hbrush=GetSysColorBrush(COLOR_BTNFACE), bool flat=false)
superPictureButton745c2c66affSColin Finck : super(GetDlgItem(hparent, id)), _hIcon(0), _hBmp(hBmp), _hBrush(hbrush), _flat(flat)
746c2c66affSColin Finck {
747c2c66affSColin Finck BITMAP bmp;
748c2c66affSColin Finck GetObject(hBmp, sizeof(bmp), &bmp);
749c2c66affSColin Finck _cx = bmp.bmWidth;
750c2c66affSColin Finck _cy = bmp.bmHeight;
751c2c66affSColin Finck }
752c2c66affSColin Finck
753c2c66affSColin Finck protected:
754c2c66affSColin Finck virtual void DrawItem(LPDRAWITEMSTRUCT dis);
755c2c66affSColin Finck
756c2c66affSColin Finck HICON _hIcon;
757c2c66affSColin Finck HBITMAP _hBmp;
758c2c66affSColin Finck HBRUSH _hBrush;
759c2c66affSColin Finck
760c2c66affSColin Finck int _cx;
761c2c66affSColin Finck int _cy;
762c2c66affSColin Finck
763c2c66affSColin Finck bool _flat;
764c2c66affSColin Finck };
765c2c66affSColin Finck
766c2c66affSColin Finck
767c2c66affSColin Finck struct ColorStatic : public SubclassedWindow
768c2c66affSColin Finck {
769c2c66affSColin Finck typedef SubclassedWindow super;
770c2c66affSColin Finck
771c2c66affSColin Finck ColorStatic(HWND hwnd, COLORREF textColor=RGB(255,0,0), HBRUSH hbrush_bkgnd=0, HFONT hfont=0)
superColorStatic772c2c66affSColin Finck : super(hwnd),
773c2c66affSColin Finck _textColor(textColor),
774c2c66affSColin Finck _hbrush_bkgnd(hbrush_bkgnd),
775c2c66affSColin Finck _hfont(hfont)
776c2c66affSColin Finck {
777c2c66affSColin Finck }
778c2c66affSColin Finck
779c2c66affSColin Finck ColorStatic(HWND owner, int id, COLORREF textColor=RGB(255,0,0), HBRUSH hbrush_bkgnd=0, HFONT hfont=0)
superColorStatic780c2c66affSColin Finck : super(GetDlgItem(owner, id)),
781c2c66affSColin Finck _textColor(textColor),
782c2c66affSColin Finck _hbrush_bkgnd(hbrush_bkgnd),
783c2c66affSColin Finck _hfont(hfont)
784c2c66affSColin Finck {
785c2c66affSColin Finck }
786c2c66affSColin Finck
787c2c66affSColin Finck protected:
WndProcColorStatic788c2c66affSColin Finck LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
789c2c66affSColin Finck {
790c2c66affSColin Finck if (nmsg == PM_DISPATCH_CTLCOLOR) {
791c2c66affSColin Finck HDC hdc = (HDC) wparam;
792c2c66affSColin Finck
793c2c66affSColin Finck SetTextColor(hdc, _textColor);
794c2c66affSColin Finck
795c2c66affSColin Finck if (_hfont)
796c2c66affSColin Finck SelectFont(hdc, _hfont);
797c2c66affSColin Finck
798c2c66affSColin Finck if (_hbrush_bkgnd)
799c2c66affSColin Finck return (LRESULT)_hbrush_bkgnd;
800c2c66affSColin Finck else {
801c2c66affSColin Finck SetBkMode(hdc, TRANSPARENT);
802c2c66affSColin Finck return (LRESULT)GetStockBrush(HOLLOW_BRUSH);
803c2c66affSColin Finck }
804c2c66affSColin Finck } else
805c2c66affSColin Finck return super::WndProc(nmsg, wparam, lparam);
806c2c66affSColin Finck }
807c2c66affSColin Finck
808c2c66affSColin Finck COLORREF _textColor;
809c2c66affSColin Finck HBRUSH _hbrush_bkgnd;
810c2c66affSColin Finck HFONT _hfont;
811c2c66affSColin Finck };
812c2c66affSColin Finck
813c2c66affSColin Finck
814c2c66affSColin Finck /// Hyperlink Controls
815c2c66affSColin Finck
816c2c66affSColin Finck struct HyperlinkCtrl : public SubclassedWindow
817c2c66affSColin Finck {
818c2c66affSColin Finck typedef SubclassedWindow super;
819c2c66affSColin Finck
820c2c66affSColin Finck HyperlinkCtrl(HWND hwnd, COLORREF colorLink=RGB(0,0,255), COLORREF colorVisited=RGB(128,0,128));
821c2c66affSColin Finck HyperlinkCtrl(HWND owner, int id, COLORREF colorLink=RGB(0,0,255), COLORREF colorVisited=RGB(128,0,128));
822c2c66affSColin Finck
823c2c66affSColin Finck ~HyperlinkCtrl();
824c2c66affSColin Finck
825c2c66affSColin Finck String _cmd;
826c2c66affSColin Finck
827c2c66affSColin Finck protected:
828c2c66affSColin Finck COLORREF _textColor;
829c2c66affSColin Finck COLORREF _colorVisited;
830c2c66affSColin Finck HFONT _hfont;
831c2c66affSColin Finck HCURSOR _crsr_link;
832c2c66affSColin Finck
833c2c66affSColin Finck LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
834c2c66affSColin Finck
835c2c66affSColin Finck void init();
836c2c66affSColin Finck
LaunchLinkHyperlinkCtrl837c2c66affSColin Finck bool LaunchLink()
838c2c66affSColin Finck {
839c2c66affSColin Finck if (!_cmd.empty()) {
840c2c66affSColin Finck HINSTANCE hinst = ShellExecute(GetParent(_hwnd), _T("open"), _cmd, 0, 0, SW_SHOWNORMAL);
841*a2f7de7eSTimo Kreuzer return (INT_PTR)hinst > HINSTANCE_ERROR;
842c2c66affSColin Finck }
843c2c66affSColin Finck
844c2c66affSColin Finck return true;
845c2c66affSColin Finck }
846c2c66affSColin Finck };
847c2c66affSColin Finck
848c2c66affSColin Finck
849c2c66affSColin Finck /// encapsulation of tool tip controls
850c2c66affSColin Finck struct ToolTip : public WindowHandle
851c2c66affSColin Finck {
852c2c66affSColin Finck typedef WindowHandle super;
853c2c66affSColin Finck
854c2c66affSColin Finck ToolTip(HWND owner);
855c2c66affSColin Finck
856c2c66affSColin Finck void activate(BOOL active=TRUE)
857c2c66affSColin Finck {
858c2c66affSColin Finck SendMessage(_hwnd, TTM_ACTIVATE, active, 0);
859c2c66affSColin Finck }
860c2c66affSColin Finck
861c2c66affSColin Finck void add(HWND hparent, HWND htool, LPCTSTR txt=LPSTR_TEXTCALLBACK, LPARAM lparam=0)
862c2c66affSColin Finck {
863c2c66affSColin Finck TOOLINFO ti = {
864*a2f7de7eSTimo Kreuzer sizeof(TOOLINFO), TTF_SUBCLASS|TTF_IDISHWND|TTF_TRANSPARENT, hparent, (UINT_PTR)htool,
865c2c66affSColin Finck {0,0,0,0}, 0, (LPTSTR)txt, lparam
866c2c66affSColin Finck };
867c2c66affSColin Finck
868c2c66affSColin Finck #ifdef UNICODE ///@todo Why is it neccesary to try both TTM_ADDTOOLW and TTM_ADDTOOLW ?!
869c2c66affSColin Finck if (!SendMessage(_hwnd, TTM_ADDTOOLW, 0, (LPARAM)&ti))
870c2c66affSColin Finck SendMessage(_hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
871c2c66affSColin Finck #else
872c2c66affSColin Finck if (!SendMessage(_hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti))
873c2c66affSColin Finck SendMessage(_hwnd, TTM_ADDTOOLW, 0, (LPARAM)&ti);
874c2c66affSColin Finck #endif
875c2c66affSColin Finck }
876c2c66affSColin Finck
877c2c66affSColin Finck void add(HWND hparent, UINT id, const RECT& rect, LPCTSTR txt=LPSTR_TEXTCALLBACK, LPARAM lparam=0)
878c2c66affSColin Finck {
879c2c66affSColin Finck TOOLINFO ti = {
880c2c66affSColin Finck sizeof(TOOLINFO), TTF_SUBCLASS|TTF_TRANSPARENT, hparent, id,
881c2c66affSColin Finck {rect.left,rect.top,rect.right,rect.bottom}, 0, (LPTSTR)txt, lparam
882c2c66affSColin Finck };
883c2c66affSColin Finck
884c2c66affSColin Finck #ifdef UNICODE
885c2c66affSColin Finck if (!SendMessage(_hwnd, TTM_ADDTOOLW, 0, (LPARAM)&ti))
886c2c66affSColin Finck SendMessage(_hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
887c2c66affSColin Finck #else
888c2c66affSColin Finck if (!SendMessage(_hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti))
889c2c66affSColin Finck SendMessage(_hwnd, TTM_ADDTOOLW, 0, (LPARAM)&ti);
890c2c66affSColin Finck #endif
891c2c66affSColin Finck }
892c2c66affSColin Finck
removeToolTip893c2c66affSColin Finck void remove(HWND hparent, HWND htool)
894c2c66affSColin Finck {
895c2c66affSColin Finck TOOLINFO ti = {
896*a2f7de7eSTimo Kreuzer sizeof(TOOLINFO), TTF_IDISHWND, hparent, (UINT_PTR)htool,
897c2c66affSColin Finck {0,0,0,0}, 0, 0, 0
898c2c66affSColin Finck };
899c2c66affSColin Finck
900c2c66affSColin Finck SendMessage(_hwnd, TTM_DELTOOL, 0, (LPARAM)&ti);
901c2c66affSColin Finck }
902c2c66affSColin Finck
removeToolTip903c2c66affSColin Finck void remove(HWND hparent, UINT id)
904c2c66affSColin Finck {
905c2c66affSColin Finck TOOLINFO ti = {
906c2c66affSColin Finck sizeof(TOOLINFO), 0, hparent, id,
907c2c66affSColin Finck {0,0,0,0}, 0, 0, 0
908c2c66affSColin Finck };
909c2c66affSColin Finck
910c2c66affSColin Finck SendMessage(_hwnd, TTM_DELTOOL, 0, (LPARAM)&ti);
911c2c66affSColin Finck }
912c2c66affSColin Finck };
913c2c66affSColin Finck
914c2c66affSColin Finck
ListView_GetItemData(HWND list_ctrl,int idx)915c2c66affSColin Finck inline int ListView_GetItemData(HWND list_ctrl, int idx)
916c2c66affSColin Finck {
917c2c66affSColin Finck LV_ITEM item;
918c2c66affSColin Finck
919c2c66affSColin Finck item.mask = LVIF_PARAM;
920c2c66affSColin Finck item.iItem = idx;
921c2c66affSColin Finck
922c2c66affSColin Finck if (!ListView_GetItem(list_ctrl, &item))
923c2c66affSColin Finck return 0;
924c2c66affSColin Finck
925c2c66affSColin Finck return item.lParam;
926c2c66affSColin Finck }
927c2c66affSColin Finck
ListView_FindItemPara(HWND list_ctrl,LPARAM param)928c2c66affSColin Finck inline int ListView_FindItemPara(HWND list_ctrl, LPARAM param)
929c2c66affSColin Finck {
930c2c66affSColin Finck LVFINDINFO fi;
931c2c66affSColin Finck
932c2c66affSColin Finck fi.flags = LVFI_PARAM;
933c2c66affSColin Finck fi.lParam = param;
934c2c66affSColin Finck
935c2c66affSColin Finck return ListView_FindItem(list_ctrl, (unsigned)-1, &fi);
936c2c66affSColin Finck }
937c2c66affSColin Finck
ListView_GetFocusedItem(HWND list_ctrl)938c2c66affSColin Finck inline int ListView_GetFocusedItem(HWND list_ctrl)
939c2c66affSColin Finck {
940c2c66affSColin Finck int idx = ListView_GetItemCount(list_ctrl);
941c2c66affSColin Finck
942c2c66affSColin Finck while(--idx >= 0)
943c2c66affSColin Finck if (ListView_GetItemState(list_ctrl, idx, LVIS_FOCUSED))
944c2c66affSColin Finck break;
945c2c66affSColin Finck
946c2c66affSColin Finck return idx;
947c2c66affSColin Finck }
948c2c66affSColin Finck
949c2c66affSColin Finck
950c2c66affSColin Finck /// sorting of list controls
951c2c66affSColin Finck struct ListSort : public WindowHandle
952c2c66affSColin Finck {
953c2c66affSColin Finck ListSort(HWND hwndListview, PFNLVCOMPARE compare_fct);
954c2c66affSColin Finck
955c2c66affSColin Finck void toggle_sort(int idx);
956c2c66affSColin Finck void sort();
957c2c66affSColin Finck
958c2c66affSColin Finck int _sort_crit;
959c2c66affSColin Finck bool _direction;
960c2c66affSColin Finck
961c2c66affSColin Finck protected:
962c2c66affSColin Finck PFNLVCOMPARE _compare_fct;
963c2c66affSColin Finck
964c2c66affSColin Finck static int CALLBACK CompareFunc(LPARAM lparam1, LPARAM lparam2, LPARAM lparamSort);
965c2c66affSColin Finck };
966c2c66affSColin Finck
967c2c66affSColin Finck
TreeView_GetItemData(HWND hwndTreeView,HTREEITEM hItem)968c2c66affSColin Finck inline LPARAM TreeView_GetItemData(HWND hwndTreeView, HTREEITEM hItem)
969c2c66affSColin Finck {
970c2c66affSColin Finck TVITEM tvItem;
971c2c66affSColin Finck
972c2c66affSColin Finck tvItem.mask = TVIF_PARAM;
973c2c66affSColin Finck tvItem.hItem = hItem;
974c2c66affSColin Finck
975c2c66affSColin Finck if (!TreeView_GetItem(hwndTreeView, &tvItem))
976c2c66affSColin Finck return 0;
977c2c66affSColin Finck
978c2c66affSColin Finck return tvItem.lParam;
979c2c66affSColin Finck }
980c2c66affSColin Finck
981c2c66affSColin Finck
982c2c66affSColin Finck enum {TRAYBUTTON_LEFT=0, TRAYBUTTON_RIGHT, TRAYBUTTON_MIDDLE};
983c2c66affSColin Finck
984c2c66affSColin Finck #define PM_TRAYICON (WM_APP+0x20)
985c2c66affSColin Finck
986c2c66affSColin Finck #define WINMSG_TASKBARCREATED TEXT("TaskbarCreated")
987c2c66affSColin Finck
988c2c66affSColin Finck #define WINMSG_SHELLHOOK TEXT("SHELLHOOK")
989c2c66affSColin Finck
990c2c66affSColin Finck
991c2c66affSColin Finck struct TrayIcon
992c2c66affSColin Finck {
TrayIconTrayIcon993c2c66affSColin Finck TrayIcon(HWND hparent, UINT id)
994c2c66affSColin Finck : _hparent(hparent), _id(id) {}
995c2c66affSColin Finck
~TrayIconTrayIcon996c2c66affSColin Finck ~TrayIcon()
997c2c66affSColin Finck {Remove();}
998c2c66affSColin Finck
999c2c66affSColin Finck void Add(HICON hIcon, LPCTSTR tooltip=NULL)
1000c2c66affSColin Finck {Set(NIM_ADD, _id, hIcon, tooltip);}
1001c2c66affSColin Finck
1002c2c66affSColin Finck void Modify(HICON hIcon, LPCTSTR tooltip=NULL)
1003c2c66affSColin Finck {Set(NIM_MODIFY, _id, hIcon, tooltip);}
1004c2c66affSColin Finck
RemoveTrayIcon1005c2c66affSColin Finck void Remove()
1006c2c66affSColin Finck {
1007c2c66affSColin Finck NOTIFYICONDATA nid = {
1008c2c66affSColin Finck sizeof(NOTIFYICONDATA), // cbSize
1009c2c66affSColin Finck _hparent, // hWnd
1010c2c66affSColin Finck _id, // uID
1011c2c66affSColin Finck };
1012c2c66affSColin Finck
1013c2c66affSColin Finck Shell_NotifyIcon(NIM_DELETE, &nid);
1014c2c66affSColin Finck }
1015c2c66affSColin Finck
1016c2c66affSColin Finck protected:
1017c2c66affSColin Finck HWND _hparent;
1018c2c66affSColin Finck UINT _id;
1019c2c66affSColin Finck
1020c2c66affSColin Finck void Set(DWORD dwMessage, UINT id, HICON hIcon, LPCTSTR tooltip=NULL)
1021c2c66affSColin Finck {
1022c2c66affSColin Finck NOTIFYICONDATA nid = {
1023c2c66affSColin Finck sizeof(NOTIFYICONDATA), // cbSize
1024c2c66affSColin Finck _hparent, // hWnd
1025c2c66affSColin Finck id, // uID
1026c2c66affSColin Finck NIF_MESSAGE|NIF_ICON, // uFlags
1027c2c66affSColin Finck PM_TRAYICON, // uCallbackMessage
1028c2c66affSColin Finck hIcon // hIcon
1029c2c66affSColin Finck };
1030c2c66affSColin Finck
1031c2c66affSColin Finck if (tooltip)
1032c2c66affSColin Finck lstrcpyn(nid.szTip, tooltip, COUNTOF(nid.szTip));
1033c2c66affSColin Finck
1034c2c66affSColin Finck if (nid.szTip[0])
1035c2c66affSColin Finck nid.uFlags |= NIF_TIP;
1036c2c66affSColin Finck
1037c2c66affSColin Finck Shell_NotifyIcon(dwMessage, &nid);
1038c2c66affSColin Finck }
1039c2c66affSColin Finck };
1040c2c66affSColin Finck
1041c2c66affSColin Finck
1042c2c66affSColin Finck template<typename BASE> struct TrayIconControllerTemplate : public BASE
1043c2c66affSColin Finck {
1044c2c66affSColin Finck typedef BASE super;
1045c2c66affSColin Finck
TrayIconControllerTemplateTrayIconControllerTemplate1046c2c66affSColin Finck TrayIconControllerTemplate(HWND hwnd) : BASE(hwnd),
1047c2c66affSColin Finck WM_TASKBARCREATED(RegisterWindowMessage(WINMSG_TASKBARCREATED))
1048c2c66affSColin Finck {
1049c2c66affSColin Finck }
1050c2c66affSColin Finck
WndProcTrayIconControllerTemplate1051c2c66affSColin Finck LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
1052c2c66affSColin Finck {
1053c2c66affSColin Finck if (nmsg == PM_TRAYICON) {
1054c2c66affSColin Finck switch(lparam) {
1055c2c66affSColin Finck case WM_MOUSEMOVE:
1056c2c66affSColin Finck TrayMouseOver(wparam);
1057c2c66affSColin Finck break;
1058c2c66affSColin Finck
1059c2c66affSColin Finck case WM_LBUTTONDOWN:
1060c2c66affSColin Finck TrayClick(wparam, TRAYBUTTON_LEFT);
1061c2c66affSColin Finck break;
1062c2c66affSColin Finck
1063c2c66affSColin Finck case WM_LBUTTONDBLCLK:
1064c2c66affSColin Finck TrayDblClick(wparam, TRAYBUTTON_LEFT);
1065c2c66affSColin Finck break;
1066c2c66affSColin Finck
1067c2c66affSColin Finck case WM_RBUTTONDOWN:
1068c2c66affSColin Finck TrayClick(wparam, TRAYBUTTON_RIGHT);
1069c2c66affSColin Finck break;
1070c2c66affSColin Finck
1071c2c66affSColin Finck case WM_RBUTTONDBLCLK:
1072c2c66affSColin Finck TrayDblClick(wparam, TRAYBUTTON_RIGHT);
1073c2c66affSColin Finck break;
1074c2c66affSColin Finck
1075c2c66affSColin Finck case WM_MBUTTONDOWN:
1076c2c66affSColin Finck TrayClick(wparam, TRAYBUTTON_MIDDLE);
1077c2c66affSColin Finck break;
1078c2c66affSColin Finck
1079c2c66affSColin Finck case WM_MBUTTONDBLCLK:
1080c2c66affSColin Finck TrayDblClick(wparam, TRAYBUTTON_MIDDLE);
1081c2c66affSColin Finck break;
1082c2c66affSColin Finck }
1083c2c66affSColin Finck
1084c2c66affSColin Finck return 0;
1085c2c66affSColin Finck } else if (nmsg == WM_TASKBARCREATED) {
1086c2c66affSColin Finck AddTrayIcons();
1087c2c66affSColin Finck return 0;
1088c2c66affSColin Finck } else
1089c2c66affSColin Finck return super::WndProc(nmsg, wparam, lparam);
1090c2c66affSColin Finck }
1091c2c66affSColin Finck
1092c2c66affSColin Finck virtual void AddTrayIcons() = 0;
TrayMouseOverTrayIconControllerTemplate1093c2c66affSColin Finck virtual void TrayMouseOver(UINT id) {}
TrayClickTrayIconControllerTemplate1094c2c66affSColin Finck virtual void TrayClick(UINT id, int btn) {}
TrayDblClickTrayIconControllerTemplate1095c2c66affSColin Finck virtual void TrayDblClick(UINT id, int btn) {}
1096c2c66affSColin Finck
1097c2c66affSColin Finck protected:
1098c2c66affSColin Finck const UINT WM_TASKBARCREATED;
1099c2c66affSColin Finck };
1100c2c66affSColin Finck
1101c2c66affSColin Finck
1102c2c66affSColin Finck struct EditController : public SubclassedWindow
1103c2c66affSColin Finck {
1104c2c66affSColin Finck typedef SubclassedWindow super;
1105c2c66affSColin Finck
EditControllerEditController1106c2c66affSColin Finck EditController(HWND hwnd)
1107c2c66affSColin Finck : super(hwnd)
1108c2c66affSColin Finck {
1109c2c66affSColin Finck }
1110c2c66affSColin Finck
1111c2c66affSColin Finck protected:
WndProcEditController1112c2c66affSColin Finck LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
1113c2c66affSColin Finck {
1114c2c66affSColin Finck if (nmsg==WM_KEYDOWN && wparam==VK_RETURN) {
1115c2c66affSColin Finck SendParent(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(_hwnd),1), (LPARAM)_hwnd);
1116c2c66affSColin Finck return 0;
1117c2c66affSColin Finck } else
1118c2c66affSColin Finck return super::WndProc(nmsg, wparam, lparam);
1119c2c66affSColin Finck }
1120c2c66affSColin Finck };
1121