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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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) (icon_size+4) 35 #define STARTMENU_SEP_HEIGHT(icon_size) (STARTMENU_LINE_HEIGHT(icon_size)/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(icon_size), 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(icon_size)/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, int icon_size); 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, int icon_size); 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, int icon_size=ICON_SIZE_SMALL); 213 StartMenu(HWND hwnd, const StartMenuCreateInfo& create_info, int icon_size=ICON_SIZE_SMALL); 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 int _icon_size; 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, int icon_size); 300 301 void DrawArrows(HDC hdc, int icon_size); 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, int icon_size=ICON_SIZE_SMALL) 337 : super(hwnd, icon_size) 338 { 339 } 340 341 StartMenuHandler(HWND hwnd, const StartMenuCreateInfo& create_info, int icon_size=ICON_SIZE_SMALL) 342 : super(hwnd, create_info, icon_size) 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 ShowRestartDialog(HWND hwndOwner, UINT flags); 352 static void ShowSearchDialog(); 353 static void ShowSearchComputer(); 354 }; 355 356 357 struct StartMenuRootCreateInfo 358 { 359 int _icon_size; 360 }; 361 362 363 /// Startmenu root window 364 struct StartMenuRoot : public StartMenuHandler 365 { 366 typedef StartMenuHandler super; 367 368 StartMenuRoot(HWND hwnd, const StartMenuRootCreateInfo& info); 369 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); 375 376 HWND _hwndStartButton; 377 378 protected: 379 LRESULT Init(LPCREATESTRUCT pcs); 380 LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); 381 382 SIZE _logo_size; 383 384 virtual void AddEntries(); 385 virtual void ProcessKey(int vk); 386 387 void Paint(PaintCanvas& canvas); 388 389 390 void ReadLogoSize(); 391 UINT GetLogoResId(); 392 }; 393 394 395 /// Settings sub-startmenu 396 struct SettingsMenu : public StartMenuHandler 397 { 398 typedef StartMenuHandler super; 399 400 SettingsMenu(HWND hwnd, const StartMenuCreateInfo& create_info) 401 : super(hwnd, create_info) 402 { 403 } 404 405 protected: 406 virtual void AddEntries(); 407 }; 408 409 410 /// "Browse Files..." sub-start menu 411 struct BrowseMenu : public StartMenuHandler 412 { 413 typedef StartMenuHandler super; 414 415 BrowseMenu(HWND hwnd, const StartMenuCreateInfo& create_info) 416 : super(hwnd, create_info) 417 { 418 } 419 420 protected: 421 virtual void AddEntries(); 422 }; 423 424 425 /// Search sub-startmenu 426 struct SearchMenu : public StartMenuHandler 427 { 428 typedef StartMenuHandler super; 429 430 SearchMenu(HWND hwnd, const StartMenuCreateInfo& create_info) 431 : super(hwnd, create_info) 432 { 433 } 434 435 protected: 436 virtual void AddEntries(); 437 }; 438 439 440 #define RECENT_DOCS_COUNT 20 ///@todo read max. count of entries from registry 441 442 /// "Recent Files" sub-start menu 443 struct RecentStartMenu : public StartMenu 444 { 445 typedef StartMenu super; 446 447 RecentStartMenu(HWND hwnd, const StartMenuCreateInfo& create_info) 448 : super(hwnd, create_info) 449 { 450 } 451 452 protected: 453 virtual void AddEntries(); 454 }; 455 456 457 #ifndef _SHELL32_FAVORITES 458 459 typedef map<int, BookmarkNode> BookmarkMap; 460 461 /// Bookmarks sub-startmenu 462 struct FavoritesMenu : public StartMenu 463 { 464 typedef StartMenu super; 465 466 FavoritesMenu(HWND hwnd, const StartMenuCreateInfo& create_info) 467 : super(hwnd, create_info), 468 _bookmarks(*(BookmarkList*)create_info._info) 469 { 470 } 471 472 protected: 473 virtual int Command(int id, int code); 474 virtual void AddEntries(); 475 476 BookmarkList _bookmarks; 477 BookmarkMap _entries; 478 }; 479 480 #endif 481