[SHELL32]

* Populate edit and view menu on first activation. TODO: enable/disable edit menu items in OnInitMenuPopup.
* Add Edit menu to resources (en-US only, other langs TODO)
* Repurpose BuildFileMenu to build the menu for the selection. This needs improvements as it uses all the items from the context menu at the moment.
* Add items to the File menu when shown.

svn path=/branches/shell-experiments/; revision=63836
This commit is contained in:
David Quintana 2014-08-07 15:21:24 +00:00
parent a4bc6818ab
commit c3558fc84a
4 changed files with 202 additions and 79 deletions

View file

@ -33,6 +33,47 @@ extern HRESULT IUnknown_ShowDW(IUnknown * punk, BOOL fShow);
#include "newatlinterfaces.h"
static void DbgDumpMenuInternal(HMENU hmenu, char* padding, int padlevel)
{
WCHAR label[128];
padding[padlevel] = '.';
padding[padlevel + 1] = '.';
padding[padlevel + 2] = 0;
int count = GetMenuItemCount(hmenu);
for (int i = 0; i < count; i++)
{
MENUITEMINFOW mii = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU | MIIM_STATE | MIIM_ID;
mii.dwTypeData = label;
mii.cch = _countof(label);
GetMenuItemInfo(hmenu, i, TRUE, &mii);
if (mii.fType & MFT_BITMAP)
DbgPrint("%s%2d - %08x: BITMAP %08p (state=%d, has submenu=%s)\n", padding, i, mii.wID, mii.hbmpItem, mii.fState, mii.hSubMenu ? "TRUE" : "FALSE");
else if (mii.fType & MFT_SEPARATOR)
DbgPrint("%s%2d - %08x ---SEPARATOR---\n", padding, i, mii.wID);
else
DbgPrint("%s%2d - %08x: %S (state=%d, has submenu=%s)\n", padding, i, mii.wID, mii.dwTypeData, mii.fState, mii.hSubMenu ? "TRUE" : "FALSE");
if (mii.hSubMenu)
DbgDumpMenuInternal(mii.hSubMenu, padding, padlevel + 2);
}
padding[padlevel] = 0;
}
static void DbgDumpMenu(HMENU hmenu)
{
char padding[128];
DbgDumpMenuInternal(hmenu, padding, 0);
}
/*
TODO:
**Provide implementation of new and delete that use LocalAlloc
@ -1851,8 +1892,18 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::ContextSensitiveHelp(BOOL fEnterMode)
HRESULT STDMETHODCALLTYPE CShellBrowser::InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
{
HMENU mainMenu = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_MAINMENU));
//DbgPrint("Menu from shell32:\n");
//DbgDumpMenu(hmenuShared);
//DbgPrint("Menu from browseui:\n");
//DbgDumpMenu(mainMenu);
Shell_MergeMenus(hmenuShared, mainMenu, 0, 0, FCIDM_BROWSERLAST, MM_SUBMENUSHAVEIDS);
//DbgPrint("Merged menu:\n");
//DbgDumpMenu(hmenuShared);
int GCCU(itemCount3) = GetMenuItemCount(hmenuShared);
Unused(itemCount3);
@ -1869,6 +1920,9 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::SetMenuSB(HMENU hmenuShared, HOLEMENU h
CComPtr<IShellMenu> shellMenu;
HRESULT hResult;
//DbgPrint("SetMenuSB:\n");
//DbgDumpMenu(hmenuShared);
if (hmenuShared && IsMenu(hmenuShared) == FALSE)
return E_FAIL;
hResult = GetMenuBand(IID_PPV_ARG(IShellMenu, &shellMenu));
@ -3192,7 +3246,15 @@ LRESULT CShellBrowser::OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam,
menuIndex = 5;
}
return RelayMsgToShellView(uMsg, wParam, menuIndex, bHandled);
//DbgPrint("Before relay:\n");
//DbgDumpMenu(theMenu);
LRESULT ret = RelayMsgToShellView(uMsg, wParam, menuIndex, bHandled);
//DbgPrint("After relay:\n");
//DbgDumpMenu(theMenu);
return ret;
}
LRESULT CShellBrowser::RelayMsgToShellView(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)

View file

@ -41,6 +41,23 @@ BEGIN
END
END
/* menubar EDIT menu */
MENU_003 MENU
BEGIN
MENUITEM "&Undo\tCtrl+Z", FCIDM_SHVIEW_UNDO
MENUITEM SEPARATOR
MENUITEM "Cu&t\tCtrl+X", FCIDM_SHVIEW_CUT
MENUITEM "&Copy\tCtrl+C", FCIDM_SHVIEW_COPY
MENUITEM "&Paste\tCtrl+V", FCIDM_SHVIEW_INSERT
MENUITEM "Paste &shortcut", FCIDM_SHVIEW_INSERTLINK
MENUITEM SEPARATOR
MENUITEM "Copy to &folder...", FCIDM_SHVIEW_COPYTO
MENUITEM "Mo&ve to folder...", FCIDM_SHVIEW_MOVETO
MENUITEM SEPARATOR
MENUITEM "Select &all\tCtrl+A", FCIDM_SHVIEW_SELECTALL
MENUITEM "&Invert Selection", FCIDM_SHVIEW_INVERTSELECTION
END
/* shellview item menu */
MENU_SHV_FILE MENU
BEGIN

