automatically opening startmenu-submenus

svn path=/trunk/; revision=5699
This commit is contained in:
Martin Fuchs 2003-08-20 12:42:25 +00:00
parent 1dbf9b9981
commit 246cb6d247
17 changed files with 259 additions and 161 deletions

View file

@ -1,8 +1,6 @@
- extend shell view code in Wine - extend shell view code in Wine
- implement start menu
- iplement taskbar and additional deskbands - iplement taskbar and additional deskbands
- taskbar notification area (aka "tray") - taskbar notification area (aka "tray")
- Fix the Explorer Bar/Start Menu. Currently it is almost nothing like Windows.
- paint desktop background: configurable colors, background image, ... - paint desktop background: configurable colors, background image, ...
- Drag Drop on desktop does not work. - Drag Drop on desktop does not work.
- implement Drag Drop from the tree view. - implement Drag Drop from the tree view.

View file

@ -246,6 +246,14 @@ SOURCE=.\utility\window.h
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=.\res\arrow.ico
# End Source File
# Begin Source File
SOURCE=.\res\arrowsel.ico
# End Source File
# Begin Source File
SOURCE=.\de.rc SOURCE=.\de.rc
!IF "$(CFG)" == "explorer - Win32 Release" !IF "$(CFG)" == "explorer - Win32 Release"
@ -509,10 +517,6 @@ SOURCE=.\shell\winfs.h
# End Group # End Group
# Begin Source File # Begin Source File
SOURCE=.\res\arrow.ico
# End Source File
# Begin Source File
SOURCE=.\explorer.cpp SOURCE=.\explorer.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

View file

@ -17,6 +17,8 @@
#define IDS_EMPTY 13 #define IDS_EMPTY 13
#define IDS_RECENT 14 #define IDS_RECENT 14
#define IDS_ADMIN 15 #define IDS_ADMIN 15
#define IDS_NETWORK 16
#define IDS_CONNECTIONS 17
#define IDI_REACTOS 100 #define IDI_REACTOS 100
#define IDI_EXPLORER 101 #define IDI_EXPLORER 101
#define IDI_STARTMENU 102 #define IDI_STARTMENU 102
@ -32,6 +34,8 @@
#define IDM_WINEFILE 112 #define IDM_WINEFILE 112
#define IDI_LOGOFF 124 #define IDI_LOGOFF 124
#define IDI_FOLDERARROW 125 #define IDI_FOLDERARROW 125
#define IDI_ARROW 125
#define IDI_ARROW_SELECTED 126
#define ID_VIEW_NAME 401 #define ID_VIEW_NAME 401
#define ID_VIEW_ALL_ATTRIBUTES 402 #define ID_VIEW_ALL_ATTRIBUTES 402
#define ID_VIEW_SELECTED_ATTRIBUTES 403 #define ID_VIEW_SELECTED_ATTRIBUTES 403

View file

@ -94,7 +94,8 @@ IDI_REACTOS ICON DISCARDABLE "res/reactos.ico"
IDI_EXPLORER ICON DISCARDABLE "res/explorer.ico" IDI_EXPLORER ICON DISCARDABLE "res/explorer.ico"
IDI_STARTMENU ICON DISCARDABLE "res/startmenu.ico" IDI_STARTMENU ICON DISCARDABLE "res/startmenu.ico"
IDI_LOGOFF ICON DISCARDABLE "res/logoff.ico" IDI_LOGOFF ICON DISCARDABLE "res/logoff.ico"
IDI_FOLDERARROW ICON DISCARDABLE "res/arrow.ico" IDI_ARROW ICON DISCARDABLE "res/arrow.ico"
IDI_ARROW_SELECTED ICON DISCARDABLE "res\\arrowsel.ico"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
@ -257,6 +258,12 @@ BEGIN
IDS_ADMIN "Administration" IDS_ADMIN "Administration"
END END
STRINGTABLE DISCARDABLE
BEGIN
IDS_NETWORK "Network"
IDS_CONNECTIONS "Connections"
END
#endif // German (Germany) resources #endif // German (Germany) resources
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

View file

@ -230,7 +230,7 @@ LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
case WM_GET_CONTROLWINDOW: case WM_GET_CONTROLWINDOW:
if (wparam == FCW_STATUS) if (wparam == FCW_STATUS)
return (LRESULT)_hstatusbar; return (LRESULT)(HWND)_hstatusbar;
break; break;
default: default:

View file

@ -42,9 +42,9 @@ protected:
HWND _hmdiclient; HWND _hmdiclient;
#endif #endif
HWND _hstatusbar; WindowHandle _hstatusbar;
HWND _htoolbar; WindowHandle _htoolbar;
HWND _hdrivebar; WindowHandle _hdrivebar;
HMENU _hMenuFrame; HMENU _hMenuFrame;
HMENU _hMenuWindow; HMENU _hMenuWindow;

