https://git.reactos.org/?p=reactos.git;a=commitdiff;h=62823a08cecf31f46a7b8…
commit 62823a08cecf31f46a7b8f4de91ceabda96941ca
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Wed Apr 24 03:41:41 2019 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Wed Apr 24 03:41:41 2019 +0200
[SHELL32] Make the new-item menu work (aka. make it dynamic) when the .lnk handler
doesn't have any ShellNew entry.
---
dll/win32/shell32/CNewMenu.cpp | 50 +++++++++++++++++++++++++-----------------
dll/win32/shell32/CNewMenu.h | 1 +
2 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/dll/win32/shell32/CNewMenu.cpp b/dll/win32/shell32/CNewMenu.cpp
index c4c3c28a97..3445ebdcfe 100644
--- a/dll/win32/shell32/CNewMenu.cpp
+++ b/dll/win32/shell32/CNewMenu.cpp
@@ -31,6 +31,9 @@ CNewMenu::CNewMenu() :
m_pItems(NULL),
m_pLinkItem(NULL),
m_pSite(NULL),
+ m_idCmdFirst(0),
+ m_idCmdFolder(-1),
+ m_idCmdLink(-1),
m_hIconFolder(NULL),
m_hIconLink(NULL)
{
@@ -297,6 +300,9 @@ CNewMenu::LoadCachedItems()
BOOL
CNewMenu::LoadAllItems()
{
+ // TODO: We need to find a way to refresh the cache from time to time, when
+ // e.g. new extensions with ShellNew handlers have been added or removed.
+
/* If there are any unload them */
UnloadAllItems();
@@ -324,6 +330,8 @@ CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
+ m_idCmdFirst = idCmd;
+
/* Insert the new folder action */
if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEWFOLDER, wszBuf,
_countof(wszBuf)))
wszBuf[0] = 0;
@@ -333,7 +341,7 @@ CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
mii.wID = idCmd;
mii.hbmpItem = HBMMENU_CALLBACK;
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
- ++idCmd;
+ m_idCmdFolder = idCmd++;
/* Insert the new shortcut action */
if (m_pLinkItem)
@@ -344,7 +352,7 @@ CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
mii.cch = wcslen(mii.dwTypeData);
mii.wID = idCmd;
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
- ++idCmd;
+ m_idCmdLink = idCmd++;
}
/* Insert a seperator for the custom new action */
@@ -354,7 +362,7 @@ CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
InsertMenuItemW(hMenu, Pos++, TRUE, &mii);
/* Insert the rest of the items */
- mii.fMask = MIIM_ID | MIIM_BITMAP | MIIM_STRING;
+ mii.fMask = MIIM_ID | MIIM_BITMAP | MIIM_STRING | MIIM_DATA;
mii.fType = 0;
for (SHELLNEW_ITEM *pCurItem = m_pItems; pCurItem; pCurItem = pCurItem->pNext)
@@ -364,6 +372,7 @@ CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
continue;
TRACE("szDesc %s\n", debugstr_w(pCurItem->pwszDesc));
+ mii.dwItemData = (ULONG_PTR)pCurItem;
mii.dwTypeData = pCurItem->pwszDesc;
mii.cch = wcslen(mii.dwTypeData);
mii.wID = idCmd;
@@ -376,23 +385,24 @@ CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT
Pos)
CNewMenu::SHELLNEW_ITEM *CNewMenu::FindItemFromIdOffset(UINT IdOffset)
{
- if (IdOffset == 0)
- return NULL; /* Folder */
-
- if (IdOffset == 1)
- return m_pLinkItem; /* shortcut */
+ /* Folder */
+ if (m_idCmdFirst + IdOffset == m_idCmdFolder)
+ return NULL;
- /* Find shell new item */
- SHELLNEW_ITEM *pItem = m_pItems;
- for (UINT i = 2; pItem; ++i)
- {
- if (i == IdOffset)
- break;
+ /* Shortcut */
+ if (m_idCmdFirst + IdOffset == m_idCmdLink)
+ return m_pLinkItem;
- pItem = pItem->pNext;
- }
+ /* Find shell new item - Retrieve menu item info */
+ MENUITEMINFOW mii;
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA;
- return pItem;
+ if (GetMenuItemInfoW(m_hSubMenu, m_idCmdFirst + IdOffset, FALSE, &mii) &&
mii.dwItemData)
+ return (SHELLNEW_ITEM *)mii.dwItemData;
+ else
+ return NULL;
}
HRESULT CNewMenu::SelectNewItem(LONG wEventId, UINT uFlags, LPWSTR pszName, BOOL
bRename)
@@ -657,7 +667,7 @@ CNewMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
{
HRESULT hr = E_FAIL;
- if (LOWORD(lpici->lpVerb) == 0)
+ if (m_idCmdFirst + LOWORD(lpici->lpVerb) == m_idCmdFolder)
{
hr = CreateNewFolder(lpici);
}
@@ -722,11 +732,11 @@ CNewMenu::HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam,
LRESULT *plRes
DWORD id = LOWORD(lpdis->itemID);
HICON hIcon = NULL;
- if (id == 0)
+ if (m_idCmdFirst + id == m_idCmdFolder)
{
hIcon = m_hIconFolder;
}
- else if (id == 1)
+ else if (m_idCmdFirst + id == m_idCmdLink)
{
hIcon = m_hIconLink;
}
diff --git a/dll/win32/shell32/CNewMenu.h b/dll/win32/shell32/CNewMenu.h
index e5c45e73d2..738fae0213 100644
--- a/dll/win32/shell32/CNewMenu.h
+++ b/dll/win32/shell32/CNewMenu.h
@@ -59,6 +59,7 @@ private:
SHELLNEW_ITEM *m_pLinkItem; // Points to the link handler item in the m_pItems list.
CComPtr<IUnknown> m_pSite;
HMENU m_hSubMenu;
+ UINT m_idCmdFirst, m_idCmdFolder, m_idCmdLink;
HICON m_hIconFolder, m_hIconLink;
SHELLNEW_ITEM *LoadItem(LPCWSTR pwszExt);