View file

@ -87,6 +87,7 @@ class CDefView :
HWND m_hWndParent;
FOLDERSETTINGS m_FolderSettings;
HMENU m_hMenu;
BOOL m_menusLoaded;
UINT m_uState;
UINT m_cidl;
LPITEMIDLIST *m_apidl;
@ -125,8 +126,8 @@ class CDefView :
static INT CALLBACK fill_list(LPVOID ptr, LPVOID arg);
HRESULT FillList();
HMENU BuildFileMenu();
void MergeFileMenu(HMENU hSubMenu);
void MergeViewMenu(HMENU hSubMenu);
void PrepareShowFileMenu(HMENU hSubMenu);
void PrepareShowViewMenu(HMENU hSubMenu);
UINT GetSelections();
HRESULT OpenSelectedItems();
void OnDeactivate();
@ -360,6 +361,7 @@ CDefView::CDefView()
m_FolderSettings.fFlags = 0;
m_FolderSettings.ViewMode = 0;
m_hMenu = NULL;
m_menusLoaded = FALSE;
m_uState = 0;
m_cidl = 0;
m_apidl = NULL;
@ -999,56 +1001,34 @@ LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
* #### Handling of the menus ####
*/
/**********************************************************
* ShellView_BuildFileMenu()
*/
HMENU CDefView::BuildFileMenu()
{ WCHAR szText[MAX_PATH];
MENUITEMINFOW mii;
int nTools, i;
HMENU hSubMenu;
{
HRESULT hr;
CComPtr<IContextMenu> cm;
TRACE("(%p)\n", this);
GetSelections();
hSubMenu = CreatePopupMenu();
if (hSubMenu)
{
/*get the number of items in our global array*/
for(nTools = 0; Tools[nTools].idCommand != -1; nTools++) {}
LPCITEMIDLIST * apidl = (LPCITEMIDLIST *)m_apidl;
/*add the menu items*/
for(i = 0; i < nTools; i++)
{
LoadStringW(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
hr = m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, apidl, IID_NULL_PPV_ARG(IContextMenu, &cm));
if (FAILED(hr))
return NULL;
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
HMENU hmenu = CreatePopupMenu();
if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
{
mii.fType = MFT_STRING;
mii.fState = MFS_ENABLED;
mii.dwTypeData = szText;
mii.wID = Tools[i].idCommand;
}
else
{
mii.fType = MFT_SEPARATOR;
}
/* tack This item onto the end of the menu */
InsertMenuItemW(hSubMenu, (UINT) - 1, TRUE, &mii);
}
}
//FIXME: get proper numbers ?
const UINT first = 0x7800;
const UINT last = 0x7A00;
hr = cm->QueryContextMenu(hmenu, 0, first, last, 0);
if (FAILED(hr))
return NULL;
TRACE("-- return (menu=%p)\n", hSubMenu);
return hSubMenu;
// TODO: filter or something
return hmenu;
}
/**********************************************************
* ShellView_MergeFileMenu()
*/
void CDefView::MergeFileMenu(HMENU hSubMenu)
void CDefView::PrepareShowFileMenu(HMENU hSubMenu)
{
TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu);
@ -1075,44 +1055,23 @@ void CDefView::MergeFileMenu(HMENU hSubMenu)
/* Insert This item at the beginning of the menu. */
_InsertMenuItemW(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
_InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM+4, MFT_STRING, L"Properties", MFS_DISABLED);
_InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM+3, MFT_STRING, L"Rename", MFS_DISABLED);
_InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM+2, MFT_STRING, L"Delete", MFS_DISABLED);
_InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM+1, MFT_STRING, L"Create Shortcut", MFS_DISABLED);
_InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM + 4, MFT_STRING, L"Properties", MFS_DISABLED);
_InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM + 3, MFT_STRING, L"Rename", MFS_DISABLED);
_InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM + 2, MFT_STRING, L"Delete", MFS_DISABLED);
_InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM + 1, MFT_STRING, L"Create Shortcut", MFS_DISABLED);
_InsertMenuItemW(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
_InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, L"New", MFS_ENABLED);
TRACE("--\n");
}
/**********************************************************
* ShellView_MergeViewMenu()
*/
void CDefView::MergeViewMenu(HMENU hSubMenu)
{
TRACE("(%p)->(submenu=%p)\n", this, hSubMenu);
if (!hSubMenu)
return;
// FIXME: I believe windows has all of the items initially in the menu,
// and actively calls DeleteMenu on the items that should not be disaplyed.
MENUITEMINFOW mii = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_ID | MIIM_STATE;
if (::GetMenuItemInfoW(hSubMenu, FCIDM_SHVIEW_BIGICON, FALSE, &mii) == 0)
HMENU menubase = BuildFileMenu();
if (menubase)
{
HMENU menubase = ::LoadMenuW(shell32_hInstance, L"MENU_001");
int count = ::GetMenuItemCount(menubase);
_InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
INT count = ::GetMenuItemCount(menubase);
for (int i = 0; i < count; i++)
{
WCHAR label[128];
ZeroMemory(&mii, sizeof(mii));
MENUITEMINFOW mii = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_DATA | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE;
mii.dwTypeData = label;
@ -1123,11 +1082,22 @@ void CDefView::MergeViewMenu(HMENU hSubMenu)
mii.fType |= MFT_RADIOCHECK;
::InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
::InsertMenuItemW(hSubMenu, IDM_MYFILEITEM, FALSE, &mii);
}
_InsertMenuItemW(hSubMenu, IDM_MYFILEITEM, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
::DestroyMenu(menubase);
}
TRACE("--\n");
}
void CDefView::PrepareShowViewMenu(HMENU hSubMenu)
{
TRACE("(%p)->(submenu=%p)\n", this, hSubMenu);
if (!hSubMenu)
return;
if (m_FolderSettings.ViewMode >= FVM_FIRST && m_FolderSettings.ViewMode <= FVM_LAST)
{
@ -1422,8 +1392,80 @@ void CDefView::DoActivate(UINT uState)
{
if(m_hMenu)
{
TRACE("-- before fnSetMenuSB\n");
m_pShellBrowser->SetMenuSB(m_hMenu, 0, m_hWnd);
if (!m_menusLoaded)
{
MENUITEMINFOW mii = { 0 };
/* initialize EDIT menu */
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU;
if (::GetMenuItemInfoW(m_hMenu, FCIDM_MENU_EDIT, FALSE, &mii))
{
HMENU hSubMenu = mii.hSubMenu;
HMENU menubase = ::LoadMenuW(shell32_hInstance, L"MENU_003");
int count = ::GetMenuItemCount(menubase);
for (int i = 0; i < count; i++)
{
WCHAR label[128];
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_DATA | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE;
mii.dwTypeData = label;
mii.cch = _countof(label);
::GetMenuItemInfoW(menubase, i, TRUE, &mii);
DbgPrint("Adding item %d label %S type %d\n", mii.wID, mii.dwTypeData, mii.fType);
mii.fType |= MFT_RADIOCHECK;
::InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
}
::DestroyMenu(menubase);
}
/* initialize VIEW menu */
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU;
if (::GetMenuItemInfoW(m_hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
{
HMENU menubase = ::LoadMenuW(shell32_hInstance, L"MENU_001");
HMENU hSubMenu = mii.hSubMenu;
_InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
int count = ::GetMenuItemCount(menubase);
for (int i = 0; i < count; i++)
{
WCHAR label[128];
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_DATA | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE;
mii.dwTypeData = label;
mii.cch = _countof(label);
::GetMenuItemInfoW(menubase, i, TRUE, &mii);
DbgPrint("Adding item %d label %S type %d\n", mii.wID, mii.dwTypeData, mii.fType);
mii.fType |= MFT_RADIOCHECK;
::InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
}
::DestroyMenu(menubase);
}
TRACE("-- before fnSetMenuSB\n");
m_pShellBrowser->SetMenuSB(m_hMenu, 0, m_hWnd);
m_menusLoaded = TRUE;
}
}
if (SVUIA_ACTIVATE_FOCUS == uState)
@ -1900,13 +1942,13 @@ LRESULT CDefView::OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
switch (menuItemId)
{
case FCIDM_MENU_FILE:
MergeFileMenu(hSubmenu);
PrepareShowFileMenu(hSubmenu);
break;
case FCIDM_MENU_EDIT:
//MergeEditMenu(hSubmenu);
//PrepareShowEditMenu(hSubmenu);
break;
case FCIDM_MENU_VIEW:
MergeViewMenu(hSubmenu);
PrepareShowViewMenu(hSubmenu);
break;
}

View file

@ -492,6 +492,8 @@
#define FCIDM_SHVIEW_INSERT 0x701A
#define FCIDM_SHVIEW_UNDO 0x701B
#define FCIDM_SHVIEW_INSERTLINK 0x701C
#define FCIDM_SHVIEW_COPYTO 0x701E
#define FCIDM_SHVIEW_MOVETO 0x701F
#define FCIDM_SHVIEW_SELECTALL 0x7021
#define FCIDM_SHVIEW_INVERTSELECTION 0x7022