View file

@ -73,7 +73,7 @@ struct Pane : public SubclassedWindow
int _widths[COLUMNS]; int _widths[COLUMNS];
int _positions[COLUMNS+1]; int _positions[COLUMNS+1];
HWND _hwndHeader; WindowHandle _hwndHeader;
bool _treePane; bool _treePane;
int _visible_cols; int _visible_cols;

View file

@ -51,7 +51,6 @@ static LPARAM TreeView_GetItemData(HWND hwndTreeView, HTREEITEM hItem)
ShellBrowserChild::ShellBrowserChild(HWND hwnd) ShellBrowserChild::ShellBrowserChild(HWND hwnd)
: super(hwnd) : super(hwnd)
{ {
_hWndFrame = 0;
_pShellView = NULL; _pShellView = NULL;
_pDropTarget = NULL; _pDropTarget = NULL;
_himlSmall = 0; _himlSmall = 0;

View file

@ -104,7 +104,7 @@ struct ShellBrowserChild : public ChildWindow, public IShellBrowserImpl
protected: protected:
Root _root; Root _root;
HWND _hWndFrame; WindowHandle _hWndFrame;
IShellView* _pShellView; // current hosted shellview IShellView* _pShellView; // current hosted shellview
HIMAGELIST _himlSmall; // list HIMAGELIST _himlSmall; // list

View file

@ -45,6 +45,7 @@ StartMenu::StartMenu(HWND hwnd)
: super(hwnd) : super(hwnd)
{ {
_next_id = IDC_FIRST_MENU; _next_id = IDC_FIRST_MENU;
_submenu_id = 0;
} }
StartMenu::StartMenu(HWND hwnd, const StartMenuFolders& info) StartMenu::StartMenu(HWND hwnd, const StartMenuFolders& info)
@ -55,6 +56,15 @@ StartMenu::StartMenu(HWND hwnd, const StartMenuFolders& info)
_dirs.push_back(ShellDirectory(Desktop(), *it, _hwnd)); _dirs.push_back(ShellDirectory(Desktop(), *it, _hwnd));
_next_id = IDC_FIRST_MENU; _next_id = IDC_FIRST_MENU;
_submenu_id = 0;
}
StartMenu::~StartMenu()
{
HWND parent = GetParent(_hwnd);
if (parent)
SendMessage(parent, WM_STARTMENU_CLOSED, 0, 0);
} }
@ -86,16 +96,16 @@ LRESULT StartMenu::Init(LPCREATESTRUCT pcs)
// create buttons for registered entries in _entries // create buttons for registered entries in _entries
if (_entries.empty()) { if (_entries.empty()) {
AddButton(ResString(IDS_EMPTY), 0, false, (UINT)-1, WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_OWNERDRAW|WS_DISABLED); AddButton(ResString(IDS_EMPTY), 0, false, (UINT)-1, WS_VISIBLE|WS_CHILD|BS_OWNERDRAW|WS_DISABLED);
} else { } else {
for(ShellEntryMap::const_iterator it=_entries.begin(); it!=_entries.end(); ++it) { for(ShellEntryMap::const_iterator it=_entries.begin(); it!=_entries.end(); ++it) {
const StartMenuEntry& sme = it->second; const StartMenuEntry& sme = it->second;
bool showArrow = false; bool hasSubmenu = false;
if (sme._entry && (sme._entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) if (sme._entry && (sme._entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
showArrow = true; hasSubmenu = true;
AddButton(sme._title, sme._hIcon, showArrow, it->first); AddButton(sme._title, sme._hIcon, hasSubmenu, it->first);
} }
} }
@ -156,6 +166,10 @@ LRESULT StartMenu::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
return 0; // disable window resizing return 0; // disable window resizing
goto def; goto def;
case WM_STARTMENU_CLOSED:
_submenu = 0;
break;
default: def: default: def:
return super::WndProc(nmsg, wparam, lparam); return super::WndProc(nmsg, wparam, lparam);
} }
@ -163,6 +177,7 @@ LRESULT StartMenu::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
return 0; return 0;
} }
int StartMenu::Command(int id, int code) int StartMenu::Command(int id, int code)
{ {
switch(id) { switch(id) {
@ -218,7 +233,7 @@ StartMenuEntry& StartMenu::AddEntry(const ShellFolder folder, const ShellEntry*
} }
void StartMenu::AddButton(LPCTSTR title, HICON hIcon, bool showArrow, UINT id, DWORD style) void StartMenu::AddButton(LPCTSTR title, HICON hIcon, bool hasSubmenu, UINT id, DWORD style)
{ {
WindowRect rect(_hwnd); WindowRect rect(_hwnd);
@ -231,7 +246,7 @@ void StartMenu::AddButton(LPCTSTR title, HICON hIcon, bool showArrow, UINT id, D
MoveWindow(_hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE); MoveWindow(_hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE);
StartMenuButton(_hwnd, rect.bottom-rect.top-STARTMENU_LINE_HEIGHT-4, title, id, hIcon, showArrow, style); StartMenuCtrl(_hwnd, rect.bottom-rect.top-STARTMENU_LINE_HEIGHT-4, title, id, hIcon, hasSubmenu, style);
} }
void StartMenu::AddSeparator() void StartMenu::AddSeparator()
@ -251,24 +266,45 @@ void StartMenu::AddSeparator()
} }
bool StartMenu::CloseOtherSubmenus(int id)
{
if (_submenu && IsWindow(_submenu)) {
if (_submenu_id == id)
return false;
else {
DestroyWindow(_submenu);
_submenu_id = 0;
_submenu = 0; // safetly first - should be reset automatically by WM_STARTMENU_CLOSED
}
}
return true;
}
void StartMenu::CreateSubmenu(int id, const StartMenuFolders& new_folders, CREATORFUNC creator) void StartMenu::CreateSubmenu(int id, const StartMenuFolders& new_folders, CREATORFUNC creator)
{ {
// Only open one submenu at a time.
if (!CloseOtherSubmenus(id))
return;
HWND btn = GetDlgItem(_hwnd, id); HWND btn = GetDlgItem(_hwnd, id);
int x, y; int x, y;
if (btn) { if (btn) {
WindowRect pos(btn); WindowRect pos(btn);
x = pos.right-8; // Submenus should overlap their parent a bit. x = pos.right-3; // Submenus should overlap their parent a bit.
y = pos.top; y = pos.top;
} else { } else {
WindowRect pos(_hwnd); WindowRect pos(_hwnd);
x = pos.right-8; x = pos.right-3;
y = pos.top; y = pos.top;
} }
StartMenu::Create(x, y, new_folders, _hwnd, creator); _submenu_id = id;
_submenu = StartMenu::Create(x, y, new_folders, _hwnd, creator);
} }
void StartMenu::CreateSubmenu(int id, int folder_id, CREATORFUNC creator) void StartMenu::CreateSubmenu(int id, int folder_id, CREATORFUNC creator)
@ -304,13 +340,91 @@ void StartMenu::CreateSubmenu(int id, int folder_id1, int folder_id2, CREATORFUN
void StartMenu::ActivateEntry(int id, ShellEntry* entry) void StartMenu::ActivateEntry(int id, ShellEntry* entry)
{ {
if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
// Only open one submenu at a time.
if (!CloseOtherSubmenus(id))
return;
StartMenuFolders new_folders; StartMenuFolders new_folders;
new_folders.push_back(entry->create_absolute_pidl(_hwnd)); new_folders.push_back(entry->create_absolute_pidl(_hwnd));
CreateSubmenu(id, new_folders); CreateSubmenu(id, new_folders);
} else { } else {
entry->launch_entry(_hwnd); entry->launch_entry(_hwnd); //TODO: launch in the background
}
}
LRESULT StartMenuButton::WndProc(UINT message, WPARAM wparam, LPARAM lparam)
{
switch(message) {
case WM_MOUSEMOVE:
// automatically set the focus to startmenu entries when moving the mouse over them
if (GetFocus()!=_hwnd && !(GetWindowStyle(_hwnd)&WS_DISABLED)) {
SetFocus(_hwnd);
UpdateWindow(GetParent(_hwnd)); // draw focused button before waiting on submenu creation
// automatically open submenus
if (_hasSubmenu)
SendMessage(GetParent(_hwnd), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(_hwnd),BN_CLICKED), (LPARAM)_hwnd);
}
break;
default:
return super::WndProc(message, wparam, lparam);
}
return 0;
}
void StartMenuButton::DrawItem(LPDRAWITEMSTRUCT dis)
{
UINT style = DFCS_BUTTONPUSH;
if (dis->itemState & ODS_DISABLED)
style |= DFCS_INACTIVE;
POINT iconPos = {dis->rcItem.left+2, (dis->rcItem.top+dis->rcItem.bottom-16)/2};
RECT textRect = {dis->rcItem.left+16+4, dis->rcItem.top+2, dis->rcItem.right-4, dis->rcItem.bottom-4};
if (dis->itemState & ODS_SELECTED) {
style |= DFCS_PUSHED;
++iconPos.x; ++iconPos.y;
++textRect.left; ++textRect.top;
++textRect.right; ++textRect.bottom;
}
int bk_color = COLOR_BTNFACE;
int text_color = COLOR_BTNTEXT;
if (dis->itemState & ODS_FOCUS) {
bk_color = COLOR_HIGHLIGHT;
text_color = COLOR_HIGHLIGHTTEXT;
}
HBRUSH bk_brush = GetSysColorBrush(bk_color);
FillRect(dis->hDC, &dis->rcItem, bk_brush);
DrawIconEx(dis->hDC, iconPos.x, iconPos.y, _hIcon, 16, 16, 0, bk_brush, DI_NORMAL);
// draw submenu arrow at the right
if (_hasSubmenu) {
static SmallIcon arrowIcon(IDI_ARROW);
static SmallIcon selArrowIcon(IDI_ARROW_SELECTED);
DrawIconEx(dis->hDC, dis->rcItem.right-16, iconPos.y,
dis->itemState&ODS_FOCUS?selArrowIcon:arrowIcon, 16, 16, 0, bk_brush, DI_NORMAL);
}
TCHAR text[BUFFER_LEN];
GetWindowText(_hwnd, text, BUFFER_LEN);
if (dis->itemState & (ODS_DISABLED|ODS_GRAYED))
DrawGrayText(dis, &textRect, text, DT_SINGLELINE|DT_NOPREFIX|DT_VCENTER);
else {
BkMode mode(dis->hDC, TRANSPARENT);
TextColor lcColor(dis->hDC, GetSysColor(text_color));
DrawText(dis->hDC, text, -1, &textRect, DT_SINGLELINE|DT_NOPREFIX|DT_VCENTER);
} }
} }
@ -339,16 +453,19 @@ LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs)
if (super::Init(pcs)) if (super::Init(pcs))
return 1; return 1;
AddButton(ResString(IDS_EXPLORE), SmallIcon(IDI_EXPLORER), false, IDC_EXPLORE);
AddSeparator(); AddSeparator();
// insert hard coded start entries // insert hard coded start entries
AddButton(ResString(IDS_PROGRAMS), 0, true, IDC_PROGRAMS); AddButton(ResString(IDS_PROGRAMS), 0, true, IDC_PROGRAMS);
AddButton(ResString(IDS_EXPLORE), SmallIcon(IDI_EXPLORER), false, IDC_EXPLORE);
AddButton(ResString(IDS_FAVORITES), 0, true, IDC_FAVORITES); AddButton(ResString(IDS_FAVORITES), 0, true, IDC_FAVORITES);
AddButton(ResString(IDS_DOCUMENTS), 0, true, IDC_DOCUMENTS); AddButton(ResString(IDS_DOCUMENTS), 0, true, IDC_DOCUMENTS);
AddButton(ResString(IDS_RECENT), 0, true, IDC_RECENT); AddButton(ResString(IDS_RECENT), 0, true, IDC_RECENT);
AddButton(ResString(IDS_SETTINGS), 0, true, IDC_SETTINGS); AddButton(ResString(IDS_SETTINGS), 0, true, IDC_SETTINGS);
AddButton(ResString(IDS_ADMIN), 0, true, IDC_ADMIN); AddButton(ResString(IDS_ADMIN), 0, true, IDC_ADMIN);
AddButton(ResString(IDS_NETWORK), 0, true, IDC_NETWORK);
AddButton(ResString(IDS_CONNECTIONS),0,true, IDC_CONNECTIONS);
AddButton(ResString(IDS_SEARCH), 0, false, IDC_SEARCH); AddButton(ResString(IDS_SEARCH), 0, false, IDC_SEARCH);
AddButton(ResString(IDS_START_HELP),0, false, IDC_START_HELP); AddButton(ResString(IDS_START_HELP),0, false, IDC_START_HELP);
AddButton(ResString(IDS_LAUNCH), 0, false, IDC_LAUNCH); AddButton(ResString(IDS_LAUNCH), 0, false, IDC_LAUNCH);
@ -392,6 +509,14 @@ int StartMenuRoot::Command(int id, int code)
CreateSubmenu(id, CSIDL_COMMON_ADMINTOOLS, CSIDL_ADMINTOOLS); CreateSubmenu(id, CSIDL_COMMON_ADMINTOOLS, CSIDL_ADMINTOOLS);
break; break;
case IDC_NETWORK:
CreateSubmenu(id, CSIDL_NETWORK);
break;
case IDC_CONNECTIONS:
CreateSubmenu(id, CSIDL_CONNECTIONS);
break;
case IDC_LOGOFF: case IDC_LOGOFF:
DestroyWindow(GetParent(_hwnd)); //TODO: show dialog and ask for acknowledge DestroyWindow(GetParent(_hwnd)); //TODO: show dialog and ask for acknowledge
break; break;

