2 * Copyright 2003 Martin Fuchs
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 // Explorer start menu
27 // Martin Fuchs, 19.08.2003
31 #include "../utility/utility.h"
33 #include "../explorer.h"
34 #include "../globals.h"
35 #include "../externals.h"
36 #include "../explorer_intres.h"
38 #include "desktopbar.h"
39 #include "startmenu.h"
42 StartMenu::StartMenu(HWND hwnd
)
45 _next_id
= IDC_FIRST_MENU
;
50 StartMenu::StartMenu(HWND hwnd
, const StartMenuFolders
& info
)
53 for(StartMenuFolders::const_iterator it
=info
.begin(); it
!=info
.end(); ++it
)
55 _dirs
.push_back(ShellDirectory(Desktop(), *it
, _hwnd
));
57 _next_id
= IDC_FIRST_MENU
;
62 StartMenu::~StartMenu()
64 SendParent(PM_STARTMENU_CLOSED
);
68 // We need this wrapper function for s_wcStartMenu, it calls to the WIN32 API
69 // through static C++ initializers are not allowed for Winelib applications.
70 BtnWindowClass
& StartMenu::GetWndClasss()
72 static BtnWindowClass
s_wcStartMenu(CLASSNAME_STARTMENU
);
78 HWND StartMenu::Create(int x, int y, HWND hwndParent)
80 return Window::Create(WINDOW_CREATOR(StartMenu), NULL, GetWndClasss(), TITLE_STARTMENU,
81 WS_POPUP|WS_THICKFRAME|WS_CLIPCHILDREN|WS_VISIBLE, x, y, STARTMENU_WIDTH_MIN, 4, hwndParent);
85 Window::CREATORFUNC
StartMenu::s_def_creator
= STARTMENU_CREATOR(StartMenu
);
87 HWND
StartMenu::Create(int x
, int y
, const StartMenuFolders
& folders
, HWND hwndParent
, CREATORFUNC creator
)
89 //TODO: check, if coordinates x/y are visible on the screen
90 return Window::Create(creator
, &folders
, 0, GetWndClasss(), NULL
,
91 WS_POPUP
|WS_THICKFRAME
|WS_CLIPCHILDREN
|WS_VISIBLE
, x
, y
, STARTMENU_WIDTH_MIN
, 4/*start height*/, hwndParent
);
95 LRESULT
StartMenu::Init(LPCREATESTRUCT pcs
)
100 if (super::Init(pcs
))
103 // create buttons for registered entries in _entries
104 for(ShellEntryMap::const_iterator it
=_entries
.begin(); it
!=_entries
.end(); ++it
) {
105 const StartMenuEntry
& sme
= it
->second
;
106 bool hasSubmenu
= false;
108 for(ShellEntrySet::const_iterator it
=sme
._entries
.begin(); it
!=sme
._entries
.end(); ++it
)
109 if ((*it
)->_data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
112 AddButton(sme
._title
, sme
._hIcon
, hasSubmenu
, it
->first
);
115 if (!GetWindow(_hwnd
, GW_CHILD
))
116 AddButton(ResString(IDS_EMPTY
), 0, false, (UINT
)-1, WS_VISIBLE
|WS_CHILD
|BS_OWNERDRAW
|WS_DISABLED
);
117 } catch(COMException
& e
) {
118 HandleException(e
, pcs
->hwndParent
); // destroys the start menu window while switching focus
124 void StartMenu::AddEntries()
126 for(StartMenuShellDirs::iterator it
=_dirs
.begin(); it
!=_dirs
.end(); ++it
) {
127 StartMenuDirectory
& smd
= *it
;
128 ShellDirectory
& dir
= smd
._dir
;
136 AddShellEntries(dir
, -1, smd
._subfolders
);
141 void StartMenu::AddShellEntries(const ShellDirectory
& dir
, int max
, bool subfolders
)
145 for(const Entry
*entry
=dir
._down
; entry
; entry
=entry
->_next
) {
146 // hide files like "desktop.ini"
147 if (entry
->_shell_attribs
& SFGAO_HIDDEN
)
148 //not appropriate for drive roots: if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
151 // hide subfolders if requested
153 if (entry
->_data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
156 // only 'max' entries shall be added.
160 const ShellEntry
* shell_entry
= static_cast<const ShellEntry
*>(entry
);
162 AddEntry(dir
._folder
, shell_entry
);
167 LRESULT
StartMenu::WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
171 ResizeButtons(LOWORD(lparam
)-_border_left
);
175 LRESULT res
= super::WndProc(nmsg
, wparam
, lparam
);
177 if (res
>=HTSIZEFIRST
&& res
<=HTSIZELAST
)
178 return HTCLIENT
; // disable window resizing
183 if ((wparam
&0xFFF0) == SC_SIZE
)
184 return 0; // disable window resizing
188 // close start menu when activating another application
191 break; // don't call super::WndProc in case "this" has been deleted
197 case PM_STARTENTRY_FOCUSED
: { //TODO: use TrackMouseEvent() and WM_MOUSEHOVER to wait a bit before opening submenus
198 BOOL hasSubmenu
= wparam
;
199 HWND hctrl
= (HWND
)lparam
;
201 // automatically open submenus
203 UpdateWindow(_hwnd
); // draw focused button before waiting on submenu creation
204 //SendMessage(_hwnd, WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hctrl),BN_CLICKED), (LPARAM)hctrl);
205 Command(GetDlgCtrlID(hctrl
), BN_CLICKED
);
207 // close any open submenu
208 CloseOtherSubmenus(0);
212 case PM_STARTENTRY_LAUNCHED
:
213 // route message to the parent menu and close menus after launching an entry
214 if (!SendParent(nmsg
, wparam
, lparam
))
215 DestroyWindow(_hwnd
);
216 return 1; // signal that we have received and processed the message
218 case PM_STARTMENU_CLOSED
:
223 return super::WndProc(nmsg
, wparam
, lparam
);
230 // resize child button controls to accomodate for new window size
231 void StartMenu::ResizeButtons(int cx
)
233 HDWP hdwp
= BeginDeferWindowPos(10);
235 for(HWND ctrl
=GetWindow(_hwnd
,GW_CHILD
); ctrl
; ctrl
=GetNextWindow(ctrl
,GW_HWNDNEXT
)) {
238 if (rt
.right
!= cx
) {
239 int height
= rt
.bottom
- rt
.top
;
241 // special handling for separator controls
242 if (!height
&& (GetWindowStyle(ctrl
)&SS_TYPEMASK
)==SS_ETCHEDHORZ
)
245 hdwp
= DeferWindowPos(hdwp
, ctrl
, 0, 0, 0, cx
, height
, SWP_NOMOVE
|SWP_NOZORDER
|SWP_NOACTIVATE
);
249 EndDeferWindowPos(hdwp
);
253 int StartMenu::Command(int id
, int code
)
257 DestroyWindow(_hwnd
);
261 ShellEntryMap::iterator found
= _entries
.find(id
);
263 if (found
!= _entries
.end()) {
264 ActivateEntry(id
, found
->second
._entries
);
268 return super::Command(id
, code
);}
275 StartMenuEntry
& StartMenu::AddEntry(LPCTSTR title
, HICON hIcon
, UINT id
)
280 StartMenuEntry
& sme
= _entries
[id
];
288 StartMenuEntry
& StartMenu::AddEntry(const ShellFolder folder
, const ShellEntry
* entry
)
290 HICON hIcon
= entry
->_hIcon
;
292 if (entry
->_data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
293 hIcon
= SmallIcon(IDI_EXPLORER
);
295 const String
& entry_name
= folder
.get_name(entry
->_pidl
);
297 // search for an already existing subdirectory entry with the same name
298 for(ShellEntryMap::iterator it
=_entries
.begin(); it
!=_entries
.end(); ++it
) {
299 StartMenuEntry
& sme
= it
->second
;
301 if (sme
._title
== entry_name
) //TODO: speed up by using a map indexed by name
302 for(ShellEntrySet::iterator it2
=sme
._entries
.begin(); it2
!=sme
._entries
.end(); ++it2
) {
303 if ((*it2
)->_data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
304 // merge the new shell entry with the existing of the same name
305 sme
._entries
.insert(entry
);
311 StartMenuEntry
& sme
= AddEntry(entry_name
, hIcon
);
313 sme
._entries
.insert(entry
);
319 void StartMenu::AddButton(LPCTSTR title
, HICON hIcon
, bool hasSubmenu
, UINT id
, DWORD style
)
321 WindowRect
rect(_hwnd
);
323 // increase window height to make room for the new button
324 rect
.top
-= STARTMENU_LINE_HEIGHT
;
327 rect
.top
+= STARTMENU_LINE_HEIGHT
;
328 rect
.bottom
+= STARTMENU_LINE_HEIGHT
;
331 // widen window, if it is too small
332 int text_width
= StartMenuButton::GetTextWidth(title
,_hwnd
) + 16/*icon*/ + 10/*placeholder*/ + 16/*arrow*/;
334 ClientRect
clnt(_hwnd
);
335 int cx
= clnt
.right
- _border_left
;
337 rect
.right
+= text_width
-cx
;
339 MoveWindow(_hwnd
, rect
.left
, rect
.top
, rect
.right
-rect
.left
, rect
.bottom
-rect
.top
, TRUE
);
341 StartMenuCtrl(_hwnd
, _border_left
, rect
.bottom
-rect
.top
-STARTMENU_LINE_HEIGHT
-6, rect
.right
-rect
.left
-_border_left
,
342 title
, id
, hIcon
, hasSubmenu
, style
);
345 void StartMenu::AddSeparator()
347 WindowRect
rect(_hwnd
);
349 rect
.top
-= STARTMENU_SEP_HEIGHT
;
352 rect
.top
+= STARTMENU_LINE_HEIGHT
;
353 rect
.bottom
+= STARTMENU_LINE_HEIGHT
;
356 MoveWindow(_hwnd
, rect
.left
, rect
.top
, rect
.right
-rect
.left
, rect
.bottom
-rect
.top
, TRUE
);
358 StartMenuSeparator(_hwnd
, _border_left
, rect
.bottom
-rect
.top
-STARTMENU_SEP_HEIGHT
-6, rect
.right
-rect
.left
-_border_left
);
362 bool StartMenu::CloseOtherSubmenus(int id
)
365 if (IsWindow(_submenu
)) {
366 if (_submenu_id
== id
)
369 DestroyWindow(_submenu
);
371 // _submenu should be reset automatically by PM_STARTMENU_CLOSED, but safety first...
382 void StartMenu::CreateSubmenu(int id
, CREATORFUNC creator
)
384 CreateSubmenu(id
, StartMenuFolders(), creator
);
387 void StartMenu::CreateSubmenu(int id
, int folder_id
, CREATORFUNC creator
)
390 SpecialFolderPath
folder(folder_id
, _hwnd
);
392 StartMenuFolders new_folders
;
393 new_folders
.push_back(folder
);
395 CreateSubmenu(id
, new_folders
, creator
);
396 } catch(COMException
&) {
397 // ignore Exception and don't display anything
401 void StartMenu::CreateSubmenu(int id
, int folder_id1
, int folder_id2
, CREATORFUNC creator
)
403 StartMenuFolders new_folders
;
406 SpecialFolderPath
folder1(folder_id1
, _hwnd
);
408 new_folders
.push_back(folder1
);
409 } catch(COMException
&) {
413 SpecialFolderPath
folder2(folder_id2
, _hwnd
);
415 new_folders
.push_back(folder2
);
416 } catch(COMException
&) {
419 if (!new_folders
.empty())
420 CreateSubmenu(id
, new_folders
, creator
);
423 void StartMenu::CreateSubmenu(int id
, const StartMenuFolders
& new_folders
, CREATORFUNC creator
)
425 // Only open one submenu at a time.
426 if (!CloseOtherSubmenus(id
))
429 HWND btn
= GetDlgItem(_hwnd
, id
);
435 x
= pos
.right
-3; // Submenus should overlap their parent a bit.
436 y
= pos
.top
+STARTMENU_LINE_HEIGHT
-3;
438 WindowRect
pos(_hwnd
);
445 _submenu
= StartMenu::Create(x
, y
, new_folders
, _hwnd
, creator
);
449 void StartMenu::ActivateEntry(int id
, const ShellEntrySet
& entries
)
451 StartMenuFolders new_folders
;
453 for(ShellEntrySet::const_iterator it
=entries
.begin(); it
!=entries
.end(); ++it
) {
454 ShellEntry
* entry
= const_cast<ShellEntry
*>(*it
);
456 if (entry
->_data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
457 new_folders
.push_back(entry
->create_absolute_pidl());
459 // If the entry is no subdirectory, there can only be one shell entry.
460 assert(entries
.size()==1);
462 entry
->launch_entry(_hwnd
); //TODO: launch in the background; specify correct HWND for error message box titles
464 // close start menus after launching the selected entry
467 // we deleted 'this' - ensure we leave loop and function
472 if (!new_folders
.empty()) {
473 // Only open one submenu at a time.
474 if (!CloseOtherSubmenus(id
))
477 CreateSubmenu(id
, new_folders
);
482 /// close all windows of the start menu popup
483 void StartMenu::CloseStartMenu(int id
)
485 if (!SendParent(PM_STARTENTRY_LAUNCHED
, id
, (LPARAM
)_hwnd
))
486 DestroyWindow(_hwnd
);
490 int StartMenuButton::GetTextWidth(LPCTSTR title
, HWND hwnd
)
492 WindowCanvas
canvas(hwnd
);
493 FontSelection
font(canvas
, GetStockFont(DEFAULT_GUI_FONT
));
495 RECT rect
= {0, 0, 0, 0};
496 DrawText(canvas
, title
, -1, &rect
, DT_SINGLELINE
|DT_NOPREFIX
|DT_CALCRECT
);
498 return rect
.right
-rect
.left
;
502 LRESULT
StartMenuButton::WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
506 // automatically set the focus to startmenu entries when moving the mouse over them
507 if (GetFocus()!=_hwnd
&& !(GetWindowStyle(_hwnd
)&WS_DISABLED
))
512 PostParent(PM_STARTENTRY_FOCUSED
, _hasSubmenu
, (LPARAM
)_hwnd
);
516 // route WM_CANCELMODE to the startmenu window
517 return SendParent(nmsg
, wparam
, lparam
);
520 return super::WndProc(nmsg
, wparam
, lparam
);
526 void StartMenuButton::DrawItem(LPDRAWITEMSTRUCT dis
)
528 UINT style
= DFCS_BUTTONPUSH
;
530 if (dis
->itemState
& ODS_DISABLED
)
531 style
|= DFCS_INACTIVE
;
533 POINT iconPos
= {dis
->rcItem
.left
+2, (dis
->rcItem
.top
+dis
->rcItem
.bottom
-16)/2};
534 RECT textRect
= {dis
->rcItem
.left
+16+4, dis
->rcItem
.top
+2, dis
->rcItem
.right
-4, dis
->rcItem
.bottom
-4};
536 if (dis
->itemState
& ODS_SELECTED
) {
537 style
|= DFCS_PUSHED
;
538 ++iconPos
.x
; ++iconPos
.y
;
539 ++textRect
.left
; ++textRect
.top
;
540 ++textRect
.right
; ++textRect
.bottom
;
543 int bk_color
= COLOR_BTNFACE
;
544 int text_color
= COLOR_BTNTEXT
;
546 if (dis
->itemState
& ODS_FOCUS
) {
547 bk_color
= COLOR_HIGHLIGHT
;
548 text_color
= COLOR_HIGHLIGHTTEXT
;
551 HBRUSH bk_brush
= GetSysColorBrush(bk_color
);
553 FillRect(dis
->hDC
, &dis
->rcItem
, bk_brush
);
554 DrawIconEx(dis
->hDC
, iconPos
.x
, iconPos
.y
, _hIcon
, 16, 16, 0, bk_brush
, DI_NORMAL
);
556 // draw submenu arrow at the right
558 static SmallIcon
arrowIcon(IDI_ARROW
);
559 static SmallIcon
selArrowIcon(IDI_ARROW_SELECTED
);
561 DrawIconEx(dis
->hDC
, dis
->rcItem
.right
-16, iconPos
.y
,
562 dis
->itemState
&ODS_FOCUS
?selArrowIcon
:arrowIcon
, 16, 16, 0, bk_brush
, DI_NORMAL
);
565 TCHAR title
[BUFFER_LEN
];
566 GetWindowText(_hwnd
, title
, BUFFER_LEN
);
568 BkMode
bk_mode(dis
->hDC
, TRANSPARENT
);
570 if (dis
->itemState
& (ODS_DISABLED
|ODS_GRAYED
))
571 DrawGrayText(dis
, &textRect
, title
, DT_SINGLELINE
|DT_NOPREFIX
|DT_VCENTER
);
573 TextColor
lcColor(dis
->hDC
, GetSysColor(text_color
));
574 DrawText(dis
->hDC
, title
, -1, &textRect
, DT_SINGLELINE
|DT_NOPREFIX
|DT_VCENTER
);
579 StartMenuRoot::StartMenuRoot(HWND hwnd
)
583 // insert directory "All Users\Start Menu"
584 ShellDirectory
cmn_startmenu(Desktop(), SpecialFolderPath(CSIDL_COMMON_STARTMENU
, _hwnd
), _hwnd
);
585 _dirs
.push_back(StartMenuDirectory(cmn_startmenu
, false)); // don't add subfolders
586 } catch(COMException
&) {
587 // ignore exception and don't show additional shortcuts
591 // insert directory "<user name>\Start Menu"
592 ShellDirectory
usr_startmenu(Desktop(), SpecialFolderPath(CSIDL_STARTMENU
, _hwnd
), _hwnd
);
593 _dirs
.push_back(StartMenuDirectory(usr_startmenu
, false)); // don't add subfolders
594 } catch(COMException
&) {
595 // ignore exception and don't show additional shortcuts
598 // read size of logo bitmap
600 GetObject(ResBitmap(IDB_LOGOV
), sizeof(BITMAP
), &bmp_hdr
);
601 _logo_size
.cx
= bmp_hdr
.bmWidth
;
602 _logo_size
.cy
= bmp_hdr
.bmHeight
;
604 _border_left
= _logo_size
.cx
;
608 HWND
StartMenuRoot::Create(HWND hwndDesktopBar
)
610 WindowRect
pos(hwndDesktopBar
);
612 return Window::Create(WINDOW_CREATOR(StartMenuRoot
), 0, GetWndClasss(), TITLE_STARTMENU
,
613 WS_POPUP
|WS_THICKFRAME
|WS_CLIPCHILDREN
|WS_VISIBLE
, pos
.left
, pos
.top
-4, STARTMENU_WIDTH_MIN
, 4, hwndDesktopBar
);
617 void StartMenuRoot::TrackStartmenu()
622 while(IsWindow(hwnd
)) {
623 if (!GetMessage(&msg
, 0, 0, 0)) {
624 PostQuitMessage(msg
.wParam
);
628 // Check for a mouse click on any window, which is not part of the start menu
629 if (msg
.message
==WM_LBUTTONDOWN
|| msg
.message
==WM_MBUTTONDOWN
|| msg
.message
==WM_RBUTTONDOWN
) {
630 StartMenu
* menu_wnd
= NULL
;
632 for(HWND hwnd
=msg
.hwnd
; hwnd
; hwnd
=GetParent(hwnd
)) {
633 menu_wnd
= WINDOW_DYNAMIC_CAST(StartMenu
, hwnd
);
640 DestroyWindow(_hwnd
);
646 if (pretranslate_msg(&msg
))
649 if (dispatch_dialog_msg(&msg
))
652 TranslateMessage(&msg
);
655 DispatchMessage(&msg
);
656 } catch(COMException
& e
) {
657 HandleException(e
, _hwnd
);
659 } catch(COMException
& e
) {
660 HandleException(e
, _hwnd
);
666 LRESULT
StartMenuRoot::Init(LPCREATESTRUCT pcs
)
668 // add buttons for entries in _entries
669 if (super::Init(pcs
))
674 // insert hard coded start entries
675 AddButton(ResString(IDS_PROGRAMS
), 0, true, IDC_PROGRAMS
);
676 AddButton(ResString(IDS_DOCUMENTS
), 0, true, IDC_DOCUMENTS
);
677 AddButton(ResString(IDS_RECENT
), 0, true, IDC_RECENT
);
678 AddButton(ResString(IDS_FAVORITES
), 0, true, IDC_FAVORITES
);
679 AddButton(ResString(IDS_SETTINGS
), 0, true, IDC_SETTINGS
);
680 AddButton(ResString(IDS_BROWSE
), 0, true, IDC_BROWSE
);
681 AddButton(ResString(IDS_SEARCH
), 0, false, IDC_SEARCH
);
682 AddButton(ResString(IDS_SEARCH_COMPUTER
),0,false, IDC_SEARCH_COMPUTER
);
683 AddButton(ResString(IDS_START_HELP
), 0, false, IDC_START_HELP
);
684 AddButton(ResString(IDS_LAUNCH
), 0, false, IDC_LAUNCH
);
688 AddButton(ResString(IDS_LOGOFF
), SmallIcon(IDI_LOGOFF
), false, IDC_LOGOFF
);
689 AddButton(ResString(IDS_SHUTDOWN
), SmallIcon(IDI_LOGOFF
), false, IDC_SHUTDOWN
);
695 void StartMenuRoot::AddEntries()
699 AddButton(ResString(IDS_EXPLORE
), SmallIcon(IDI_EXPLORER
), false, IDC_EXPLORE
);
703 LRESULT
StartMenuRoot::WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
707 PaintCanvas
canvas(_hwnd
);
709 ResBitmap
bmp(IDB_LOGOV
);
710 BitmapSelection
sel(mem_dc
, bmp
);
712 ClientRect
clnt(_hwnd
);
713 int h
= min(_logo_size
.cy
, clnt
.bottom
);
715 RECT rect
= {0, 0, _logo_size
.cx
-1, clnt
.bottom
-h
};
716 HBRUSH hbr
= CreateSolidBrush(RGB(166,202,240)); // same color as the background color in the logo bitmap
717 FillRect(canvas
, &rect
, hbr
);
718 PatBlt(canvas
, _logo_size
.cx
-1, 0, 1, clnt
.bottom
-h
, WHITENESS
);
721 BitBlt(canvas
, 0, clnt
.bottom
-h
, _logo_size
.cx
, h
, mem_dc
, 0, 0, SRCCOPY
);
725 return super::WndProc(nmsg
, wparam
, lparam
);
732 int StartMenuRoot::Command(int id
, int code
)
736 CreateSubmenu(id
, CSIDL_COMMON_PROGRAMS
, CSIDL_PROGRAMS
);
740 explorer_show_frame(_hwnd
, SW_SHOWNORMAL
);
745 HWND hwndDesktopBar
= GetWindow(_hwnd
, GW_OWNER
);
747 ShowLaunchDialog(hwndDesktopBar
);
751 CreateSubmenu(id
, CSIDL_PERSONAL
);
755 CreateSubmenu(id
, CSIDL_RECENT
, STARTMENU_CREATOR(RecentStartMenu
));
759 CreateSubmenu(id
, CSIDL_FAVORITES
);
763 CreateSubmenu(id
, STARTMENU_CREATOR(BrowseMenu
));
767 CreateSubmenu(id
, STARTMENU_CREATOR(SettingsMenu
));
774 case IDC_SEARCH_COMPUTER
:
775 ShowSearchComputer();
779 /* The shell32 Dialog prompts about some system setting change. This is not what we want to display here.
780 HWND hwndDesktopBar = GetWindow(_hwnd, GW_OWNER);
782 ShowRestartDialog(hwndDesktopBar, EWX_LOGOFF);*/
783 DestroyWindow(GetParent(_hwnd
));
787 HWND hwndDesktopBar
= GetWindow(_hwnd
, GW_OWNER
);
789 ShowExitWindowsDialog(hwndDesktopBar
);
793 return super::Command(id
, code
);
800 void StartMenuRoot::ShowLaunchDialog(HWND hwndDesktopBar
)
802 //TODO: All text phrases should be put into the resources.
803 static LPCSTR szTitle
= "Create New Task";
804 static LPCSTR szText
= "Type the name of a program, folder, document, or Internet resource, and Task Manager will open it for you.";
806 static DynamicFct
<RUNFILEDLG
> RunFileDlg(TEXT("SHELL32"), 61);
808 // Show "Run..." dialog
811 if ((HIWORD(GetVersion())>>14) == W_VER_NT
) {
812 WCHAR wTitle
[40], wText
[256];
814 MultiByteToWideChar(CP_ACP
, 0, szTitle
, -1, wTitle
, 40);
815 MultiByteToWideChar(CP_ACP
, 0, szText
, -1, wText
, 256);
817 (*RunFileDlg
)(hwndDesktopBar
, 0, NULL
, (LPCSTR
)wTitle
, (LPCSTR
)wText
, RFF_CALCDIRECTORY
);
820 (*RunFileDlg
)(hwndDesktopBar
, 0, NULL
, szTitle
, szText
, RFF_CALCDIRECTORY
);
824 void StartMenuRoot::ShowExitWindowsDialog(HWND hwndOwner
)
826 static DynamicFct
<EXITWINDOWSDLG
> ExitWindowsDlg(TEXT("SHELL32"), 60);
829 (*ExitWindowsDlg
)(hwndOwner
);
832 void StartMenuRoot::ShowRestartDialog(HWND hwndOwner
, UINT flags
)
834 static DynamicFct
<RESTARTWINDOWSDLG
> RestartDlg(TEXT("SHELL32"), 59);
837 (*RestartDlg
)(hwndOwner
, (LPWSTR
)L
"You selected <Log Off>.\n\n", flags
); //TODO: ANSI string conversion if needed
840 void StartMenuRoot::ShowSearchDialog()
842 static DynamicFct
<SHFINDFILES
> SHFindFiles(TEXT("SHELL32"), 90);
845 (*SHFindFiles
)(NULL
, NULL
);
848 void StartMenuRoot::ShowSearchComputer()
850 static DynamicFct
<SHFINDCOMPUTER
> SHFindComputer(TEXT("SHELL32"), 91);
853 (*SHFindComputer
)(NULL
, NULL
);
857 void SettingsMenu::AddEntries()
861 AddButton(ResString(IDS_CONTROL_PANEL
), 0, false, IDC_CONTROL_PANEL
);
862 AddButton(ResString(IDS_PRINTERS
), 0, true, IDC_PRINTERS
);
863 AddButton(ResString(IDS_CONNECTIONS
), 0, true, IDC_CONNECTIONS
);
864 AddButton(ResString(IDS_ADMIN
), 0, true, IDC_ADMIN
);
865 AddButton(ResString(IDS_SETTINGS_MENU
), 0, true, IDC_SETTINGS_MENU
);
868 int SettingsMenu::Command(int id
, int code
)
871 case IDC_SETTINGS_MENU
:
872 CreateSubmenu(id
, CSIDL_CONTROLS
);
876 CreateSubmenu(id
, CSIDL_PRINTERS
, CSIDL_PRINTHOOD
);
879 case IDC_CONTROL_PANEL
:
881 MainFrame::Create(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"), FALSE
);
885 CreateSubmenu(id
, CSIDL_COMMON_ADMINTOOLS
, CSIDL_ADMINTOOLS
);
888 case IDC_CONNECTIONS
:
889 CreateSubmenu(id
, CSIDL_CONNECTIONS
);
893 return super::Command(id
, code
);
900 void BrowseMenu::AddEntries()
904 AddButton(ResString(IDS_NETWORK
), 0, true, IDC_NETWORK
);
905 AddButton(ResString(IDS_DRIVES
), 0, true, IDC_DRIVES
);
908 int BrowseMenu::Command(int id
, int code
)
912 CreateSubmenu(id
, CSIDL_NETWORK
);
916 //TODO: exclude removeable drives
917 CreateSubmenu(id
, CSIDL_DRIVES
);
921 return super::Command(id
, code
);
928 RecentStartMenu::RecentStartMenu(HWND hwnd
, const StartMenuFolders
& info
)
933 void RecentStartMenu::AddEntries()
935 for(StartMenuShellDirs::iterator it
=_dirs
.begin(); it
!=_dirs
.end(); ++it
) {
936 StartMenuDirectory
& smd
= *it
;
937 ShellDirectory
& dir
= smd
._dir
;
945 dir
.sort_directory(SORT_DATE
);
946 AddShellEntries(dir
, 16, smd
._subfolders
); //TODO: read max. count of entries from registry