//
- // Explorer clone, lean version
+ // Explorer clone
//
// startmenu.cpp
//
//
-#include "../utility/utility.h"
+#include "precomp.h"
-#include "../explorer.h"
-#include "../globals.h"
-#include "../externals.h"
#include "../explorer_intres.h"
#include "desktopbar.h"
#include "startmenu.h"
+#include "../dialogs/searchprogram.h"
#include "../dialogs/settings.h"
+#define SHELLPATH_CONTROL_PANEL TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}")
+#define SHELLPATH_PRINTERS TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{2227A280-3AEA-1069-A2DE-08002B30309D}")
+#define SHELLPATH_NET_CONNECTIONS TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}")
+
+
StartMenu::StartMenu(HWND hwnd)
: super(hwnd)
{
_next_id = IDC_FIRST_MENU;
_submenu_id = 0;
+
_border_left = 0;
_border_top = 0;
+ _bottom_max = INT_MAX;
+
+ _floating_btn = false;
+ _arrow_btns = false;
+ _scroll_mode = SCROLL_NOT;
+ _scroll_pos = 0;
+ _invisible_lines = 0;
+
_last_pos = WindowRect(hwnd).pos();
#ifdef _LIGHT_STARTMENU
_selected_id = -1;
_next_id = IDC_FIRST_MENU;
_submenu_id = 0;
+
_border_left = 0;
_border_top = create_info._border_top;
+ _bottom_max = INT_MAX;
+
+ _floating_btn = create_info._border_top? true: false;
+ _arrow_btns = false;
+ _scroll_mode = SCROLL_NOT;
+ _scroll_pos = 0;
+ _invisible_lines = 0;
+
_last_pos = WindowRect(hwnd).pos();
#ifdef _LIGHT_STARTMENU
_selected_id = -1;
Window::CREATORFUNC_INFO StartMenu::s_def_creator = STARTMENU_CREATOR(StartMenu);
-HWND StartMenu::Create(int x, int y, const StartMenuFolders& folders, HWND hwndParent, LPCTSTR title, CREATORFUNC_INFO creator)
+HWND StartMenu::Create(int x, int y, const StartMenuFolders& folders, HWND hwndParent, LPCTSTR title, CREATORFUNC_INFO creator, void* info)
{
UINT style, ex_style;
int top_height;
create_info._folders = folders;
create_info._border_top = top_height;
create_info._creator = creator;
+ create_info._info = info;
if (title)
create_info._title = title;
}
-LRESULT StartMenu::Init(LPCREATESTRUCT pcs)
+LRESULT StartMenu::Init(LPCREATESTRUCT pcs)
{
try {
AddEntries();
WaitCursor wait;
#ifdef _LAZY_ICONEXTRACT
- dir.smart_scan(SCAN_FILESYSTEM); // lazy icon extraction, try to read directly from filesystem
+ dir.smart_scan(SORT_NAME, SCAN_FILESYSTEM); // lazy icon extraction, try to read directly from filesystem
#else
- dir.smart_scan(SCAN_EXTRACT_ICONS|SCAN_FILESYSTEM);
+ dir.smart_scan(SORT_NAME, SCAN_EXTRACT_ICONS|SCAN_FILESYSTEM);
#endif
}
WindowRect pos(_hwnd);
///@todo do something similar to StartMenuRoot::TrackStartmenu() in order to automatically close submenus when clicking on the desktop background
- StartMenu::Create(pos.left+3, pos.bottom-3, _create_info._folders, 0, _create_info._title, _create_info._creator);
+ StartMenu::Create(pos.left+3, pos.bottom-3, _create_info._folders, 0, _create_info._title, _create_info._creator, _create_info._info);
CloseStartMenu();
}
case WM_CANCELMODE:
CloseStartMenu();
+
+#ifdef _LIGHT_STARTMENU
+ if (_scroll_mode != SCROLL_NOT) {
+ ReleaseCapture();
+ KillTimer(_hwnd, 0);
+ }
+#endif
break;
#ifdef _LIGHT_STARTMENU
case WM_MOUSEMOVE: {
// automatically set the focus to startmenu entries when moving the mouse over them
if (lparam != _last_mouse_pos) { // don't process WM_MOUSEMOVE when opening submenus using keyboard navigation
- int new_id = ButtonHitTest(Point(lparam));
+ Point pt(lparam);
+
+ if (_arrow_btns) {
+ RECT rect_up, rect_down;
- if (new_id != _selected_id)
+ GetArrowButtonRects(&rect_up, &rect_down);
+
+ SCROLL_MODE scroll_mode = SCROLL_NOT;
+
+ if (PtInRect(&rect_up, pt))
+ scroll_mode = SCROLL_UP;
+ else if (PtInRect(&rect_down, pt))
+ scroll_mode = SCROLL_DOWN;
+
+ if (scroll_mode != _scroll_mode) {
+ if (scroll_mode == SCROLL_NOT) {
+ ReleaseCapture();
+ KillTimer(_hwnd, 0);
+ } else {
+ CloseSubmenus();
+ SetTimer(_hwnd, 0, 150, NULL); // 150 ms scroll interval
+ SetCapture(_hwnd);
+ }
+
+ _scroll_mode = scroll_mode;
+ }
+ }
+
+ int new_id = ButtonHitTest(pt);
+
+ if (new_id > 0 && new_id != _selected_id)
SelectButton(new_id);
_last_mouse_pos = lparam;
}
break;}
+ case WM_TIMER:
+ if (_scroll_mode == SCROLL_UP) {
+ if (_scroll_pos > 0) {
+ --_scroll_pos;
+ InvalidateRect(_hwnd, NULL, TRUE);
+ }
+ } else {
+ if (_scroll_pos <= _invisible_lines) {
+ ++_scroll_pos;
+ InvalidateRect(_hwnd, NULL, TRUE);
+ }
+ }
+ break;
+
case WM_KEYDOWN:
ProcessKey(wparam);
break;
break;
case PM_SELECT_ENTRY:
- SelectButtonIndex(0, wparam?true:false);
+ SelectButtonIndex(0, wparam!=0);
break;
+#ifdef _LIGHT_STARTMENU
+ case WM_CONTEXTMENU: {
+ Point screen_pt(lparam), clnt_pt=screen_pt;
+ ScreenToClient(_hwnd, &clnt_pt);
+
+ int id = ButtonHitTest(clnt_pt);
+
+ if (id) {
+ StartMenuEntry& sme = _entries[id];
+
+ for(ShellEntrySet::iterator it=sme._entries.begin(); it!=sme._entries.end(); ++it) {
+ Entry* entry = *it;
+
+ if (entry) {
+ CHECKERROR(entry->do_context_menu(_hwnd, screen_pt, _cm_ifs)); // may close start menu because of focus loss
+ break; ///@todo handle context menu for more than one entry
+ }
+ }
+ }
+ break;}
+#endif
+
default: def:
return super::WndProc(nmsg, wparam, lparam);
}
if (pt.x<rect.left || pt.x>rect.right)
return 0;
- for(SMBtnVector::const_iterator it=_buttons.begin(); it!=_buttons.end(); ++it) {
+ for(SMBtnVector::const_iterator it=_buttons.begin()+_scroll_pos; it!=_buttons.end(); ++it) {
const SMBtnInfo& info = *it;
if (rect.top > pt.y)
rect.bottom = rect.top + (info._id==-1? STARTMENU_SEP_HEIGHT: STARTMENU_LINE_HEIGHT);
+ if (rect.bottom > _bottom_max)
+ break;
+
if (pt.y < rect.bottom) // PtInRect(&rect, pt)
return info._id;
void StartMenu::InvalidateSelection()
{
- if (!_selected_id)
+ if (_selected_id <= 0)
return;
ClientRect clnt(_hwnd);
RECT rect = {_border_left, _border_top, clnt.right, STARTMENU_LINE_HEIGHT};
- for(SMBtnVector::const_iterator it=_buttons.begin(); it!=_buttons.end(); ++it) {
+ for(SMBtnVector::const_iterator it=_buttons.begin()+_scroll_pos; it!=_buttons.end(); ++it) {
const SMBtnInfo& info = *it;
rect.bottom = rect.top + (info._id==-1? STARTMENU_SEP_HEIGHT: STARTMENU_LINE_HEIGHT);
ClientRect clnt(_hwnd);
RECT rect = {_border_left, _border_top, clnt.right, STARTMENU_LINE_HEIGHT};
- for(SMBtnVector::const_iterator it=_buttons.begin(); it!=_buttons.end(); ++it) {
+ for(SMBtnVector::const_iterator it=_buttons.begin()+_scroll_pos; it!=_buttons.end(); ++it) {
const SMBtnInfo& info = *it;
rect.bottom = rect.top + (info._id==-1? STARTMENU_SEP_HEIGHT: STARTMENU_LINE_HEIGHT);
}
+void StartMenu::DrawArrows(HDC hdc)
+{
+ static ResIconEx arrowUpIcon(IDI_ARROW_UP, 8, 4);
+ static ResIconEx arrowDownIcon(IDI_ARROW_DOWN, 8, 4);
+
+ ClientRect clnt(_hwnd);
+
+ DrawIconEx(hdc, clnt.right/2-4, _floating_btn?3:1, arrowUpIcon, 8, 4, 0, 0, DI_NORMAL);
+ DrawIconEx(hdc, clnt.right/2-4, clnt.bottom-5, arrowDownIcon, 8, 4, 0, 0, DI_NORMAL);
+}
+
+void StartMenu::GetArrowButtonRects(LPRECT prect_up, LPRECT prect_down)
+{
+ GetClientRect(_hwnd, prect_up);
+ *prect_down = *prect_up;
+
+// prect_up->left = prect_up->right/2 - 4;
+// prect_up->right = prect_up->left + 8;
+ prect_up->right -= 8;
+ prect_up->top = _floating_btn? 3: 1;
+ prect_up->bottom = prect_up->top + 4;
+
+// prect_down->left = prect_down->right/2 - 4;
+// prect_down->right = prect_down->left + 8;
+ prect_down->right -= 8;
+ prect_down->top = prect_down->bottom - 5;
+}
+
+
void StartMenu::Paint(PaintCanvas& canvas)
{
- if (_border_top)
+ if (_floating_btn)
DrawFloatingButton(canvas);
#ifdef _LIGHT_STARTMENU
+ if (_arrow_btns)
+ DrawArrows(canvas);
+
ClientRect clnt(_hwnd);
RECT rect = {_border_left, _border_top, clnt.right, STARTMENU_LINE_HEIGHT};
FontSelection font(canvas, GetStockFont(DEFAULT_GUI_FONT));
BkMode bk_mode(canvas, TRANSPARENT);
- for(SMBtnVector::const_iterator it=_buttons.begin(); it!=_buttons.end(); ++it) {
+ for(SMBtnVector::const_iterator it=_buttons.begin()+_scroll_pos; it!=_buttons.end(); ++it) {
const SMBtnInfo& btn = *it;
if (rect.top > canvas.rcPaint.bottom)
if (btn._id == -1) { // a separator?
rect.bottom = rect.top + STARTMENU_SEP_HEIGHT;
+ if (rect.bottom > _bottom_max)
+ break;
+
BrushSelection brush_sel(canvas, GetSysColorBrush(COLOR_BTNSHADOW));
PatBlt(canvas, rect.left+2, rect.top+STARTMENU_SEP_HEIGHT/2-1, sep_width, 1, PATCOPY);
} else {
rect.bottom = rect.top + STARTMENU_LINE_HEIGHT;
+ if (rect.bottom > _bottom_max)
+ break;
+
if (rect.top >= canvas.rcPaint.top)
DrawStartMenuButton(canvas, rect, btn._title, btn, btn._id==_selected_id, false);
}
#ifdef _SINGLE_ICONEXTRACT
//if (idx >= 0)
- int idx = 0;
+ int idx = _scroll_pos;
for(; idx<(int)_buttons.size(); ++idx) {
SMBtnInfo& btn = _buttons[idx];
Entry* entry = *it;
if (entry->_icon_id == ICID_UNKNOWN)
- entry->extract_icon();
+ try {
+ entry->extract_icon();
+ } catch(COMException&) {
+ // ignore unexpected exceptions while extracting icons
+ }
if (entry->_icon_id > ICID_NONE) {
btn._icon_id = (ICON_ID)/*@@*/ entry->_icon_id;
RECT rect;
GetButtonRect(btn._id, &rect);
+
+ if (rect.bottom > _bottom_max)
+ break;
+
WindowCanvas canvas(_hwnd);
DrawStartMenuButton(canvas, rect, NULL, btn, btn._id==_selected_id, false);
}
-StartMenuEntry& StartMenu::AddEntry(const String& title, ICON_ID icon_id, Entry* entry)
+ShellEntryMap::iterator StartMenu::AddEntry(const String& title, ICON_ID icon_id, Entry* entry)
{
// search for an already existing subdirectory entry with the same name
if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
for(ShellEntryMap::iterator it=_entries.begin(); it!=_entries.end(); ++it) {
StartMenuEntry& sme = it->second;
- if (sme._title == title) ///@todo speed up by using a map indexed by name
+ if (!_tcsicmp(sme._title, title)) ///@todo speed up by using a map indexed by name
for(ShellEntrySet::iterator it2=sme._entries.begin(); it2!=sme._entries.end(); ++it2) {
if ((*it2)->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
// merge the new shell entry with the existing of the same name
sme._entries.insert(entry);
- return sme;
+
+ return it;
}
}
}
- StartMenuEntry& sme = AddEntry(title, icon_id);
+ ShellEntryMap::iterator sme = AddEntry(title, icon_id);
- sme._entries.insert(entry);
+ sme->second._entries.insert(entry);
return sme;
}
-StartMenuEntry& StartMenu::AddEntry(const String& title, ICON_ID icon_id, int id)
+ShellEntryMap::iterator StartMenu::AddEntry(const String& title, ICON_ID icon_id, int id)
{
if (id == -1)
id = ++_next_id;
- StartMenuEntry& sme = _entries[id];
+ StartMenuEntry sme;
sme._title = title;
sme._icon_id = icon_id;
- return sme;
+ ShellEntryMap::iterator it = _entries.insert(make_pair(id, sme)).first;
+
+ return it;
}
-StartMenuEntry& StartMenu::AddEntry(const ShellFolder folder, ShellEntry* entry)
+ShellEntryMap::iterator StartMenu::AddEntry(const ShellFolder folder, ShellEntry* entry)
{
ICON_ID icon_id;
return AddEntry(folder.get_name(entry->_pidl), icon_id, entry);
}
-StartMenuEntry& StartMenu::AddEntry(const ShellFolder folder, Entry* entry)
+ShellEntryMap::iterator StartMenu::AddEntry(const ShellFolder folder, Entry* entry)
{
ICON_ID icon_id;
}
-void StartMenu::CreateSubmenu(int id, LPCTSTR title, CREATORFUNC_INFO creator)
+void StartMenu::CreateSubmenu(int id, LPCTSTR title, CREATORFUNC_INFO creator, void* info)
{
- CreateSubmenu(id, StartMenuFolders(), title, creator);
+ CreateSubmenu(id, StartMenuFolders(), title, creator, info);
}
-bool StartMenu::CreateSubmenu(int id, int folder_id, LPCTSTR title, CREATORFUNC_INFO creator)
+bool StartMenu::CreateSubmenu(int id, int folder_id, LPCTSTR title, CREATORFUNC_INFO creator, void* info)
{
try {
SpecialFolderPath folder(folder_id, _hwnd);
StartMenuFolders new_folders;
new_folders.push_back(folder);
- CreateSubmenu(id, new_folders, title, creator);
+ CreateSubmenu(id, new_folders, title, creator, info);
return true;
} catch(COMException&) {
}
}
-bool StartMenu::CreateSubmenu(int id, int folder_id1, int folder_id2, LPCTSTR title, CREATORFUNC_INFO creator)
+bool StartMenu::CreateSubmenu(int id, int folder_id1, int folder_id2, LPCTSTR title, CREATORFUNC_INFO creator, void* info)
{
StartMenuFolders new_folders;
}
if (!new_folders.empty()) {
- CreateSubmenu(id, new_folders, title, creator);
+ CreateSubmenu(id, new_folders, title, creator, info);
return true;
} else {
CloseOtherSubmenus(id);
}
}
-void StartMenu::CreateSubmenu(int id, const StartMenuFolders& new_folders, LPCTSTR title, CREATORFUNC_INFO creator)
+void StartMenu::CreateSubmenu(int id, const StartMenuFolders& new_folders, LPCTSTR title, CREATORFUNC_INFO creator, void* info)
{
// Only open one submenu at a time.
if (!CloseOtherSubmenus(id))
ClientToScreen(_hwnd, &rect);
x = rect.right; // Submenus should overlap their parent a bit.
- y = rect.top+STARTMENU_LINE_HEIGHT-_border_top;
+ y = rect.top+STARTMENU_LINE_HEIGHT +_border_top/*own border*/ -STARTMENU_TOP_BTN_SPACE/*border of new submenu*/;
} else {
WindowRect pos(_hwnd);
}
_submenu_id = id;
- _submenu = StartMenu::Create(x, y, new_folders, _hwnd, title, creator);
+ _submenu = StartMenu::Create(x, y, new_folders, _hwnd, title, creator, info);
}
if (title.empty())
title = entry->_display_name;
} else {
- // If the entry is no subdirectory, there can only be one shell entry.
+ // The entry is no subdirectory, so there can only be one shell entry.
assert(entries.size()==1);
HWND hparent = GetParent(_hwnd);
ShellPath shell_path = entry->create_absolute_pidl();
- // close start menus after launching the selected entry
+ // close start menus when launching the selected entry
CloseStartMenu(id);
///@todo launch in the background; specify correct HWND for error message box titles
SHELLEXECUTEINFO shexinfo;
shexinfo.cbSize = sizeof(SHELLEXECUTEINFO);
- shexinfo.fMask = SEE_MASK_INVOKEIDLIST; // SEE_MASK_IDLIST is also possible.
+ shexinfo.fMask = SEE_MASK_IDLIST; // SEE_MASK_INVOKEIDLIST is also possible.
shexinfo.hwnd = hparent;
shexinfo.lpVerb = NULL;
shexinfo.lpFile = NULL;
// move down if we are too high
if (rect.top < 0) {
- rect.top += STARTMENU_LINE_HEIGHT;
- rect.bottom += STARTMENU_LINE_HEIGHT;
+ int dy = -rect.top;
+ rect.top += dy;
+ rect.bottom += dy;
+ }
+
+ // enable scroll mode for long start menus, which span more than the whole screen height
+ int cyscreen = GetSystemMetrics(SM_CYSCREEN);
+ int bottom_max = 0;
+
+ if (rect.bottom > cyscreen) {
+ _arrow_btns = true;
+
+ _invisible_lines = (rect.bottom-cyscreen+(STARTMENU_LINE_HEIGHT-1))/STARTMENU_LINE_HEIGHT + 1;
+ rect.bottom -= _invisible_lines * STARTMENU_LINE_HEIGHT;
+
+ bottom_max = rect.bottom;
+
+ if (_floating_btn)
+ rect.bottom += 6; // lower scroll arrow
+ else {
+ _border_top += 6; // upper scroll arrow
+ rect.bottom += 2*6; // upper+lower scroll arrow
+ }
}
MoveWindow(_hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE);
+
+ if (bottom_max) {
+ POINT pt = {0, bottom_max};
+
+ ScreenToClient(_hwnd, &pt);
+
+ _bottom_max = pt.y;
+ }
}
#else // _LIGHT_STARTMENU
}
-HWND StartMenuRoot::Create(HWND hwndOwner)
+static void CalculateStartPos(HWND hwndOwner, RECT& rect)
{
WindowRect pos(hwndOwner);
- RECT rect = {pos.left, pos.top-STARTMENU_LINE_HEIGHT-4, pos.left+STARTMENU_WIDTH_MIN, pos.top};
+ rect.left = pos.left;
+ rect.top = pos.top-STARTMENU_LINE_HEIGHT-4;
+ rect.right = pos.left+STARTMENU_WIDTH_MIN;
+ rect.bottom = pos.top;
#ifndef _LIGHT_STARTMENU
rect.top += STARTMENU_LINE_HEIGHT;
#endif
AdjustWindowRectEx(&rect, WS_POPUP|WS_THICKFRAME|WS_CLIPCHILDREN|WS_VISIBLE, FALSE, 0);
+}
+
+HWND StartMenuRoot::Create(HWND hwndOwner)
+{
+ RECT rect;
+
+ CalculateStartPos(hwndOwner, rect);
return Window::Create(WINDOW_CREATOR(StartMenuRoot), 0, GetWndClasss(), TITLE_STARTMENU,
WS_POPUP|WS_THICKFRAME|WS_CLIPCHILDREN,
_selected_id = -1;
#endif
+#ifdef _LIGHT_STARTMENU
+ // recalculate start menu root position
+ RECT rect;
+
+ CalculateStartPos(GetParent(hwnd), rect);
+
+ SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0);
+
+ ResizeToButtons();
+#endif
+
// show previously hidden start menu
ShowWindow(hwnd, SW_SHOW);
SetForegroundWindow(hwnd);
AddButton(ResString(IDS_SETTINGS), ICID_CONFIG, true, IDC_SETTINGS);
+ AddButton(ResString(IDS_BROWSE), ICID_FOLDER, true, IDC_BROWSE);
+
#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
if (!g_Globals._SHRestricted || !SHRestricted(REST_NOFIND))
#else
AddButton(ResString(IDS_SHUTDOWN), ICID_LOGOFF, false, IDC_SHUTDOWN);
+ AddButton(ResString(IDS_TERMINATE), ICID_LOGOFF, false, IDC_TERMINATE);
+
+
#ifdef __MINGW32__
RegCloseKey(hkeyAdv);
RegCloseKey(hkey);
break;
case IDC_FAVORITES:
- CreateSubmenu(id, CSIDL_FAVORITES, ResString(IDS_FAVORITES));
+#ifndef _SHELL32_FAVORITES
+ CreateSubmenu(id, ResString(IDS_FAVORITES), STARTMENU_CREATOR(FavoritesMenu), &static_cast<BookmarkList&>(g_Globals._favorites));
+#else
+ CreateSubmenu(id, CSIDL_COMMON_FAVORITES, CSIDL_FAVORITES, ResString(IDS_FAVORITES));
+#endif
+ break;
+
+ case IDC_BROWSE:
+ CreateSubmenu(id, ResString(IDS_BROWSE), STARTMENU_CREATOR(BrowseMenu));
break;
case IDC_SETTINGS:
break;
case IDC_LOGOFF:
- /* The shell32 Dialog prompts about some system setting change. This is not what we want to display here.
CloseStartMenu(id);
- ShowRestartDialog(g_Globals._hwndDesktopBar, EWX_LOGOFF);*/
+ ShowLogoffDialog(g_Globals._hwndDesktopBar);
+ break;
+
+ case IDC_TERMINATE:
DestroyWindow(GetParent(_hwnd));
break;
ExplorerPropertySheet(g_Globals._hwndDesktopBar);
break;
- case IDC_PRINTERS:
+ case IDC_CONTROL_PANEL: {
CloseStartMenu(id);
- MainFrame::Create(SpecialFolderPath(CSIDL_PRINTERS, _hwnd), OWM_PIDL);
+#ifndef ROSSHELL
+#ifndef _NO_MDI
+ XMLPos explorer_options = g_Globals.get_cfg("general/explorer");
+ bool mdi = XMLBool(explorer_options, "mdi", true);
+
+ if (mdi)
+ MDIMainFrame::Create(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"), 0);
+ else
+#endif
+ SDIMainFrame::Create(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"), 0);
+#else
+ launch_file(_hwnd, SHELLPATH_CONTROL_PANEL);
+#endif
+ break;}
+
+ case IDC_SETTINGS_MENU:
+ CreateSubmenu(id, CSIDL_CONTROLS, ResString(IDS_SETTINGS_MENU));
break;
- case IDC_CONTROL_PANEL:
+ case IDC_PRINTERS: {
CloseStartMenu(id);
- MainFrame::Create(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"), 0);
+
+#ifndef ROSSHELL
+#ifdef _ROS_ // to be removed when printer folder will be implemented
+ MessageBox(0, TEXT("printer folder not yet implemented in SHELL32"), ResString(IDS_TITLE), MB_OK);
+#else
+#ifndef _NO_MDI
+ XMLPos explorer_options = g_Globals.get_cfg("general/explorer");
+ bool mdi = XMLBool(explorer_options, "mdi", true);
+
+ if (mdi)
+ MDIMainFrame::Create(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{2227A280-3AEA-1069-A2DE-08002B30309D}"), 0);
+ else
+#endif
+ SDIMainFrame::Create(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{2227A280-3AEA-1069-A2DE-08002B30309D}"), 0);
+#endif
+#else
+ launch_file(_hwnd, SHELLPATH_PRINTERS);
+#endif
+ break;}
+
+ case IDC_PRINTERS_MENU:
+ CreateSubmenu(id, CSIDL_PRINTERS, CSIDL_PRINTHOOD, ResString(IDS_PRINTERS));
+/* StartMenuFolders new_folders;
+
+ try {
+ new_folders.push_back(ShellPath(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{2227A280-3AEA-1069-A2DE-08002B30309D}")));
+ } catch(COMException&) {
+ }
+
+ CreateSubmenu(id, new_folders, ResString(IDS_PRINTERS));*/
break;
case IDC_ADMIN:
- CloseStartMenu(id);
- MainFrame::Create(SpecialFolderPath(CSIDL_COMMON_ADMINTOOLS, _hwnd), OWM_PIDL);
+#ifndef ROSSHELL
+ CreateSubmenu(id, CSIDL_COMMON_ADMINTOOLS, CSIDL_ADMINTOOLS, ResString(IDS_ADMIN));
+ //CloseStartMenu(id);
+ //MainFrame::Create(SpecialFolderPath(CSIDL_COMMON_ADMINTOOLS, _hwnd), OWM_PIDL);
+#else
+ launch_file(_hwnd, SpecialFolderFSPath(CSIDL_COMMON_ADMINTOOLS, _hwnd));
+#endif
break;
case IDC_CONNECTIONS:
- CloseStartMenu(id);
- MainFrame::Create(SpecialFolderPath(CSIDL_CONNECTIONS, _hwnd), OWM_PIDL);
+#ifndef ROSSHELL
+#ifdef _ROS_ // to be removed when RAS will be implemented
+ MessageBox(0, TEXT("RAS folder not yet implemented in SHELL32"), ResString(IDS_TITLE), MB_OK);
+#else
+ CreateSubmenu(id, CSIDL_CONNECTIONS, ResString(IDS_CONNECTIONS));
+ //CloseStartMenu(id);
+ //MainFrame::Create(SpecialFolderPath(CSIDL_CONNECTIONS, _hwnd), OWM_PIDL);
+#endif
+#else
+ launch_file(_hwnd, SHELLPATH_NET_CONNECTIONS);
+#endif
+ break;
+
+
+ // browse menu
+
+ case IDC_NETWORK:
+#ifdef _ROS_ // to be removed when network will be implemented
+ MessageBox(0, TEXT("network not yet implemented"), ResString(IDS_TITLE), MB_OK);
+#else
+ CreateSubmenu(id, CSIDL_NETWORK, ResString(IDS_NETWORK));
+#endif
+ break;
+
+ case IDC_DRIVES:
+ ///@todo exclude removable drives
+ CreateSubmenu(id, CSIDL_DRIVES, ResString(IDS_DRIVES));
break;
// search menu
+ case IDC_SEARCH_PROGRAM:
+ CloseStartMenu(id);
+ Dialog::DoModal(IDD_SEARCH_PROGRAM, WINDOW_CREATOR(FindProgramDlg));
+ break;
+
case IDC_SEARCH_FILES:
CloseStartMenu(id);
ShowSearchDialog();
// Show "Run..." dialog
if (RunFileDlg) {
#ifndef _ROS_ /* FIXME: our shell32 always expects Ansi strings */
-#define W_VER_NT 0
if ((HIWORD(GetVersion())>>14) == W_VER_NT) {
WCHAR wTitle[40], wText[256];
}
}
-void StartMenuHandler::ShowRestartDialog(HWND hwndOwner, UINT flags)
+void StartMenuHandler::ShowLogoffDialog(HWND hwndOwner)
{
- static DynamicFct<RESTARTWINDOWSDLG> RestartDlg(TEXT("SHELL32"), 59);
-
- if (RestartDlg)
- (*RestartDlg)(hwndOwner, (LPWSTR)L"You selected <Log Off>.\n\n", flags); ///@todo ANSI string conversion if needed
+ static DynamicFct<LOGOFFWINDOWSDIALOG> LogoffWindowsDialog(TEXT("SHELL32"), 54);
+// static DynamicFct<RESTARTWINDOWSDLG> RestartDialog(TEXT("SHELL32"), 59);
+
+ if (LogoffWindowsDialog)
+ (*LogoffWindowsDialog)(0);
+/* The RestartDialog function prompts about some system setting change. This is not what we want to display here.
+ else if (RestartDialog)
+ return (*RestartDialog)(hwndOwner, (LPWSTR)L"You selected <Log Off>.\n\n", EWX_LOGOFF) == 1; ///@todo ANSI string conversion if needed
+*/
else
- MessageBox(hwndOwner, TEXT("RestartDlg() not yet implemented in SHELL32"), ResString(IDS_TITLE), MB_OK);
+ MessageBox(hwndOwner, TEXT("LogoffWindowsDialog() not yet implemented in SHELL32"), ResString(IDS_TITLE), MB_OK);
}
void ShowExitWindowsDialog(HWND hwndOwner)
{
- static DynamicFct<EXITWINDOWSDLG> ExitWindowsDlg(TEXT("SHELL32"), 60);
+ static DynamicFct<EXITWINDOWSDLG> ExitWindowsDialog(TEXT("SHELL32"), 60);
- if (ExitWindowsDlg)
- (*ExitWindowsDlg)(hwndOwner);
+ if (ExitWindowsDialog)
+ (*ExitWindowsDialog)(hwndOwner);
else
- MessageBox(hwndOwner, TEXT("ExitWindowsDlg() not yet implemented in SHELL32"), ResString(IDS_TITLE), MB_OK);
+ MessageBox(hwndOwner, TEXT("ExitWindowsDialog() not yet implemented in SHELL32"), ResString(IDS_TITLE), MB_OK);
}
{
super::AddEntries();
+#ifdef _ROS_ // to be removed when printer/network will be implemented
+ AddButton(ResString(IDS_PRINTERS), ICID_PRINTER, false, IDC_PRINTERS_MENU);
+ AddButton(ResString(IDS_CONNECTIONS), ICID_NETWORK, false, IDC_CONNECTIONS);
+#else
+ AddButton(ResString(IDS_PRINTERS), ICID_PRINTER, true, IDC_PRINTERS_MENU);
+ AddButton(ResString(IDS_CONNECTIONS), ICID_NETWORK, true, IDC_CONNECTIONS);
+#endif
+ AddButton(ResString(IDS_ADMIN), ICID_CONFIG, true, IDC_ADMIN);
+
+#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
+ if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCONTROLPANEL))
+#endif
+ AddButton(ResString(IDS_SETTINGS_MENU), ICID_CONFIG, true, IDC_SETTINGS_MENU);
+
+ AddButton(ResString(IDS_DESKTOPBAR_SETTINGS), ICID_CONFIG, false, ID_DESKTOPBAR_SETTINGS);
+
+ AddButton(ResString(IDS_PRINTERS), ICID_PRINTER, false, IDC_PRINTERS);
+
#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCONTROLPANEL))
#endif
AddButton(ResString(IDS_CONTROL_PANEL), ICID_CONFIG, false, IDC_CONTROL_PANEL);
+}
- AddButton(ResString(IDS_PRINTERS), ICID_PRINTER, false, IDC_PRINTERS);
- AddButton(ResString(IDS_CONNECTIONS), ICID_NETWORK, false, IDC_CONNECTIONS);
- AddButton(ResString(IDS_ADMIN), ICID_CONFIG, false, IDC_ADMIN);
+void BrowseMenu::AddEntries()
+{
+ super::AddEntries();
- AddButton(ResString(IDS_DESKTOPBAR_SETTINGS), ICID_CONFIG, false, ID_DESKTOPBAR_SETTINGS);
+#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
+ if (!g_Globals._SHRestricted || !SHRestricted(REST_NONETHOOD)) // or REST_NOENTIRENETWORK ?
+#endif
+#ifdef _ROS_ // to be removed when printer/network will be implemented
+ AddButton(ResString(IDS_NETWORK), ICID_NETWORK, false, IDC_NETWORK);
+#else
+ AddButton(ResString(IDS_NETWORK), ICID_NETWORK, true, IDC_NETWORK);
+#endif
+
+ AddButton(ResString(IDS_DRIVES), ICID_FOLDER, true, IDC_DRIVES);
}
void SearchMenu::AddEntries()
{
super::AddEntries();
- AddButton(ResString(IDS_SEARCH_FILES), ICID_SEARCH_DOC, false, IDC_SEARCH_FILES);
+ AddButton(ResString(IDS_SEARCH_FILES), ICID_SEARCH_DOC, false, IDC_SEARCH_FILES);
#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
if (!g_Globals._SHRestricted || !SHRestricted(REST_HASFINDCOMPUTERS))
#endif
- AddButton(ResString(IDS_SEARCH_COMPUTER), ICID_COMPUTER, false, IDC_SEARCH_COMPUTER);
+ AddButton(ResString(IDS_SEARCH_COMPUTER),ICID_COMPUTER, false, IDC_SEARCH_COMPUTER);
+
+ AddButton(ResString(IDS_SEARCH_PRG), ICID_APPS, false, IDC_SEARCH_PROGRAM);
}
WaitCursor wait;
#ifdef _LAZY_ICONEXTRACT
- dir.smart_scan(SCAN_FILESYSTEM);
+ dir.smart_scan(SORT_NAME, SCAN_FILESYSTEM);
#else
- dir.smart_scan(SCAN_EXTRACT_ICONS|SCAN_FILESYSTEM);
+ dir.smart_scan(SORT_NAME, SCAN_EXTRACT_ICONS|SCAN_FILESYSTEM);
#endif
}
dir.sort_directory(SORT_DATE);
- AddShellEntries(dir, RECENT_DOCS_COUNT, smd._subfolders); ///@todo read max. count of entries from registry
+ AddShellEntries(dir, RECENT_DOCS_COUNT, smd._subfolders);
+ }
+}
+
+
+#ifndef _SHELL32_FAVORITES
+
+void FavoritesMenu::AddEntries()
+{
+ super::AddEntries();
+
+ for(BookmarkList::iterator it=_bookmarks.begin(); it!=_bookmarks.end(); ++it) {
+ BookmarkNode& node = *it;
+
+ int id = ++_next_id;
+
+ _entries[id] = node;
+
+ if (node._type == BookmarkNode::BMNT_FOLDER) {
+ BookmarkFolder& folder = *node._pfolder;
+
+ AddButton(folder._name, ICID_FOLDER, true, id);
+ } else if (node._type == BookmarkNode::BMNT_BOOKMARK) {
+ Bookmark& bookmark = *node._pbookmark;
+
+ ICON_ID icon = ICID_NONE;
+
+ if (!bookmark._icon_path.empty())
+ icon = g_Globals._icon_cache.extract(bookmark._icon_path, bookmark._icon_idx);
+
+ AddButton(bookmark._name, icon!=ICID_NONE?icon:ICID_BOOKMARK, false, id);
+ }
}
}
+
+int FavoritesMenu::Command(int id, int code)
+{
+ BookmarkMap::iterator found = _entries.find(id);
+
+ if (found != _entries.end()) {
+ BookmarkNode& node = found->second;
+
+ if (node._type == BookmarkNode::BMNT_FOLDER) {
+ BookmarkFolder& folder = *node._pfolder;
+
+ if (CloseOtherSubmenus(id))
+ CreateSubmenu(id, folder._name, STARTMENU_CREATOR(FavoritesMenu), &static_cast<BookmarkList&>(folder._bookmarks));
+ } else if (node._type == BookmarkNode::BMNT_BOOKMARK) {
+ Bookmark& bookmark = *node._pbookmark;
+
+ String url = bookmark._url;
+ HWND hparent = GetParent(_hwnd);
+
+ CloseStartMenu(id);
+
+ launch_file(hparent, url, SW_SHOWNORMAL);
+ }
+
+ return 0;
+ }
+
+ return super::Command(id, code);
+}
+
+#endif