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
)
101 if (super::Init(pcs
))
104 // create buttons for registered entries in _entries
105 if (_entries
.empty()) {
106 AddButton(ResString(IDS_EMPTY
), 0, false, (UINT
)-1, WS_VISIBLE
|WS_CHILD
|BS_OWNERDRAW
|WS_DISABLED
);
108 for(ShellEntryMap::const_iterator it
=_entries
.begin(); it
!=_entries
.end(); ++it
) {
109 const StartMenuEntry
& sme
= it
->second
;
110 bool hasSubmenu
= false;
112 if (sme
._entry
&& (sme
._entry
->_data
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
))
115 AddButton(sme
._title
, sme
._hIcon
, hasSubmenu
, it
->first
);
122 void StartMenu::AddEntries()
124 for(StartMenuShellDirs::iterator it
=_dirs
.begin(); it
!=_dirs
.end(); ++it
) {
125 StartMenuDirectory
& smd
= *it
;
126 ShellDirectory
& dir
= smd
._dir
;
130 AddShellEntries(dir
, -1, smd
._subfolders
);
135 void StartMenu::AddShellEntries(const ShellDirectory
& dir
, int max
, bool subfolders
)
139 for(const Entry
*entry
=dir
._down
; entry
; entry
=entry
->_next
) {
140 // hide files like "desktop.ini"
141 if (entry
->_shell_attribs
& SFGAO_HIDDEN
)
142 //not appropriate for drive roots: if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
145 // hide subfolders if requested
147 if (entry
->_data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
150 // only 'max' entries shall be added.
154 const ShellEntry
* shell_entry
= static_cast<const ShellEntry
*>(entry
);
156 AddEntry(dir
._folder
, shell_entry
);
161 LRESULT
StartMenu::WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
165 ResizeButtons(LOWORD(lparam
)-_border_left
);
169 LRESULT res
= super::WndProc(nmsg
, wparam
, lparam
);
171 if (res
>=HTSIZEFIRST
&& res
<=HTSIZELAST
)
172 return HTCLIENT
; // disable window resizing
177 if ((wparam
&0xFFF0) == SC_SIZE
)
178 return 0; // disable window resizing
182 // close start menu when activating another application
185 break; // don't call super::WndProc in case "this" has been deleted
191 case PM_STARTENTRY_FOCUSED
: { //TODO: use TrackMouseEvent() and WM_MOUSEHOVER to wait a bit before opening submenus
192 BOOL hasSubmenu
= wparam
;
193 HWND hctrl
= (HWND
)lparam
;
195 // automatically open submenus
197 UpdateWindow(_hwnd
); // draw focused button before waiting on submenu creation
198 //SendMessage(_hwnd, WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hctrl),BN_CLICKED), (LPARAM)hctrl);
199 Command(GetDlgCtrlID(hctrl
), BN_CLICKED
);
201 // close any open submenu
202 CloseOtherSubmenus(0);
206 case PM_STARTENTRY_LAUNCHED
:
207 // route message to the parent menu and close menus after launching an entry
208 if (!SendParent(nmsg
, wparam
, lparam
))
209 DestroyWindow(_hwnd
);
210 return 1; // signal that we have received and processed the message
212 case PM_STARTMENU_CLOSED
:
217 return super::WndProc(nmsg
, wparam
, lparam
);
224 // resize child button controls to accomodate for new window size
225 void StartMenu::ResizeButtons(int cx
)
227 HDWP hdwp
= BeginDeferWindowPos(10);
229 for(HWND ctrl
=GetWindow(_hwnd
,GW_CHILD
); ctrl
; ctrl
=GetNextWindow(ctrl
,GW_HWNDNEXT
)) {
232 if (rt
.right
!= cx
) {
233 int height
= rt
.bottom
- rt
.top
;
235 // special handling for separator controls
236 if (!height
&& (GetWindowStyle(ctrl
)&SS_TYPEMASK
)==SS_ETCHEDHORZ
)
239 hdwp
= DeferWindowPos(hdwp
, ctrl
, 0, 0, 0, cx
, height
, SWP_NOMOVE
|SWP_NOZORDER
|SWP_NOACTIVATE
);
243 EndDeferWindowPos(hdwp
);
247 int StartMenu::Command(int id
, int code
)
251 DestroyWindow(_hwnd
);
255 ShellEntryMap::const_iterator found
= _entries
.find(id
);
257 if (found
!= _entries
.end()) {
258 ShellEntry
* entry
= const_cast<ShellEntry
*>(found
->second
._entry
);
261 ActivateEntry(id
, entry
);
265 return super::Command(id
, code
);}
272 StartMenuEntry
& StartMenu::AddEntry(LPCTSTR title
, HICON hIcon
, UINT id
)
277 StartMenuEntry
& sme
= _entries
[id
];
285 StartMenuEntry
& StartMenu::AddEntry(const ShellFolder folder
, const ShellEntry
* entry
)
287 HICON hIcon
= entry
->_hIcon
;
289 if (entry
->_data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
290 hIcon
= SmallIcon(IDI_EXPLORER
);
292 const String
& entry_name
= folder
.get_name(entry
->_pidl
);
294 StartMenuEntry
& sme
= AddEntry(entry_name
, hIcon
);
302 void StartMenu::AddButton(LPCTSTR title
, HICON hIcon
, bool hasSubmenu
, UINT id
, DWORD style
)
304 WindowRect
rect(_hwnd
);
306 // increase window height to make room for the new button
307 rect
.top
-= STARTMENU_LINE_HEIGHT
;
310 rect
.top
+= STARTMENU_LINE_HEIGHT
;
311 rect
.bottom
+= STARTMENU_LINE_HEIGHT
;
314 // widen window, if it is too small
315 int text_width
= StartMenuButton::GetTextWidth(title
,_hwnd
) + 16/*icon*/ + 10/*placeholder*/ + 16/*arrow*/;
317 ClientRect
clnt(_hwnd
);
318 int cx
= clnt
.right
- _border_left
;
320 rect
.right
+= text_width
-cx
;
322 MoveWindow(_hwnd
, rect
.left
, rect
.top
, rect
.right
-rect
.left
, rect
.bottom
-rect
.top
, TRUE
);
324 StartMenuCtrl(_hwnd
, _border_left
, rect
.bottom
-rect
.top
-STARTMENU_LINE_HEIGHT
-6, rect
.right
-rect
.left
-_border_left
,
325 title
, id
, hIcon
, hasSubmenu
, style
);
328 void StartMenu::AddSeparator()
330 WindowRect
rect(_hwnd
);
332 rect
.top
-= STARTMENU_SEP_HEIGHT
;
335 rect
.top
+= STARTMENU_LINE_HEIGHT
;
336 rect
.bottom
+= STARTMENU_LINE_HEIGHT
;
339 MoveWindow(_hwnd
, rect
.left
, rect
.top
, rect
.right
-rect
.left
, rect
.bottom
-rect
.top
, TRUE
);
341 StartMenuSeparator(_hwnd
, _border_left
, rect
.bottom
-rect
.top
-STARTMENU_SEP_HEIGHT
-6, rect
.right
-rect
.left
-_border_left
);
345 bool StartMenu::CloseOtherSubmenus(int id
)
348 if (IsWindow(_submenu
)) {
349 if (_submenu_id
== id
)
352 DestroyWindow(_submenu
);
354 // _submenu should be reset automatically by PM_STARTMENU_CLOSED, but safety first...
365 void StartMenu::CreateSubmenu(int id
, const StartMenuFolders
& new_folders
, CREATORFUNC creator
)
367 // Only open one submenu at a time.
368 if (!CloseOtherSubmenus(id
))
371 HWND btn
= GetDlgItem(_hwnd
, id
);
377 x
= pos
.right
-3; // Submenus should overlap their parent a bit.
378 y
= pos
.top
+STARTMENU_LINE_HEIGHT
-3;
380 WindowRect
pos(_hwnd
);
387 _submenu
= StartMenu::Create(x
, y
, new_folders
, _hwnd
, creator
);
390 void StartMenu::CreateSubmenu(int id
, int folder_id
, CREATORFUNC creator
)
392 StartMenuFolders new_folders
;
394 SpecialFolderPath
folder(folder_id
, _hwnd
);
397 new_folders
.push_back(folder
);
399 CreateSubmenu(id
, new_folders
, creator
);
402 void StartMenu::CreateSubmenu(int id
, int folder_id1
, int folder_id2
, CREATORFUNC creator
)
404 StartMenuFolders new_folders
;
406 SpecialFolderPath
folder1(folder_id1
, _hwnd
);
409 new_folders
.push_back(folder1
);
411 SpecialFolderPath
folder2(folder_id2
, _hwnd
);
414 new_folders
.push_back(folder2
);
416 CreateSubmenu(id
, new_folders
, creator
);
420 void StartMenu::ActivateEntry(int id
, ShellEntry
* entry
)
422 if (entry
->_data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
423 // Only open one submenu at a time.
424 if (!CloseOtherSubmenus(id
))
427 StartMenuFolders new_folders
;
429 new_folders
.push_back(entry
->create_absolute_pidl(_hwnd
));
431 //TODO: merge all entries of subdirectories with the same name, like "All Users\...\Accessories" and "<user>\...\Accessories"
433 CreateSubmenu(id
, new_folders
);
435 entry
->launch_entry(_hwnd
); //TODO: launch in the background; specify correct HWND for error message box titles
437 // close start menus after launching the selected entry
443 /// close all windows of the start menu popup
444 void StartMenu::CloseStartMenu(int id
)
446 if (!SendParent(PM_STARTENTRY_LAUNCHED
, id
, (LPARAM
)_hwnd
))
447 DestroyWindow(_hwnd
);
451 int StartMenuButton::GetTextWidth(LPCTSTR title
, HWND hwnd
)
453 WindowCanvas
canvas(hwnd
);
454 FontSelection
font(canvas
, GetStockFont(DEFAULT_GUI_FONT
));
456 RECT rect
= {0, 0, 0, 0};
457 DrawText(canvas
, title
, -1, &rect
, DT_SINGLELINE
|DT_NOPREFIX
|DT_CALCRECT
);
459 return rect
.right
-rect
.left
;
463 LRESULT
StartMenuButton::WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
467 // automatically set the focus to startmenu entries when moving the mouse over them
468 if (GetFocus()!=_hwnd
&& !(GetWindowStyle(_hwnd
)&WS_DISABLED
))
473 PostParent(PM_STARTENTRY_FOCUSED
, _hasSubmenu
, (LPARAM
)_hwnd
);
477 // route WM_CANCELMODE to the startmenu window
478 return SendParent(nmsg
, wparam
, lparam
);
481 return super::WndProc(nmsg
, wparam
, lparam
);
487 void StartMenuButton::DrawItem(LPDRAWITEMSTRUCT dis
)
489 UINT style
= DFCS_BUTTONPUSH
;
491 if (dis
->itemState
& ODS_DISABLED
)
492 style
|= DFCS_INACTIVE
;
494 POINT iconPos
= {dis
->rcItem
.left
+2, (dis
->rcItem
.top
+dis
->rcItem
.bottom
-16)/2};
495 RECT textRect
= {dis
->rcItem
.left
+16+4, dis
->rcItem
.top
+2, dis
->rcItem
.right
-4, dis
->rcItem
.bottom
-4};
497 if (dis
->itemState
& ODS_SELECTED
) {
498 style
|= DFCS_PUSHED
;
499 ++iconPos
.x
; ++iconPos
.y
;
500 ++textRect
.left
; ++textRect
.top
;
501 ++textRect
.right
; ++textRect
.bottom
;
504 int bk_color
= COLOR_BTNFACE
;
505 int text_color
= COLOR_BTNTEXT
;
507 if (dis
->itemState
& ODS_FOCUS
) {
508 bk_color
= COLOR_HIGHLIGHT
;
509 text_color
= COLOR_HIGHLIGHTTEXT
;
512 HBRUSH bk_brush
= GetSysColorBrush(bk_color
);
514 FillRect(dis
->hDC
, &dis
->rcItem
, bk_brush
);
515 DrawIconEx(dis
->hDC
, iconPos
.x
, iconPos
.y
, _hIcon
, 16, 16, 0, bk_brush
, DI_NORMAL
);
517 // draw submenu arrow at the right
519 static SmallIcon
arrowIcon(IDI_ARROW
);
520 static SmallIcon
selArrowIcon(IDI_ARROW_SELECTED
);
522 DrawIconEx(dis
->hDC
, dis
->rcItem
.right
-16, iconPos
.y
,
523 dis
->itemState
&ODS_FOCUS
?selArrowIcon
:arrowIcon
, 16, 16, 0, bk_brush
, DI_NORMAL
);
526 TCHAR title
[BUFFER_LEN
];
527 GetWindowText(_hwnd
, title
, BUFFER_LEN
);
529 if (dis
->itemState
& (ODS_DISABLED
|ODS_GRAYED
))
530 DrawGrayText(dis
, &textRect
, title
, DT_SINGLELINE
|DT_NOPREFIX
|DT_VCENTER
);
532 BkMode
mode(dis
->hDC
, TRANSPARENT
);
533 TextColor
lcColor(dis
->hDC
, GetSysColor(text_color
));
534 DrawText(dis
->hDC
, title
, -1, &textRect
, DT_SINGLELINE
|DT_NOPREFIX
|DT_VCENTER
);
539 StartMenuRoot::StartMenuRoot(HWND hwnd
)
542 // insert directory "All Users\Start Menu"
543 ShellDirectory
cmn_startmenu(Desktop(), SpecialFolderPath(CSIDL_COMMON_STARTMENU
, _hwnd
), _hwnd
);
544 _dirs
.push_back(StartMenuDirectory(cmn_startmenu
, false)); // don't add subfolders
546 // insert directory "<user name>\Start Menu"
547 ShellDirectory
usr_startmenu(Desktop(), SpecialFolderPath(CSIDL_STARTMENU
, _hwnd
), _hwnd
);
548 _dirs
.push_back(StartMenuDirectory(usr_startmenu
, false)); // don't add subfolders
550 // read size of logo bitmap
552 GetObject(ResBitmap(IDB_LOGOV
), sizeof(BITMAP
), &bmp_hdr
);
553 _logo_size
.cx
= bmp_hdr
.bmWidth
;
554 _logo_size
.cy
= bmp_hdr
.bmHeight
;
556 _border_left
= _logo_size
.cx
;
560 HWND
StartMenuRoot::Create(HWND hwndDesktopBar
)
562 WindowRect
pos(hwndDesktopBar
);
564 return Window::Create(WINDOW_CREATOR(StartMenuRoot
), 0, GetWndClasss(), TITLE_STARTMENU
,
565 WS_POPUP
|WS_THICKFRAME
|WS_CLIPCHILDREN
|WS_VISIBLE
, pos
.left
, pos
.top
-4, STARTMENU_WIDTH_MIN
, 4, hwndDesktopBar
);
569 void StartMenuRoot::TrackStartmenu()
574 while(IsWindow(hwnd
)) {
575 if (!GetMessage(&msg
, 0, 0, 0)) {
576 PostQuitMessage(msg
.wParam
);
580 // Check for a mouse click on any window, which is not part of the start menu
581 if (msg
.message
==WM_LBUTTONDOWN
|| msg
.message
==WM_MBUTTONDOWN
|| msg
.message
==WM_RBUTTONDOWN
) {
582 StartMenu
* menu_wnd
= NULL
;
584 for(HWND hwnd
=msg
.hwnd
; hwnd
; hwnd
=GetParent(hwnd
)) {
585 menu_wnd
= WINDOW_DYNAMIC_CAST(StartMenu
, hwnd
);
592 DestroyWindow(_hwnd
);
598 if (pretranslate_msg(&msg
))
601 if (dispatch_dialog_msg(&msg
))
604 TranslateMessage(&msg
);
607 DispatchMessage(&msg
);
608 } catch(COMException
& e
) {
609 HandleException(e
, g_Globals
._hMainWnd
);
611 } catch(COMException
& e
) {
612 HandleException(e
, g_Globals
._hMainWnd
);
618 LRESULT
StartMenuRoot::Init(LPCREATESTRUCT pcs
)
620 // add buttons for entries in _entries
621 if (super::Init(pcs
))
624 AddButton(ResString(IDS_EXPLORE
), SmallIcon(IDI_EXPLORER
), false, IDC_EXPLORE
);
628 // insert hard coded start entries
629 AddButton(ResString(IDS_PROGRAMS
), 0, true, IDC_PROGRAMS
);
630 AddButton(ResString(IDS_FAVORITES
), 0, true, IDC_FAVORITES
);
631 AddButton(ResString(IDS_DOCUMENTS
), 0, true, IDC_DOCUMENTS
);
632 AddButton(ResString(IDS_RECENT
), 0, true, IDC_RECENT
);
633 AddButton(ResString(IDS_SETTINGS
), 0, true, IDC_SETTINGS
);
634 AddButton(ResString(IDS_PRINTERS
), 0, true, IDC_PRINTERS
);
635 AddButton(ResString(IDS_SETTINGS_WND
), 0, false, IDC_SETTINGS_WND
);
636 AddButton(ResString(IDS_ADMIN
), 0, true, IDC_ADMIN
);
637 AddButton(ResString(IDS_DRIVES
), 0, true, IDC_DRIVES
);
638 AddButton(ResString(IDS_NETWORK
), 0, true, IDC_NETWORK
);
639 AddButton(ResString(IDS_CONNECTIONS
), 0, true, IDC_CONNECTIONS
);
640 AddButton(ResString(IDS_SEARCH
), 0, false, IDC_SEARCH
);
641 AddButton(ResString(IDS_SEARCH_COMPUTER
),0,false, IDC_SEARCH_COMPUTER
);
642 AddButton(ResString(IDS_START_HELP
), 0, false, IDC_START_HELP
);
643 AddButton(ResString(IDS_LAUNCH
), 0, false, IDC_LAUNCH
);
647 AddButton(ResString(IDS_LOGOFF
), SmallIcon(IDI_LOGOFF
), false, IDC_LOGOFF
);
648 AddButton(ResString(IDS_SHUTDOWN
), SmallIcon(IDI_LOGOFF
), false, IDC_SHUTDOWN
);
654 LRESULT
StartMenuRoot::WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
658 PaintCanvas
canvas(_hwnd
);
660 ResBitmap
bmp(IDB_LOGOV
);
661 BitmapSelection
sel(mem_dc
, bmp
);
663 ClientRect
clnt(_hwnd
);
664 int h
= min(_logo_size
.cy
, clnt
.bottom
);
666 RECT rect
= {0, 0, _logo_size
.cx
-1, clnt
.bottom
-h
};
667 HBRUSH hbr
= CreateSolidBrush(RGB(166,202,240)); // same color as the background color in the logo bitmap
668 FillRect(canvas
, &rect
, hbr
);
669 PatBlt(canvas
, _logo_size
.cx
-1, 0, 1, clnt
.bottom
-h
, WHITENESS
);
672 BitBlt(canvas
, 0, clnt
.bottom
-h
, _logo_size
.cx
, h
, mem_dc
, 0, 0, SRCCOPY
);
676 return super::WndProc(nmsg
, wparam
, lparam
);
683 int StartMenuRoot::Command(int id
, int code
)
687 CreateSubmenu(id
, CSIDL_COMMON_PROGRAMS
, CSIDL_PROGRAMS
);
691 explorer_show_frame(_hwnd
, SW_SHOWNORMAL
);
696 HWND hwndDesktopBar
= GetWindow(_hwnd
, GW_OWNER
);
698 ShowLaunchDialog(hwndDesktopBar
);
702 CreateSubmenu(id
, CSIDL_PERSONAL
);
706 CreateSubmenu(id
, CSIDL_RECENT
, STARTMENU_CREATOR(RecentStartMenu
));
710 CreateSubmenu(id
, CSIDL_CONTROLS
);
714 CreateSubmenu(id
, CSIDL_PRINTERS
, CSIDL_PRINTHOOD
);
717 case IDC_SETTINGS_WND
:
719 MainFrame::Create(_T("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"), FALSE
);
723 CreateSubmenu(id
, CSIDL_FAVORITES
);
727 CreateSubmenu(id
, CSIDL_COMMON_ADMINTOOLS
, CSIDL_ADMINTOOLS
);
731 CreateSubmenu(id
, CSIDL_NETWORK
);
734 case IDC_CONNECTIONS
:
735 CreateSubmenu(id
, CSIDL_CONNECTIONS
);
739 //TODO: exclude removeable drives
740 CreateSubmenu(id
, CSIDL_DRIVES
);
747 case IDC_SEARCH_COMPUTER
:
748 ShowSearchComputer();
752 /* The shell32 Dialog prompts about some system setting change. This is not what we want to display here.
753 HWND hwndDesktopBar = GetWindow(_hwnd, GW_OWNER);
755 ShowRestartDialog(hwndDesktopBar, EWX_LOGOFF);*/
756 DestroyWindow(GetParent(_hwnd
));
760 HWND hwndDesktopBar
= GetWindow(_hwnd
, GW_OWNER
);
762 ShowExitWindowsDialog(hwndDesktopBar
);
766 return super::Command(id
, code
);
773 void StartMenuRoot::ShowLaunchDialog(HWND hwndDesktopBar
)
775 //TODO: All text phrases should be put into the resources.
776 static LPCSTR szTitle
= "Create New Task";
777 static LPCSTR szText
= "Type the name of a program, folder, document, or Internet resource, and Task Manager will open it for you.";
779 HMODULE hShell32
= GetModuleHandle(_T("SHELL32"));
780 RUNFILEDLG RunFileDlg
= (RUNFILEDLG
)GetProcAddress(hShell32
, (LPCSTR
)61);
782 // Show "Run..." dialog
785 if ((HIWORD(GetVersion())>>14) == W_VER_NT
) {
786 WCHAR wTitle
[40], wText
[256];
788 MultiByteToWideChar(CP_ACP
, 0, szTitle
, -1, wTitle
, 40);
789 MultiByteToWideChar(CP_ACP
, 0, szText
, -1, wText
, 256);
791 RunFileDlg(hwndDesktopBar
, 0, NULL
, (LPCSTR
)wTitle
, (LPCSTR
)wText
, RFF_CALCDIRECTORY
);
794 RunFileDlg(hwndDesktopBar
, 0, NULL
, szTitle
, szText
, RFF_CALCDIRECTORY
);
798 void StartMenuRoot::ShowExitWindowsDialog(HWND hwndOwner
)
800 HMODULE hShell32
= GetModuleHandle(_T("SHELL32"));
801 EXITWINDOWSDLG ExitWindowsDlg
= (EXITWINDOWSDLG
)GetProcAddress(hShell32
, (LPCSTR
)60);
804 ExitWindowsDlg(hwndOwner
);
807 void StartMenuRoot::ShowRestartDialog(HWND hwndOwner
, UINT flags
)
809 HMODULE hShell32
= GetModuleHandle(_T("SHELL32"));
810 RESTARTWINDOWSDLG RestartDlg
= (RESTARTWINDOWSDLG
)GetProcAddress(hShell32
, (LPCSTR
)59);
813 RestartDlg(hwndOwner
, (LPWSTR
)L
"You selected <Log Off>.\n\n", flags
); //TODO: ANSI string conversion if needed
816 void StartMenuRoot::ShowSearchDialog()
818 HMODULE hShell32
= GetModuleHandle(_T("SHELL32"));
819 SHFINDFILES SHFindFiles
= (SHFINDFILES
)GetProcAddress(hShell32
, (LPCSTR
)90);
822 SHFindFiles(NULL
, NULL
);
825 void StartMenuRoot::ShowSearchComputer()
827 HMODULE hShell32
= GetModuleHandle(_T("SHELL32"));
828 SHFINDCOMPUTER SHFindComputer
= (SHFINDCOMPUTER
)GetProcAddress(hShell32
, (LPCSTR
)91);
831 SHFindComputer(NULL
, NULL
);
835 RecentStartMenu::RecentStartMenu(HWND hwnd
, const StartMenuFolders
& info
)
840 void RecentStartMenu::AddEntries()
842 for(StartMenuShellDirs::iterator it
=_dirs
.begin(); it
!=_dirs
.end(); ++it
) {
843 StartMenuDirectory
& smd
= *it
;
844 ShellDirectory
& dir
= smd
._dir
;
848 dir
.sort_directory(SORT_DATE
);
849 AddShellEntries(dir
, 16, smd
._subfolders
); //TODO: read max. count of entries from registry