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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 // Explorer and Desktop clone
25 // Martin Fuchs, 16.08.2003
29 #define CLASSNAME_STARTMENU TEXT("ReactOSStartmenuClass")
30 #define TITLE_STARTMENU TEXT("Start Menu")
33 #define STARTMENU_WIDTH_MIN 120
34 #define STARTMENU_LINE_HEIGHT(icon_size) (icon_size+4)
35 #define STARTMENU_SEP_HEIGHT(icon_size) (STARTMENU_LINE_HEIGHT(icon_size)/2)
36 #define STARTMENU_TOP_BTN_SPACE 8
39 // private message constants
40 #define PM_STARTMENU_CLOSED (WM_APP+0x11)
41 #define PM_STARTENTRY_LAUNCHED (WM_APP+0x12)
43 #ifndef _LIGHT_STARTMENU
44 #define PM_STARTENTRY_FOCUSED (WM_APP+0x13)
47 #define PM_UPDATE_ICONS (WM_APP+0x14)
48 #define PM_SELECT_ENTRY (WM_APP+0x15)
51 /// StartMenuDirectory is used to store the base directory of start menus.
52 struct StartMenuDirectory
54 StartMenuDirectory(const ShellDirectory
& dir
, const String
& ignore
="")
55 : _dir(dir
), _ignore(ignore
)
61 _dir
.free_subentries();
68 typedef list
<StartMenuDirectory
> StartMenuShellDirs
;
69 typedef set
<Entry
*> ShellEntrySet
;
71 /// structure holding information about one start menu entry
74 StartMenuEntry() : _icon_id(ICID_UNKNOWN
) {}
78 ShellEntrySet _entries
;
82 extern int GetStartMenuBtnTextWidth(HDC hdc
, LPCTSTR title
, HWND hwnd
);
85 #ifndef _LIGHT_STARTMENU
88 StartMenuButton draws the face of a StartMenuCtrl button control.
90 struct StartMenuButton
: public OwnerdrawnButton
92 typedef OwnerdrawnButton super
;
94 StartMenuButton(HWND hwnd
, ICON_ID icon_id
, bool hasSubmenu
)
95 : super(hwnd
), _hIcon(hIcon
), _hasSubmenu(hasSubmenu
) {}
98 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
99 virtual void DrawItem(LPDRAWITEMSTRUCT dis
);
107 To create a Startmenu button control, construct a StartMenuCtrl object.
109 struct StartMenuCtrl
: public Button
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(icon_size
), id
, style
, exStyle
)
115 *new StartMenuButton(_hwnd
, hIcon
, hasSubmenu
);
117 SetWindowFont(_hwnd
, GetStockFont(DEFAULT_GUI_FONT
), FALSE
);
122 /// separator between start menu entries
123 struct StartMenuSeparator
: public Static
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(icon_size
)/2-1, w
, 2, -1, style
, exStyle
)
134 typedef list
<ShellPath
> StartMenuFolders
;
136 /// structor containing information for creating of start menus
137 struct StartMenuCreateInfo
139 StartMenuCreateInfo() : _border_top(0) {}
141 StartMenuFolders _folders
;
144 Window::CREATORFUNC_INFO _creator
;
149 #define STARTMENU_CREATOR(WND_CLASS) WINDOW_CREATOR_INFO(WND_CLASS, StartMenuCreateInfo)
151 typedef map
<int, StartMenuEntry
> ShellEntryMap
;
154 #ifdef _LIGHT_STARTMENU
158 SMBtnInfo(const StartMenuEntry
& entry
, int id
, bool hasSubmenu
=false, bool enabled
=true)
159 : _title(entry
._title
),
160 _icon_id(entry
._icon_id
),
162 _hasSubmenu(hasSubmenu
),
167 SMBtnInfo(LPCTSTR title
, ICON_ID icon_id
, int id
, bool hasSubmenu
=false, bool enabled
=true)
171 _hasSubmenu(hasSubmenu
),
183 typedef vector
<SMBtnInfo
> SMBtnVector
;
185 extern void DrawStartMenuButton(HDC hdc
, const RECT
& rect
, LPCTSTR title
, const SMBtnInfo
& btn
, bool has_focus
, bool pushed
, int icon_size
);
189 extern void DrawStartMenuButton(HDC hdc
, const RECT
& rect
, LPCTSTR title
, HICON hIcon
,
190 bool hasSubmenu
, bool enabled
, bool has_focus
, bool pushed
, int icon_size
);
197 To create a start menu call its Create() function.
200 #ifdef _LIGHT_STARTMENU
201 public ExtContextMenuHandlerT
<OwnerDrawParent
<Window
> >
203 public ExtContextMenuHandlerT
<OwnerDrawParent
<DialogWindow
> >
206 #ifdef _LIGHT_STARTMENU
207 typedef ExtContextMenuHandlerT
<OwnerDrawParent
<Window
> > super
;
209 typedef ExtContextMenuHandlerT
<OwnerDrawParent
<DialogWindow
> > super
;
212 StartMenu(HWND hwnd
, int icon_size
=ICON_SIZE_SMALL
);
213 StartMenu(HWND hwnd
, const StartMenuCreateInfo
& create_info
, int icon_size
=ICON_SIZE_SMALL
);
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
;
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
);
227 static BtnWindowClass
& GetWndClasss();
231 ShellEntryMap _entries
;
232 StartMenuShellDirs _dirs
;
235 WindowHandle _submenu
;
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
245 enum SCROLL_MODE
{SCROLL_NOT
, SCROLL_UP
, SCROLL_DOWN
} _scroll_mode
;
247 int _invisible_lines
;
249 StartMenuCreateInfo _create_info
; // copy of the original create info
253 #ifdef _LIGHT_STARTMENU
254 SMBtnVector _buttons
;
256 LPARAM _last_mouse_pos
;
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
);
272 void ResizeButtons(int cx
);
274 virtual void AddEntries();
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
);
281 void AddShellEntries(const ShellDirectory
& dir
, int max
=-1, const String
& ignore
="");
283 void AddButton(LPCTSTR title
, ICON_ID icon_id
=ICID_NONE
, bool hasSubmenu
=false, int id
=-1, bool enabled
=true);
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);
295 bool GetButtonRect(int id
, PRECT prect
) const;
297 void DrawFloatingButton(HDC hdc
);
298 void GetFloatingButtonRect(LPRECT prect
);
299 void GetArrowButtonRects(LPRECT prect_up
, LPRECT prect_down
, int icon_size
);
301 void DrawArrows(HDC hdc
, int icon_size
);
303 void Paint(PaintCanvas
& canvas
);
304 void UpdateIcons(/*int idx*/);
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
);
312 // Flags for RunFileDlg
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).
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
);
331 /// Handling of standard start menu commands
332 struct StartMenuHandler
: public StartMenu
334 typedef StartMenu super
;
336 StartMenuHandler(HWND hwnd
, int icon_size
=ICON_SIZE_SMALL
)
337 : super(hwnd
, icon_size
)
341 StartMenuHandler(HWND hwnd
, const StartMenuCreateInfo
& create_info
, int icon_size
=ICON_SIZE_SMALL
)
342 : super(hwnd
, create_info
, icon_size
)
347 int Command(int id
, int code
);
349 static void ShowLaunchDialog(HWND hwndOwner
);
350 static void ShowLogoffDialog(HWND hwndOwner
);
351 static void ShowRestartDialog(HWND hwndOwner
, UINT flags
);
352 static void ShowSearchDialog();
353 static void ShowSearchComputer();
357 struct StartMenuRootCreateInfo
363 /// Startmenu root window
364 struct StartMenuRoot
: public StartMenuHandler
366 typedef StartMenuHandler super
;
368 StartMenuRoot(HWND hwnd
, const StartMenuRootCreateInfo
& info
);
370 static HWND
Create(HWND hwndDesktopBar
, int icon_size
);
371 void TrackStartmenu();
372 void CloseStartMenu(int id
=0);
373 bool IsStartMenuVisible() const;
374 int Command(int id
, int code
);
376 HWND _hwndStartButton
;
379 LRESULT
Init(LPCREATESTRUCT pcs
);
380 LRESULT
WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
);
384 virtual void AddEntries();
385 virtual void ProcessKey(int vk
);
387 void Paint(PaintCanvas
& canvas
);
395 /// Settings sub-startmenu
396 struct SettingsMenu
: public StartMenuHandler
398 typedef StartMenuHandler super
;
400 SettingsMenu(HWND hwnd
, const StartMenuCreateInfo
& create_info
)
401 : super(hwnd
, create_info
)
406 virtual void AddEntries();
410 /// "Browse Files..." sub-start menu
411 struct BrowseMenu
: public StartMenuHandler
413 typedef StartMenuHandler super
;
415 BrowseMenu(HWND hwnd
, const StartMenuCreateInfo
& create_info
)
416 : super(hwnd
, create_info
)
421 virtual void AddEntries();
425 /// Search sub-startmenu
426 struct SearchMenu
: public StartMenuHandler
428 typedef StartMenuHandler super
;
430 SearchMenu(HWND hwnd
, const StartMenuCreateInfo
& create_info
)
431 : super(hwnd
, create_info
)
436 virtual void AddEntries();
440 #define RECENT_DOCS_COUNT 20 ///@todo read max. count of entries from registry
442 /// "Recent Files" sub-start menu
443 struct RecentStartMenu
: public StartMenu
445 typedef StartMenu super
;
447 RecentStartMenu(HWND hwnd
, const StartMenuCreateInfo
& create_info
)
448 : super(hwnd
, create_info
)
453 virtual void AddEntries();
457 #ifndef _SHELL32_FAVORITES
459 typedef map
<int, BookmarkNode
> BookmarkMap
;
461 /// Bookmarks sub-startmenu
462 struct FavoritesMenu
: public StartMenu
464 typedef StartMenu super
;
466 FavoritesMenu(HWND hwnd
, const StartMenuCreateInfo
& create_info
)
467 : super(hwnd
, create_info
),
468 _bookmarks(*(BookmarkList
*)create_info
._info
)
473 virtual int Command(int id
, int code
);
474 virtual void AddEntries();
476 BookmarkList _bookmarks
;
477 BookmarkMap _entries
;