explorer: merge changes from lean explorer branch (shell namespace iteration, icon...
[reactos.git] / reactos / subsys / system / explorer / taskbar / startmenu.h
1 /*
2 * Copyright 2003, 2004 Martin Fuchs
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19
20 //
21 // Explorer and Desktop clone
22 //
23 // startmenu.h
24 //
25 // Martin Fuchs, 16.08.2003
26 //
27
28
29 #define CLASSNAME_STARTMENU TEXT("ReactosStartmenuClass")
30 #define TITLE_STARTMENU TEXT("Start Menu")
31
32
33 #define STARTMENU_WIDTH_MIN 120
34 #define STARTMENU_LINE_HEIGHT (ICON_SIZE_X+4)
35 #define STARTMENU_SEP_HEIGHT (STARTMENU_LINE_HEIGHT/2)
36 #define STARTMENU_TOP_BTN_SPACE 8
37
38
39 // private message constants
40 #define PM_STARTMENU_CLOSED (WM_APP+0x11)
41 #define PM_STARTENTRY_LAUNCHED (WM_APP+0x12)
42
43 #ifndef _LIGHT_STARTMENU
44 #define PM_STARTENTRY_FOCUSED (WM_APP+0x13)
45 #endif
46
47 #define PM_UPDATE_ICONS (WM_APP+0x14)
48 #define PM_SELECT_ENTRY (WM_APP+0x15)
49
50
51 /// StartMenuDirectory is used to store the base directory of start menus.
52 struct StartMenuDirectory
53 {
54 StartMenuDirectory(const ShellDirectory& dir, const String& ignore="")
55 : _dir(dir), _ignore(ignore)
56 {
57 }
58
59 ~StartMenuDirectory()
60 {
61 _dir.free_subentries();
62 }
63
64 ShellDirectory _dir;
65 String _ignore;
66 };
67
68 typedef list<StartMenuDirectory> StartMenuShellDirs;
69 typedef set<Entry*> ShellEntrySet;
70
71 /// structure holding information about one start menu entry
72 struct StartMenuEntry
73 {
74 StartMenuEntry() : _icon_id(ICID_UNKNOWN) {}
75
76 String _title;
77 ICON_ID _icon_id;
78 ShellEntrySet _entries;
79 };
80
81
82 extern int GetStartMenuBtnTextWidth(HDC hdc, LPCTSTR title, HWND hwnd);
83
84
85 #ifndef _LIGHT_STARTMENU
86
87 /**
88 StartMenuButton draws the face of a StartMenuCtrl button control.
89 */
90 struct StartMenuButton : public OwnerdrawnButton
91 {
92 typedef OwnerdrawnButton super;
93
94 StartMenuButton(HWND hwnd, ICON_ID icon_id, bool hasSubmenu)
95 : super(hwnd), _hIcon(hIcon), _hasSubmenu(hasSubmenu) {}
96
97 protected:
98 LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
99 virtual void DrawItem(LPDRAWITEMSTRUCT dis);
100
101 ICON_ID _icon_id;
102 bool _hasSubmenu;
103 };
104
105
106 /**
107 To create a Startmenu button control, construct a StartMenuCtrl object.
108 */
109 struct StartMenuCtrl : public Button
110 {
111 StartMenuCtrl(HWND parent, int x, int y, int w, LPCTSTR title,
112 UINT id, HICON hIcon=0, bool hasSubmenu=false, DWORD style=WS_VISIBLE|WS_CHILD|BS_OWNERDRAW, DWORD exStyle=0)
113 : Button(parent, title, x, y, w, STARTMENU_LINE_HEIGHT, id, style, exStyle)
114 {
115 *new StartMenuButton(_hwnd, hIcon, hasSubmenu);
116
117 SetWindowFont(_hwnd, GetStockFont(DEFAULT_GUI_FONT), FALSE);
118 }
119 };
120
121
122 /// separator between start menu entries
123 struct StartMenuSeparator : public Static
124 {
125 StartMenuSeparator(HWND parent, int x, int y, int w, DWORD style=WS_VISIBLE|WS_CHILD|WS_DISABLED|SS_ETCHEDHORZ, DWORD exStyle=0)
126 : Static(parent, NULL, x, y+STARTMENU_SEP_HEIGHT/2-1, w, 2, -1, style, exStyle)
127 {
128 }
129 };
130
131 #endif
132
133
134 typedef list<ShellPath> StartMenuFolders;
135
136 /// structor containing information for creating of start menus
137 struct StartMenuCreateInfo
138 {
139 StartMenuCreateInfo() : _border_top(0) {}
140
141 StartMenuFolders _folders;
142 int _border_top;
143 String _title;
144 Window::CREATORFUNC_INFO _creator;
145 void* _info;
146 String _filter;
147 };
148
149 #define STARTMENU_CREATOR(WND_CLASS) WINDOW_CREATOR_INFO(WND_CLASS, StartMenuCreateInfo)
150
151 typedef map<int, StartMenuEntry> ShellEntryMap;
152
153
154 #ifdef _LIGHT_STARTMENU
155
156 struct SMBtnInfo
157 {
158 SMBtnInfo(const StartMenuEntry& entry, int id, bool hasSubmenu=false, bool enabled=true)
159 : _title(entry._title),
160 _icon_id(entry._icon_id),
161 _id(id),
162 _hasSubmenu(hasSubmenu),
163 _enabled(enabled)
164 {
165 }
166
167 SMBtnInfo(LPCTSTR title, ICON_ID icon_id, int id, bool hasSubmenu=false, bool enabled=true)
168 : _title(title),
169 _icon_id(icon_id),
170 _id(id),
171 _hasSubmenu(hasSubmenu),
172 _enabled(enabled)
173 {
174 }
175
176 String _title;
177 ICON_ID _icon_id;
178 int _id;
179 bool _hasSubmenu;
180 bool _enabled;
181 };
182
183 typedef vector<SMBtnInfo> SMBtnVector;
184
185 extern void DrawStartMenuButton(HDC hdc, const RECT& rect, LPCTSTR title, const SMBtnInfo& btn, bool has_focus, bool pushed, bool large_icons);
186
187 #else
188
189 extern void DrawStartMenuButton(HDC hdc, const RECT& rect, LPCTSTR title, HICON hIcon,
190 bool hasSubmenu, bool enabled, bool has_focus, bool pushed, bool large_icons);
191
192 #endif
193
194
195 /**
196 Startmenu window.
197 To create a start menu call its Create() function.
198 */
199 struct StartMenu :
200 #ifdef _LIGHT_STARTMENU
201 public ExtContextMenuHandlerT<OwnerDrawParent<Window> >
202 #else
203 public ExtContextMenuHandlerT<OwnerDrawParent<DialogWindow> >
204 #endif
205 {
206 #ifdef _LIGHT_STARTMENU
207 typedef ExtContextMenuHandlerT<OwnerDrawParent<Window> > super;
208 #else
209 typedef ExtContextMenuHandlerT<OwnerDrawParent<DialogWindow> > super;
210 #endif
211
212 StartMenu(HWND hwnd, bool large_icons=false);
213 StartMenu(HWND hwnd, const StartMenuCreateInfo& create_info, bool large_icons=false);
214 ~StartMenu();
215
216 static HWND Create(int x, int y, const StartMenuFolders&, HWND hwndParent, LPCTSTR title,
217 CREATORFUNC_INFO creator=s_def_creator, void* info=NULL, const String& filter="");
218 static CREATORFUNC_INFO s_def_creator;
219
220 protected:
221 // overridden member functions
222 LRESULT Init(LPCREATESTRUCT pcs);
223 LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
224 int Command(int id, int code);
225
226 // window class
227 static BtnWindowClass& GetWndClasss();
228
229 // data members
230 int _next_id;
231 ShellEntryMap _entries;
232 StartMenuShellDirs _dirs;
233
234 int _submenu_id;
235 WindowHandle _submenu;
236
237 int _border_left; // left border in pixels
238 int _border_top; // top border in pixels
239 int _bottom_max; // limit display area for long start menus
240
241 bool _floating_btn;
242 bool _arrow_btns;
243
244 POINT _last_pos;
245 enum SCROLL_MODE {SCROLL_NOT, SCROLL_UP, SCROLL_DOWN} _scroll_mode;
246 int _scroll_pos;
247 int _invisible_lines;
248
249 StartMenuCreateInfo _create_info; // copy of the original create info
250
251 bool _large_icons;
252
253 #ifdef _LIGHT_STARTMENU
254 SMBtnVector _buttons;
255 int _selected_id;
256 LPARAM _last_mouse_pos;
257
258 void ResizeToButtons();
259 int ButtonHitTest(POINT pt);
260 void InvalidateSelection();
261 const SMBtnInfo* GetButtonInfo(int id) const;
262 bool SelectButton(int id, bool open_sub=true);
263 bool SelectButtonIndex(int idx, bool open_sub=true);
264 int GetSelectionIndex();
265 virtual void ProcessKey(int vk);
266 bool Navigate(int step);
267 bool OpenSubmenu(bool select_first=false);
268 bool JumpToNextShortcut(char c);
269 #endif
270
271 // member functions
272 void ResizeButtons(int cx);
273
274 virtual void AddEntries();
275
276 ShellEntryMap::iterator AddEntry(const String& title, ICON_ID icon_id, Entry* entry);
277 ShellEntryMap::iterator AddEntry(const String& title, ICON_ID icon_id=ICID_NONE, int id=-1);
278 ShellEntryMap::iterator AddEntry(const ShellFolder folder, ShellEntry* entry);
279 ShellEntryMap::iterator AddEntry(const ShellFolder folder, Entry* entry);
280
281 void AddShellEntries(const ShellDirectory& dir, int max=-1, const String& ignore="");
282
283 void AddButton(LPCTSTR title, ICON_ID icon_id=ICID_NONE, bool hasSubmenu=false, int id=-1, bool enabled=true);
284 void AddSeparator();
285
286 bool CloseSubmenus() {return CloseOtherSubmenus();}
287 bool CloseOtherSubmenus(int id=0);
288 void CreateSubmenu(int id, LPCTSTR title, CREATORFUNC_INFO creator=s_def_creator, void*info=NULL);
289 bool CreateSubmenu(int id, int folder, LPCTSTR title, CREATORFUNC_INFO creator=s_def_creator, void*info=NULL);
290 bool CreateSubmenu(int id, int folder1, int folder2, LPCTSTR title, CREATORFUNC_INFO creator=s_def_creator, void*info=NULL);
291 void CreateSubmenu(int id, const StartMenuFolders& new_folders, LPCTSTR title, CREATORFUNC_INFO creator=s_def_creator, void*info=NULL);
292 void ActivateEntry(int id, const ShellEntrySet& entries);
293 virtual void CloseStartMenu(int id=0);
294
295 bool GetButtonRect(int id, PRECT prect) const;
296
297 void DrawFloatingButton(HDC hdc);
298 void GetFloatingButtonRect(LPRECT prect);
299 void GetArrowButtonRects(LPRECT prect_up, LPRECT prect_down, bool large_icons);
300
301 void DrawArrows(HDC hdc, bool large_icons);
302
303 void Paint(PaintCanvas& canvas);
304 void UpdateIcons(/*int idx*/);
305 };
306
307
308 // declare shell32's "Run..." dialog export function
309 typedef void (WINAPI* RUNFILEDLG)(HWND hwndOwner, HICON hIcon, LPCSTR lpstrDirectory, LPCSTR lpstrTitle, LPCSTR lpstrDescription, UINT uFlags);
310
311 //
312 // Flags for RunFileDlg
313 //
314
315 #define RFF_NOBROWSE 0x01 // Removes the browse button.
316 #define RFF_NODEFAULT 0x02 // No default item selected.
317 #define RFF_CALCDIRECTORY 0x04 // Calculates the working directory from the file name.
318 #define RFF_NOLABEL 0x08 // Removes the edit box label.
319 #define RFF_NOSEPARATEMEM 0x20 // Removes the Separate Memory Space check box (Windows NT only).
320
321
322 // declare more previously undocumented shell32 functions
323 typedef void (WINAPI* EXITWINDOWSDLG)(HWND hwndOwner);
324 typedef int (WINAPI* LOGOFFWINDOWSDIALOG)(UINT flags);
325 typedef int (WINAPI* RESTARTWINDOWSDLG)(HWND hwndOwner, LPCWSTR reason, UINT flags);
326 typedef int (WINAPI* RESTARTWINDOWSDLGEX)(HWND hWndOwner, LPCWSTR lpwstrReason, DWORD uFlags, DWORD uReason);
327 typedef BOOL (WINAPI* SHFINDFILES)(LPCITEMIDLIST pidlRoot, LPCITEMIDLIST pidlSavedSearch);
328 typedef BOOL (WINAPI* SHFINDCOMPUTER)(LPCITEMIDLIST pidlRoot, LPCITEMIDLIST pidlSavedSearch);
329
330
331 /// Handling of standard start menu commands
332 struct StartMenuHandler : public StartMenu
333 {
334 typedef StartMenu super;
335
336 StartMenuHandler(HWND hwnd, bool large_icons=false)
337 : super(hwnd, large_icons)
338 {
339 }
340
341 StartMenuHandler(HWND hwnd, const StartMenuCreateInfo& create_info, bool large_icons=false)
342 : super(hwnd, create_info, large_icons)
343 {
344 }
345
346 protected:
347 int Command(int id, int code);
348
349 static void ShowLaunchDialog(HWND hwndOwner);
350 static void ShowLogoffDialog(HWND hwndOwner);
351 static void ShowSearchDialog();
352 static void ShowSearchComputer();
353 };
354
355
356 /// Startmenu root window
357 struct StartMenuRoot : public StartMenuHandler
358 {
359 typedef StartMenuHandler super;
360
361 StartMenuRoot(HWND hwnd);
362
363 static HWND Create(HWND hwndDesktopBar, bool large_icons);
364 void TrackStartmenu();
365
366 protected:
367 LRESULT Init(LPCREATESTRUCT pcs);
368 LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
369
370 SIZE _logo_size;
371
372 virtual void AddEntries();
373 virtual void ProcessKey(int vk);
374
375 void Paint(PaintCanvas& canvas);
376 void CloseStartMenu(int id=0);
377
378 void ReadLogoSize();
379 UINT GetLogoResId();
380 };
381
382
383 /// Settings sub-startmenu
384 struct SettingsMenu : public StartMenuHandler
385 {
386 typedef StartMenuHandler super;
387
388 SettingsMenu(HWND hwnd, const StartMenuCreateInfo& create_info)
389 : super(hwnd, create_info)
390 {
391 }
392
393 protected:
394 virtual void AddEntries();
395 };
396
397
398 /// "Browse Files..." sub-start menu
399 struct BrowseMenu : public StartMenuHandler
400 {
401 typedef StartMenuHandler super;
402
403 BrowseMenu(HWND hwnd, const StartMenuCreateInfo& create_info)
404 : super(hwnd, create_info)
405 {
406 }
407
408 protected:
409 virtual void AddEntries();
410 };
411
412
413 /// Search sub-startmenu
414 struct SearchMenu : public StartMenuHandler
415 {
416 typedef StartMenuHandler super;
417
418 SearchMenu(HWND hwnd, const StartMenuCreateInfo& create_info)
419 : super(hwnd, create_info)
420 {
421 }
422
423 protected:
424 virtual void AddEntries();
425 };
426
427
428 #define RECENT_DOCS_COUNT 20 ///@todo read max. count of entries from registry
429
430 /// "Recent Files" sub-start menu
431 struct RecentStartMenu : public StartMenu
432 {
433 typedef StartMenu super;
434
435 RecentStartMenu(HWND hwnd, const StartMenuCreateInfo& create_info)
436 : super(hwnd, create_info)
437 {
438 }
439
440 protected:
441 virtual void AddEntries();
442 };
443
444
445 #ifndef _SHELL32_FAVORITES
446
447 typedef map<int, BookmarkNode> BookmarkMap;
448
449 /// Bookmarks sub-startmenu
450 struct FavoritesMenu : public StartMenu
451 {
452 typedef StartMenu super;
453
454 FavoritesMenu(HWND hwnd, const StartMenuCreateInfo& create_info)
455 : super(hwnd, create_info),
456 _bookmarks(*(BookmarkList*)create_info._info)
457 {
458 }
459
460 protected:
461 virtual int Command(int id, int code);
462 virtual void AddEntries();
463
464 BookmarkList _bookmarks;
465 BookmarkMap _entries;
466 };
467
468 #endif