mirror of
https://github.com/reactos/reactos.git
synced 2025-01-04 05:20:54 +00:00
Correctly create cache about ".lnk" and handling in the member functions. Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
This commit is contained in:
parent
f2512254e0
commit
8e60c2efee
2 changed files with 164 additions and 152 deletions
|
@ -4,6 +4,7 @@
|
||||||
* Copyright 2007 Johannes Anderwald (johannes.anderwald@reactos.org)
|
* Copyright 2007 Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||||
* Copyright 2009 Andrew Hill
|
* Copyright 2009 Andrew Hill
|
||||||
* Copyright 2012 Rafal Harabien
|
* Copyright 2012 Rafal Harabien
|
||||||
|
* Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -60,18 +61,14 @@ void CNewMenu::UnloadAllItems()
|
||||||
{
|
{
|
||||||
SHELLNEW_ITEM *pCurItem;
|
SHELLNEW_ITEM *pCurItem;
|
||||||
|
|
||||||
/* Unload normal items */
|
/* Unload the handler items, including the link item */
|
||||||
while (m_pItems)
|
while (m_pItems)
|
||||||
{
|
{
|
||||||
pCurItem = m_pItems;
|
pCurItem = m_pItems;
|
||||||
m_pItems = m_pItems->pNext;
|
m_pItems = m_pItems->pNext;
|
||||||
|
|
||||||
UnloadItem(pCurItem);
|
UnloadItem(pCurItem);
|
||||||
}
|
}
|
||||||
|
m_pItems = NULL;
|
||||||
/* Unload link item */
|
|
||||||
if (m_pLinkItem)
|
|
||||||
UnloadItem(m_pLinkItem);
|
|
||||||
m_pLinkItem = NULL;
|
m_pLinkItem = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,20 +180,20 @@ CNewMenu::CacheItems()
|
||||||
if (pNewItem)
|
if (pNewItem)
|
||||||
{
|
{
|
||||||
dwSize += wcslen(wszName) + 1;
|
dwSize += wcslen(wszName) + 1;
|
||||||
if (wcsicmp(pNewItem->pwszExt, L".lnk") == 0)
|
if (!m_pLinkItem && wcsicmp(pNewItem->pwszExt, L".lnk") == 0)
|
||||||
{
|
{
|
||||||
/* Link handler */
|
/* The unique link handler */
|
||||||
m_pLinkItem = pNewItem;
|
m_pLinkItem = pNewItem;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
/* Add at the end of the list */
|
||||||
/* Add at the end of list */
|
|
||||||
if (pCurItem)
|
if (pCurItem)
|
||||||
{
|
{
|
||||||
pCurItem->pNext = pNewItem;
|
pCurItem->pNext = pNewItem;
|
||||||
pCurItem = pNewItem;
|
pCurItem = pNewItem;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
pCurItem = m_pItems = pNewItem;
|
pCurItem = m_pItems = pNewItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,13 +205,10 @@ CNewMenu::CacheItems()
|
||||||
if (!lpValues)
|
if (!lpValues)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
lpValue = lpValues;
|
for (pCurItem = m_pItems, lpValue = lpValues; pCurItem; pCurItem = pCurItem->pNext)
|
||||||
pCurItem = m_pItems;
|
|
||||||
while (pCurItem)
|
|
||||||
{
|
{
|
||||||
memcpy(lpValue, pCurItem->pwszExt, (wcslen(pCurItem->pwszExt) + 1) * sizeof(WCHAR));
|
memcpy(lpValue, pCurItem->pwszExt, (wcslen(pCurItem->pwszExt) + 1) * sizeof(WCHAR));
|
||||||
lpValue += wcslen(pCurItem->pwszExt) + 1;
|
lpValue += wcslen(pCurItem->pwszExt) + 1;
|
||||||
pCurItem = pCurItem->pNext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RegCreateKeyEx(HKEY_CURRENT_USER, ShellNewKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
|
if (RegCreateKeyEx(HKEY_CURRENT_USER, ShellNewKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
|
||||||
|
@ -269,20 +263,20 @@ CNewMenu::LoadCachedItems()
|
||||||
pNewItem = LoadItem(wszName);
|
pNewItem = LoadItem(wszName);
|
||||||
if (pNewItem)
|
if (pNewItem)
|
||||||
{
|
{
|
||||||
if (wcsicmp(pNewItem->pwszExt, L".lnk") == 0)
|
if (!m_pLinkItem && wcsicmp(pNewItem->pwszExt, L".lnk") == 0)
|
||||||
{
|
{
|
||||||
/* Link handler */
|
/* The unique link handler */
|
||||||
m_pLinkItem = pNewItem;
|
m_pLinkItem = pNewItem;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
/* Add at the end of the list */
|
||||||
/* Add at the end of list */
|
|
||||||
if (pCurItem)
|
if (pCurItem)
|
||||||
{
|
{
|
||||||
pCurItem->pNext = pNewItem;
|
pCurItem->pNext = pNewItem;
|
||||||
pCurItem = pNewItem;
|
pCurItem = pNewItem;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
pCurItem = m_pItems = pNewItem;
|
pCurItem = m_pItems = pNewItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,21 +299,7 @@ CNewMenu::LoadAllItems()
|
||||||
CacheItems();
|
CacheItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_pLinkItem)
|
return (m_pItems != NULL);
|
||||||
{
|
|
||||||
m_pLinkItem = static_cast<SHELLNEW_ITEM *>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SHELLNEW_ITEM)));
|
|
||||||
if (m_pLinkItem)
|
|
||||||
{
|
|
||||||
m_pLinkItem->Type = SHELLNEW_TYPE_NULLFILE;
|
|
||||||
m_pLinkItem->pwszDesc = _wcsdup(L"Link");
|
|
||||||
m_pLinkItem->pwszExt = _wcsdup(L".lnk");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pItems == NULL)
|
|
||||||
return FALSE;
|
|
||||||
else
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT
|
UINT
|
||||||
|
@ -349,7 +329,9 @@ CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
|
||||||
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
|
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
|
||||||
++idCmd;
|
++idCmd;
|
||||||
|
|
||||||
/* Insert new shortcut action */
|
/* Insert the new shortcut action */
|
||||||
|
if (m_pLinkItem)
|
||||||
|
{
|
||||||
if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEWLINK, wszBuf, _countof(wszBuf)))
|
if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEWLINK, wszBuf, _countof(wszBuf)))
|
||||||
wszBuf[0] = 0;
|
wszBuf[0] = 0;
|
||||||
mii.dwTypeData = wszBuf;
|
mii.dwTypeData = wszBuf;
|
||||||
|
@ -357,6 +339,7 @@ CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
|
||||||
mii.wID = idCmd;
|
mii.wID = idCmd;
|
||||||
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
|
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
|
||||||
++idCmd;
|
++idCmd;
|
||||||
|
}
|
||||||
|
|
||||||
/* Insert seperator for custom new action */
|
/* Insert seperator for custom new action */
|
||||||
mii.fMask = MIIM_TYPE | MIIM_ID;
|
mii.fMask = MIIM_TYPE | MIIM_ID;
|
||||||
|
@ -371,6 +354,10 @@ CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
|
||||||
SHELLNEW_ITEM *pCurItem = m_pItems;
|
SHELLNEW_ITEM *pCurItem = m_pItems;
|
||||||
while (pCurItem)
|
while (pCurItem)
|
||||||
{
|
{
|
||||||
|
/* Skip shortcut item */
|
||||||
|
if (pCurItem == m_pLinkItem)
|
||||||
|
continue;
|
||||||
|
|
||||||
TRACE("szDesc %s\n", debugstr_w(pCurItem->pwszDesc));
|
TRACE("szDesc %s\n", debugstr_w(pCurItem->pwszDesc));
|
||||||
mii.dwTypeData = pCurItem->pwszDesc;
|
mii.dwTypeData = pCurItem->pwszDesc;
|
||||||
mii.cch = wcslen(mii.dwTypeData);
|
mii.cch = wcslen(mii.dwTypeData);
|
||||||
|
@ -404,13 +391,18 @@ CNewMenu::SHELLNEW_ITEM *CNewMenu::FindItemFromIdOffset(UINT IdOffset)
|
||||||
return pItem;
|
return pItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CNewMenu::SelectNewItem(LONG wEventId, UINT uFlags, LPWSTR pszName)
|
HRESULT CNewMenu::SelectNewItem(LONG wEventId, UINT uFlags, LPWSTR pszName, BOOL bRename)
|
||||||
{
|
{
|
||||||
CComPtr<IShellBrowser> lpSB;
|
CComPtr<IShellBrowser> lpSB;
|
||||||
CComPtr<IShellView> lpSV;
|
CComPtr<IShellView> lpSV;
|
||||||
HRESULT hr = E_FAIL;
|
HRESULT hr = E_FAIL;
|
||||||
LPITEMIDLIST pidl;
|
LPITEMIDLIST pidl;
|
||||||
PITEMID_CHILD pidlNewItem;
|
PITEMID_CHILD pidlNewItem;
|
||||||
|
DWORD dwSelectFlags;
|
||||||
|
|
||||||
|
dwSelectFlags = SVSI_DESELECTOTHERS | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT;
|
||||||
|
if (bRename)
|
||||||
|
dwSelectFlags |= SVSI_EDIT;
|
||||||
|
|
||||||
/* Notify the view object about the new item */
|
/* Notify the view object about the new item */
|
||||||
SHChangeNotify(wEventId, uFlags, (LPCVOID) pszName, NULL);
|
SHChangeNotify(wEventId, uFlags, (LPCVOID) pszName, NULL);
|
||||||
|
@ -430,8 +422,7 @@ HRESULT CNewMenu::SelectNewItem(LONG wEventId, UINT uFlags, LPWSTR pszName)
|
||||||
|
|
||||||
pidlNewItem = ILFindLastID(pidl);
|
pidlNewItem = ILFindLastID(pidl);
|
||||||
|
|
||||||
hr = lpSV->SelectItem(pidlNewItem, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE |
|
hr = lpSV->SelectItem(pidlNewItem, dwSelectFlags);
|
||||||
SVSI_FOCUSED | SVSI_SELECT);
|
|
||||||
|
|
||||||
SHFree(pidl);
|
SHFree(pidl);
|
||||||
|
|
||||||
|
@ -463,26 +454,14 @@ HRESULT CNewMenu::CreateNewFolder(LPCMINVOKECOMMANDINFO lpici)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
/* Show and select the new item in the def view */
|
/* Show and select the new item in the def view */
|
||||||
SelectNewItem(SHCNE_MKDIR, SHCNF_PATHW, wszName);
|
SelectNewItem(SHCNE_MKDIR, SHCNF_PATHW, wszName, TRUE);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CNewMenu::CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi)
|
HRESULT CNewMenu::NewItemByCommand(SHELLNEW_ITEM *pItem, LPCWSTR wszPath)
|
||||||
{
|
{
|
||||||
WCHAR wszBuf[MAX_PATH];
|
WCHAR wszBuf[MAX_PATH];
|
||||||
WCHAR wszPath[MAX_PATH];
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
/* Get folder path */
|
|
||||||
hr = SHGetPathFromIDListW(m_pidlFolder, wszPath);
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
switch (pItem->Type)
|
|
||||||
{
|
|
||||||
case SHELLNEW_TYPE_COMMAND:
|
|
||||||
{
|
|
||||||
LPWSTR Ptr, pwszCmd;
|
LPWSTR Ptr, pwszCmd;
|
||||||
WCHAR wszTemp[MAX_PATH];
|
WCHAR wszTemp[MAX_PATH];
|
||||||
STARTUPINFOW si;
|
STARTUPINFOW si;
|
||||||
|
@ -491,7 +470,7 @@ HRESULT CNewMenu::CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcm
|
||||||
if (!ExpandEnvironmentStringsW((LPWSTR)pItem->pData, wszBuf, _countof(wszBuf)))
|
if (!ExpandEnvironmentStringsW((LPWSTR)pItem->pData, wszBuf, _countof(wszBuf)))
|
||||||
{
|
{
|
||||||
TRACE("ExpandEnvironmentStrings failed\n");
|
TRACE("ExpandEnvironmentStrings failed\n");
|
||||||
break;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expand command parameter, FIXME: there can be more modifiers */
|
/* Expand command parameter, FIXME: there can be more modifiers */
|
||||||
|
@ -514,21 +493,21 @@ HRESULT CNewMenu::CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcm
|
||||||
{
|
{
|
||||||
CloseHandle(pi.hProcess);
|
CloseHandle(pi.hProcess);
|
||||||
CloseHandle(pi.hThread);
|
CloseHandle(pi.hThread);
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERR("Failed to create process\n");
|
ERR("Failed to create process\n");
|
||||||
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
case SHELLNEW_TYPE_DATA:
|
HRESULT CNewMenu::NewItemByNonCommand(SHELLNEW_ITEM *pItem, LPWSTR wszName,
|
||||||
case SHELLNEW_TYPE_FILENAME:
|
DWORD cchNameMax, LPCWSTR wszPath)
|
||||||
case SHELLNEW_TYPE_NULLFILE:
|
{
|
||||||
{
|
WCHAR wszBuf[MAX_PATH];
|
||||||
BOOL bSuccess = TRUE;
|
|
||||||
WCHAR wszName[MAX_PATH];
|
|
||||||
WCHAR wszNewFile[MAX_PATH];
|
WCHAR wszNewFile[MAX_PATH];
|
||||||
|
BOOL bSuccess = TRUE;
|
||||||
|
|
||||||
if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEW, wszBuf, _countof(wszBuf)))
|
if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEW, wszBuf, _countof(wszBuf)))
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
@ -569,16 +548,46 @@ HRESULT CNewMenu::CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcm
|
||||||
if (bSuccess)
|
if (bSuccess)
|
||||||
{
|
{
|
||||||
TRACE("Notifying fs %s\n", debugstr_w(wszName));
|
TRACE("Notifying fs %s\n", debugstr_w(wszName));
|
||||||
SelectNewItem(SHCNE_CREATE, SHCNF_PATHW, wszName);
|
SelectNewItem(SHCNE_CREATE, SHCNF_PATHW, wszName, pItem != m_pLinkItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Cannot create file: %s", wszName);
|
StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Cannot create file: %s", wszName);
|
||||||
MessageBoxW(NULL, wszBuf, L"Cannot create file", MB_OK|MB_ICONERROR); // FIXME load localized error msg
|
MessageBoxW(NULL, wszBuf, L"Cannot create file", MB_OK|MB_ICONERROR); // FIXME load localized error msg
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CNewMenu::CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
WCHAR wszPath[MAX_PATH], wszName[MAX_PATH];
|
||||||
|
|
||||||
|
/* Get folder path */
|
||||||
|
hr = SHGetPathFromIDListW(m_pidlFolder, wszPath);
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (pItem == m_pLinkItem)
|
||||||
|
{
|
||||||
|
NewItemByNonCommand(pItem, wszName, _countof(wszName), wszPath);
|
||||||
|
NewItemByCommand(pItem, wszName);
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (pItem->Type)
|
||||||
|
{
|
||||||
|
case SHELLNEW_TYPE_COMMAND:
|
||||||
|
NewItemByCommand(pItem, wszPath);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHELLNEW_TYPE_DATA:
|
||||||
|
case SHELLNEW_TYPE_FILENAME:
|
||||||
|
case SHELLNEW_TYPE_NULLFILE:
|
||||||
|
NewItemByNonCommand(pItem, wszName, _countof(wszName), wszPath);
|
||||||
|
break;
|
||||||
|
|
||||||
case SHELLNEW_TYPE_INVALID:
|
case SHELLNEW_TYPE_INVALID:
|
||||||
ERR("Invalid type\n");
|
ERR("Invalid type\n");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -56,7 +56,7 @@ private:
|
||||||
LPITEMIDLIST m_pidlFolder;
|
LPITEMIDLIST m_pidlFolder;
|
||||||
LPWSTR m_wszPath;
|
LPWSTR m_wszPath;
|
||||||
SHELLNEW_ITEM *m_pItems;
|
SHELLNEW_ITEM *m_pItems;
|
||||||
SHELLNEW_ITEM *m_pLinkItem;
|
SHELLNEW_ITEM *m_pLinkItem; // Points to the link handler item in the m_pItems list.
|
||||||
CComPtr<IUnknown> m_pSite;
|
CComPtr<IUnknown> m_pSite;
|
||||||
HMENU m_hSubMenu;
|
HMENU m_hSubMenu;
|
||||||
HICON m_hiconFolder, m_hiconLink;
|
HICON m_hiconFolder, m_hiconLink;
|
||||||
|
@ -71,7 +71,10 @@ private:
|
||||||
SHELLNEW_ITEM *FindItemFromIdOffset(UINT IdOffset);
|
SHELLNEW_ITEM *FindItemFromIdOffset(UINT IdOffset);
|
||||||
HRESULT CreateNewFolder(LPCMINVOKECOMMANDINFO lpici);
|
HRESULT CreateNewFolder(LPCMINVOKECOMMANDINFO lpici);
|
||||||
HRESULT CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi);
|
HRESULT CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi);
|
||||||
HRESULT SelectNewItem(LONG wEventId, UINT uFlags, LPWSTR pszName);
|
HRESULT SelectNewItem(LONG wEventId, UINT uFlags, LPWSTR pszName, BOOL bRename);
|
||||||
|
HRESULT NewItemByCommand(SHELLNEW_ITEM *pItem, LPCWSTR wszPath);
|
||||||
|
HRESULT NewItemByNonCommand(SHELLNEW_ITEM *pItem, LPWSTR wszName,
|
||||||
|
DWORD cchNameMax, LPCWSTR wszPath);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CNewMenu();
|
CNewMenu();
|
||||||
|
|
Loading…
Reference in a new issue