View file

@ -38,27 +38,7 @@
#define STARTMENU_SEP_HEIGHT (STARTMENU_LINE_HEIGHT/2) #define STARTMENU_SEP_HEIGHT (STARTMENU_LINE_HEIGHT/2)
// Startmenu button #define WM_STARTMENU_CLOSED (WM_APP+0x11)
struct StartMenuButton : public Button
{
StartMenuButton(HWND parent, int y, LPCTSTR title,
UINT id, HICON hIcon=0, bool showArrow=false, DWORD style=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_OWNERDRAW, DWORD exStyle=0)
: Button(parent, title, 0, y, ClientRect(parent).right, STARTMENU_LINE_HEIGHT, id, style, exStyle)
{
*new StartmenuEntry(_hwnd, hIcon, showArrow);
SetWindowFont(_hwnd, GetStockFont(DEFAULT_GUI_FONT), FALSE);
}
};
struct StartMenuSeparator : public Static
{
StartMenuSeparator(HWND parent, int y, DWORD style=WS_VISIBLE|WS_CHILD|SS_ETCHEDHORZ, DWORD exStyle=0)
: Static(parent, NULL, 0, y+STARTMENU_SEP_HEIGHT/2-1, ClientRect(parent).right, 2, -1, style, exStyle)
{
}
};
struct StartMenuDirectory struct StartMenuDirectory
@ -81,21 +61,67 @@ struct StartMenuEntry
const ShellEntry* _entry; const ShellEntry* _entry;
}; };
typedef map<UINT, StartMenuEntry> ShellEntryMap;
/**
StartMenuButton draws to face of a StartMenuCtrl button control.
*/
struct StartMenuButton : public OwnerdrawnButton
{
typedef OwnerdrawnButton super;
StartMenuButton(HWND hwnd, HICON hIcon, bool hasSubmenu)
: super(hwnd), _hIcon(hIcon), _hasSubmenu(hasSubmenu) {}
protected:
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
virtual void DrawItem(LPDRAWITEMSTRUCT dis);
HICON _hIcon;
bool _hasSubmenu;
};
/**
To create a Startmenu button control, construct a StartMenuCtrl object.
*/
struct StartMenuCtrl : public Button
{
StartMenuCtrl(HWND parent, int y, LPCTSTR title,
UINT id, HICON hIcon=0, bool hasSubmenu=false, DWORD style=WS_VISIBLE|WS_CHILD|BS_OWNERDRAW, DWORD exStyle=0)
: Button(parent, title, 0, y, ClientRect(parent).right, STARTMENU_LINE_HEIGHT, id, style, exStyle)
{
*new StartMenuButton(_hwnd, hIcon, hasSubmenu);
SetWindowFont(_hwnd, GetStockFont(DEFAULT_GUI_FONT), FALSE);
}
};
struct StartMenuSeparator : public Static
{
StartMenuSeparator(HWND parent, int y, DWORD style=WS_VISIBLE|WS_CHILD|WS_DISABLED|SS_ETCHEDHORZ, DWORD exStyle=0)
: Static(parent, NULL, 0, y+STARTMENU_SEP_HEIGHT/2-1, ClientRect(parent).right, 2, -1, style, exStyle)
{
}
};
typedef list<ShellPath> StartMenuFolders; typedef list<ShellPath> StartMenuFolders;
#define STARTMENU_CREATOR(WND_CLASS) WINDOW_CREATOR_INFO(WND_CLASS, StartMenuFolders) #define STARTMENU_CREATOR(WND_CLASS) WINDOW_CREATOR_INFO(WND_CLASS, StartMenuFolders)
typedef map<UINT, StartMenuEntry> ShellEntryMap;
// Startmenu window
/**
Startmenu window
*/
struct StartMenu : public OwnerDrawParent<Dialog> struct StartMenu : public OwnerDrawParent<Dialog>
{ {
typedef OwnerDrawParent<Dialog> super; typedef OwnerDrawParent<Dialog> super;
StartMenu(HWND hwnd); StartMenu(HWND hwnd);
StartMenu(HWND hwnd, const StartMenuFolders& info); StartMenu(HWND hwnd, const StartMenuFolders& info);
~StartMenu();
static HWND Create(int x, int y, HWND hwndParent=0); static HWND Create(int x, int y, HWND hwndParent=0);
static HWND Create(int x, int y, const StartMenuFolders&, HWND hwndParent=0, CREATORFUNC creator=s_def_creator); static HWND Create(int x, int y, const StartMenuFolders&, HWND hwndParent=0, CREATORFUNC creator=s_def_creator);
@ -106,6 +132,9 @@ protected:
ShellEntryMap _entries; ShellEntryMap _entries;
StartMenuShellDirs _dirs; StartMenuShellDirs _dirs;
UINT _submenu_id;
WindowHandle _submenu;
static BtnWindowClass s_wcStartMenu; static BtnWindowClass s_wcStartMenu;
LRESULT Init(LPCREATESTRUCT pcs); LRESULT Init(LPCREATESTRUCT pcs);
@ -119,9 +148,10 @@ protected:
void AddShellEntries(const ShellDirectory& dir, int max=-1, bool subfolders=true); void AddShellEntries(const ShellDirectory& dir, int max=-1, bool subfolders=true);
void AddButton(LPCTSTR title, HICON hIcon=0, bool showArrow=false, UINT id=(UINT)-1, DWORD style=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_OWNERDRAW); void AddButton(LPCTSTR title, HICON hIcon=0, bool hasSubmenu=false, UINT id=(UINT)-1, DWORD style=WS_VISIBLE|WS_CHILD|BS_OWNERDRAW);
void AddSeparator(); void AddSeparator();
bool CloseOtherSubmenus(int id);
void CreateSubmenu(int id, const StartMenuFolders& new_folders, CREATORFUNC creator=s_def_creator); void CreateSubmenu(int id, const StartMenuFolders& new_folders, CREATORFUNC creator=s_def_creator);
void CreateSubmenu(int id, int folder1, int folder2, CREATORFUNC creator=s_def_creator); void CreateSubmenu(int id, int folder1, int folder2, CREATORFUNC creator=s_def_creator);
void CreateSubmenu(int id, int folder, CREATORFUNC creator=s_def_creator); void CreateSubmenu(int id, int folder, CREATORFUNC creator=s_def_creator);

View file

@ -77,8 +77,7 @@ LRESULT DesktopBar::Init(LPCREATESTRUCT pcs)
return 1; return 1;
// create start button // create start button
new PictureButton(Button(_hwnd, ResString(IDS_START), 2, 2, STARTBUTTON_WIDTH, TASKBAR_HEIGHT-8, IDC_START, new PictureButton(Button(_hwnd, ResString(IDS_START), 2, 2, STARTBUTTON_WIDTH, TASKBAR_HEIGHT-8, IDC_START, WS_VISIBLE|WS_CHILD|BS_OWNERDRAW),
WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_OWNERDRAW),
SmallIcon(IDI_STARTMENU)); SmallIcon(IDI_STARTMENU));
// create task bar // create task bar
@ -133,6 +132,10 @@ LRESULT DesktopBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
case WM_CLOSE: case WM_CLOSE:
break; break;
case WM_STARTMENU_CLOSED:
_startMenuRoot = 0;
break;
default: def: default: def:
return super::WndProc(nmsg, wparam, lparam); return super::WndProc(nmsg, wparam, lparam);
} }
@ -145,7 +148,7 @@ int DesktopBar::Command(int id, int code)
{ {
switch(id) { switch(id) {
case IDC_START: case IDC_START:
if (_startMenuRoot && IsWindow(_startMenuRoot)) { if (_startMenuRoot && IsWindow(_startMenuRoot)) { // IsWindow(): safety first
// dispose Startmenu // dispose Startmenu
DestroyWindow(_startMenuRoot); DestroyWindow(_startMenuRoot);
_startMenuRoot = 0; _startMenuRoot = 0;
@ -229,7 +232,6 @@ TaskBar::TaskBar(HWND hwnd)
: super(hwnd) : super(hwnd)
{ {
_desktop_bar = NULL; _desktop_bar = NULL;
_last_foreground_wnd = 0;
} }
TaskBar::~TaskBar() TaskBar::~TaskBar()

View file

@ -34,8 +34,6 @@
#define TASKBAR_LEFT 70 #define TASKBAR_LEFT 70
//#define TASKBAR_AT_TOP //#define TASKBAR_AT_TOP
#define WM_SHELLHOOK_NOTIFY (WM_APP+0x10)
#define CLASSNAME_EXPLORERBAR _T("Shell_TrayWnd") #define CLASSNAME_EXPLORERBAR _T("Shell_TrayWnd")
#define TITLE_EXPLORERBAR _T("DesktopBar") #define TITLE_EXPLORERBAR _T("DesktopBar")
@ -44,6 +42,9 @@
#define TITLE_TASKBAR _T("Running Applications") #define TITLE_TASKBAR _T("Running Applications")
#define WM_SHELLHOOK_NOTIFY (WM_APP+0x10)
#define IDC_START 0x1000 #define IDC_START 0x1000
#define IDC_LOGOFF 0x1001 #define IDC_LOGOFF 0x1001
#define IDC_SHUTDOWN 0x1002 #define IDC_SHUTDOWN 0x1002
@ -57,6 +58,8 @@
#define IDC_FAVORITES 0x100A #define IDC_FAVORITES 0x100A
#define IDC_PROGRAMS 0x100B #define IDC_PROGRAMS 0x100B
#define IDC_EXPLORE 0x100C #define IDC_EXPLORE 0x100C
#define IDC_NETWORK 0x100D
#define IDC_CONNECTIONS 0x100E
#define IDC_FIRST_APP 0x2000 #define IDC_FIRST_APP 0x2000
#define IDC_FIRST_MENU 0x3000 #define IDC_FIRST_MENU 0x3000
@ -74,8 +77,8 @@ protected:
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
int Command(int id, int code); int Command(int id, int code);
HWND _hwndTaskBar; WindowHandle _hwndTaskBar;
HWND _startMenuRoot; WindowHandle _startMenuRoot;
}; };
@ -114,10 +117,10 @@ struct TaskBar : public Window
DesktopBar* _desktop_bar; DesktopBar* _desktop_bar;
protected: protected:
HWND _htoolbar; WindowHandle _htoolbar;
TaskBarMap _map; TaskBarMap _map;
int _next_id; int _next_id;
HWND _last_foreground_wnd; WindowHandle _last_foreground_wnd;
LRESULT Init(LPCREATESTRUCT pcs); LRESULT Init(LPCREATESTRUCT pcs);
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);

View file

@ -31,7 +31,6 @@
#include "window.h" #include "window.h"
#include "../globals.h" #include "../globals.h"
#include "../explorer_intres.h"
WindowClass::WindowClass(LPCTSTR classname, UINT style_, WNDPROC wndproc) WindowClass::WindowClass(LPCTSTR classname, UINT style_, WNDPROC wndproc)
@ -219,9 +218,6 @@ LRESULT SubclassedWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
ChildWindow::ChildWindow(HWND hwnd) ChildWindow::ChildWindow(HWND hwnd)
: super(hwnd) : super(hwnd)
{ {
_left_hwnd = 0;
_right_hwnd = 0;
_focus_pane = 0; _focus_pane = 0;
_split_pos = DEFAULT_SPLIT_POS; _split_pos = DEFAULT_SPLIT_POS;
_last_split = DEFAULT_SPLIT_POS; _last_split = DEFAULT_SPLIT_POS;
@ -466,9 +462,9 @@ int Window::MessageLoop()
Button::Button(HWND parent, LPCTSTR text, int left, int top, int width, int height, Button::Button(HWND parent, LPCTSTR text, int left, int top, int width, int height,
int id, DWORD flags, DWORD exStyle) int id, DWORD flags, DWORD exStyle)
: WindowHandle(CreateWindowEx(exStyle, TEXT("BUTTON"), text, flags, left, top, width, height,
parent, (HMENU)id, g_Globals._hInstance, 0))
{ {
_hwnd = CreateWindowEx(exStyle, TEXT("BUTTON"), text, flags, left, top, width, height,
parent, (HMENU)id, g_Globals._hInstance, 0);
} }
@ -484,9 +480,9 @@ LRESULT OwnerdrawnButton::WndProc(UINT message, WPARAM wparam, LPARAM lparam)
Static::Static(HWND parent, LPCTSTR text, int left, int top, int width, int height, Static::Static(HWND parent, LPCTSTR text, int left, int top, int width, int height,
int id, DWORD flags, DWORD exStyle) int id, DWORD flags, DWORD exStyle)
: WindowHandle(CreateWindowEx(exStyle, TEXT("STATIC"), text, flags, left, top, width, height,
parent, (HMENU)id, g_Globals._hInstance, 0))
{ {
_hwnd = CreateWindowEx(exStyle, TEXT("STATIC"), text, flags, left, top, width, height,
parent, (HMENU)id, g_Globals._hInstance, 0);
} }
@ -619,52 +615,3 @@ void PictureButton::DrawItem(LPDRAWITEMSTRUCT dis)
DrawFocusRect(dis->hDC, &rect); DrawFocusRect(dis->hDC, &rect);
} }
} }
void StartmenuEntry::DrawItem(LPDRAWITEMSTRUCT dis)
{
UINT style = DFCS_BUTTONPUSH;
if (dis->itemState & ODS_DISABLED)
style |= DFCS_INACTIVE;
POINT iconPos = {dis->rcItem.left+2, (dis->rcItem.top+dis->rcItem.bottom-16)/2};
RECT textRect = {dis->rcItem.left+16+4, dis->rcItem.top+2, dis->rcItem.right-4, dis->rcItem.bottom-4};
if (dis->itemState & ODS_SELECTED) {
style |= DFCS_PUSHED;
++iconPos.x; ++iconPos.y;
++textRect.left; ++textRect.top;
++textRect.right; ++textRect.bottom;
}
int bk_color = COLOR_BTNFACE;
int text_color = COLOR_BTNTEXT;
if (dis->itemState & ODS_FOCUS) {
bk_color = COLOR_HIGHLIGHT;
text_color = COLOR_HIGHLIGHTTEXT;
}
HBRUSH bk_brush = GetSysColorBrush(bk_color);
FillRect(dis->hDC, &dis->rcItem, bk_brush);
DrawIconEx(dis->hDC, iconPos.x, iconPos.y, _hIcon, 16, 16, 0, bk_brush, DI_NORMAL);
// draw submenu arrow at the right
if (_showArrow) {
SmallIcon arrowIcon(IDI_FOLDERARROW);
DrawIconEx(dis->hDC, dis->rcItem.right-16, iconPos.y, arrowIcon, 16, 16, 0, bk_brush, DI_NORMAL);
}
TCHAR text[BUFFER_LEN];
GetWindowText(_hwnd, text, BUFFER_LEN);
if (dis->itemState & (ODS_DISABLED|ODS_GRAYED))
DrawGrayText(dis, &textRect, text, DT_SINGLELINE|DT_VCENTER);
else {
BkMode mode(dis->hDC, TRANSPARENT);
TextColor lcColor(dis->hDC, GetSysColor(text_color));
DrawText(dis->hDC, text, -1, &textRect, DT_SINGLELINE|DT_VCENTER);
}
}

View file

@ -44,15 +44,28 @@ typedef set<HWND> WindowSet;
*/ */
struct WindowHandle
{
WindowHandle(HWND hwnd=0)
: _hwnd(hwnd) {}
operator HWND() const {return _hwnd;}
HWND* operator&() {return &_hwnd;}
protected:
HWND _hwnd;
};
/** /**
Class Window is the base class for several C++ window wrapper classes. Class Window is the base class for several C++ window wrapper classes.
Window objects are allocated from the heap. They are automatically freed Window objects are allocated from the heap. They are automatically freed
when the window gets destroyed. when the window gets destroyed.
*/ */
struct Window struct Window : public WindowHandle
{ {
Window(HWND hwnd) Window(HWND hwnd)
: _hwnd(hwnd) : WindowHandle(hwnd)
{ {
// store "this" pointer as user data // store "this" pointer as user data
SetWindowLong(hwnd, GWL_USERDATA, (LONG)this); SetWindowLong(hwnd, GWL_USERDATA, (LONG)this);
@ -65,9 +78,6 @@ struct Window
} }
operator HWND() const {return _hwnd;}
typedef Window* (*CREATORFUNC)(HWND, const void*); typedef Window* (*CREATORFUNC)(HWND, const void*);
static HWND Create(CREATORFUNC creator, DWORD dwExStyle, static HWND Create(CREATORFUNC creator, DWORD dwExStyle,
@ -98,9 +108,6 @@ struct Window
protected: protected:
HWND _hwnd;
virtual LRESULT Init(LPCREATESTRUCT pcs); // WM_CREATE processing virtual LRESULT Init(LPCREATESTRUCT pcs); // WM_CREATE processing
virtual LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); virtual LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
virtual int Command(int id, int code); // WM_COMMAND processing virtual int Command(int id, int code); // WM_COMMAND processing
@ -249,8 +256,8 @@ protected:
protected: protected:
MenuInfo*_menu_info; MenuInfo*_menu_info;
HWND _left_hwnd; WindowHandle _left_hwnd;
HWND _right_hwnd; WindowHandle _right_hwnd;
int _focus_pane; // 0: left 1: right int _focus_pane; // 0: left 1: right
int _split_pos; int _split_pos;
@ -292,15 +299,10 @@ struct Dialog : public Window
The button will remain existent when the C++ Button object is destroyed. The button will remain existent when the C++ Button object is destroyed.
There is no conjunction between C++ object and windows control life time. There is no conjunction between C++ object and windows control life time.
*/ */
struct Button struct Button : public WindowHandle
{ {
Button(HWND parent, LPCTSTR text, int left, int top, int width, int height, Button(HWND parent, LPCTSTR text, int left, int top, int width, int height,
int id, DWORD flags=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON, DWORD exStyle=0); int id, DWORD flags=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON, DWORD exStyle=0);
operator HWND() const {return _hwnd;}
protected:
HWND _hwnd;
}; };
@ -309,15 +311,10 @@ protected:
The control will remain existent when the C++ object is destroyed. The control will remain existent when the C++ object is destroyed.
There is no conjunction between C++ object and windows control life time. There is no conjunction between C++ object and windows control life time.
*/ */
struct Static struct Static : public WindowHandle
{ {
Static(HWND parent, LPCTSTR text, int left, int top, int width, int height, Static(HWND parent, LPCTSTR text, int left, int top, int width, int height,
int id, DWORD flags=WS_VISIBLE|WS_CHILD|SS_SIMPLE, DWORD ex_flags=0); int id, DWORD flags=WS_VISIBLE|WS_CHILD|SS_SIMPLE, DWORD ex_flags=0);
operator HWND() const {return _hwnd;}
protected:
HWND _hwnd;
}; };
@ -443,21 +440,3 @@ protected:
HICON _hIcon; HICON _hIcon;
bool _flat; bool _flat;
}; };
/**
implement start menu button as owner drawn buitton controls
*/
struct StartmenuEntry : public OwnerdrawnButton
{
typedef OwnerdrawnButton super;
StartmenuEntry(HWND hwnd, HICON hIcon, bool showArrow)
: super(hwnd), _hIcon(hIcon), _showArrow(showArrow) {}
protected:
virtual void DrawItem(LPDRAWITEMSTRUCT dis);
HICON _hIcon;
bool _showArrow;
};