https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5308a606dc79e429ea5be…
commit 5308a606dc79e429ea5be5e42a06526de2ec97f6
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Nov 9 08:08:40 2019 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Nov 9 08:08:40 2019 +0900
[SHELL32] Initial SendTo implementation (#2021)
This PR will realize SendTo feature. Initially, there is no file in SendTo folder
(displayed as "(None)"). If you added some shortcut files, then SendTo shows
some menu items.
- Copy, Move, and Link are working.
- Added icons.
CORE-12562
---
dll/win32/shell32/CMakeLists.txt | 1 +
dll/win32/shell32/CSendToMenu.cpp | 520 +++++++++++++++++++++++++++++++
dll/win32/shell32/CSendToMenu.h | 99 ++++++
dll/win32/shell32/lang/bg-BG.rc | 1 +
dll/win32/shell32/lang/ca-ES.rc | 3 +-
dll/win32/shell32/lang/cs-CZ.rc | 3 +-
dll/win32/shell32/lang/da-DK.rc | 1 +
dll/win32/shell32/lang/de-DE.rc | 1 +
dll/win32/shell32/lang/el-GR.rc | 3 +-
dll/win32/shell32/lang/en-GB.rc | 3 +-
dll/win32/shell32/lang/en-US.rc | 3 +-
dll/win32/shell32/lang/es-ES.rc | 1 +
dll/win32/shell32/lang/et-EE.rc | 3 +-
dll/win32/shell32/lang/fi-FI.rc | 1 +
dll/win32/shell32/lang/fr-FR.rc | 3 +-
dll/win32/shell32/lang/he-IL.rc | 1 +
dll/win32/shell32/lang/hi-IN.rc | 1 +
dll/win32/shell32/lang/hu-HU.rc | 3 +-
dll/win32/shell32/lang/id-ID.rc | 1 +
dll/win32/shell32/lang/it-IT.rc | 1 +
dll/win32/shell32/lang/ja-JP.rc | 3 +-
dll/win32/shell32/lang/ko-KR.rc | 3 +-
dll/win32/shell32/lang/nl-NL.rc | 3 +-
dll/win32/shell32/lang/no-NO.rc | 1 +
dll/win32/shell32/lang/pl-PL.rc | 1 +
dll/win32/shell32/lang/pt-BR.rc | 1 +
dll/win32/shell32/lang/pt-PT.rc | 1 +
dll/win32/shell32/lang/ro-RO.rc | 1 +
dll/win32/shell32/lang/ru-RU.rc | 1 +
dll/win32/shell32/lang/sk-SK.rc | 1 +
dll/win32/shell32/lang/sl-SI.rc | 3 +-
dll/win32/shell32/lang/sq-AL.rc | 1 +
dll/win32/shell32/lang/sv-SE.rc | 3 +-
dll/win32/shell32/lang/tr-TR.rc | 1 +
dll/win32/shell32/lang/uk-UA.rc | 1 +
dll/win32/shell32/lang/zh-CN.rc | 3 +-
dll/win32/shell32/lang/zh-TW.rc | 3 +-
dll/win32/shell32/precomp.h | 1 +
dll/win32/shell32/res/rgs/sendtomenu.rgs | 26 ++
dll/win32/shell32/rgs_res.rc | 1 +
dll/win32/shell32/shell32.cpp | 1 +
dll/win32/shell32/shresdef.h | 2 +
42 files changed, 700 insertions(+), 15 deletions(-)
diff --git a/dll/win32/shell32/CMakeLists.txt b/dll/win32/shell32/CMakeLists.txt
index ea2fe80631d..fb850fceafa 100644
--- a/dll/win32/shell32/CMakeLists.txt
+++ b/dll/win32/shell32/CMakeLists.txt
@@ -81,6 +81,7 @@ list(APPEND SOURCE
CDefaultContextMenu.cpp
COpenWithMenu.cpp
CNewMenu.cpp
+ CSendToMenu.cpp
CShellDispatch.cpp
CFolder.cpp
CFolderItems.cpp
diff --git a/dll/win32/shell32/CSendToMenu.cpp b/dll/win32/shell32/CSendToMenu.cpp
new file mode 100644
index 00000000000..4b0dcab1348
--- /dev/null
+++ b/dll/win32/shell32/CSendToMenu.cpp
@@ -0,0 +1,520 @@
+/*
+ * provides SendTo shell item service
+ *
+ * Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "precomp.h"
+#define INITGUID
+#include <guiddef.h>
+
+#define MAX_ITEM_COUNT 64
+
+WINE_DEFAULT_DEBUG_CHANNEL(shell);
+
+DEFINE_GUID(CLSID_SendToMenu, 0x7BA4C740, 0x9E81, 0x11CF,
+ 0x99, 0xD3, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37);
+
+CSendToMenu::CSendToMenu()
+ : m_hSubMenu(NULL)
+ , m_pItems(NULL)
+ , m_idCmdFirst(0)
+{
+ SHGetDesktopFolder(&m_pDesktop);
+ m_pSendTo = GetSpecialFolder(NULL, CSIDL_SENDTO);
+}
+
+CSendToMenu::~CSendToMenu()
+{
+ UnloadAllItems();
+
+ if (m_hSubMenu)
+ {
+ DestroyMenu(m_hSubMenu);
+ m_hSubMenu = NULL;
+ }
+}
+
+HRESULT CSendToMenu::DoDrop(IDataObject *pDataObject, IDropTarget *pDropTarget)
+{
+ DWORD dwEffect = DROPEFFECT_MOVE | DROPEFFECT_COPY | DROPEFFECT_LINK;
+
+ BOOL bShift = (GetAsyncKeyState(VK_SHIFT) < 0);
+ BOOL bCtrl = (GetAsyncKeyState(VK_CONTROL) < 0);
+
+ // THIS CODE IS NOT HUMAN-FRIENDLY. SORRY.
+ // (We have to translate a SendTo action to a Drop action)
+ DWORD dwKeyState = MK_LBUTTON;
+ if (bShift && bCtrl)
+ dwKeyState |= MK_SHIFT | MK_CONTROL;
+ else if (!bShift)
+ dwKeyState |= MK_CONTROL;
+ if (bCtrl)
+ dwKeyState |= MK_SHIFT;
+
+ POINTL ptl = { 0, 0 };
+ HRESULT hr = pDropTarget->DragEnter(pDataObject, dwKeyState, ptl, &dwEffect);
+ if (SUCCEEDED(hr) && dwEffect != DROPEFFECT_NONE)
+ {
+ // THIS CODE IS NOT HUMAN-FRIENDLY. SORRY.
+ // (We have to translate a SendTo action to a Drop action)
+ if (bShift && bCtrl)
+ dwEffect = DROPEFFECT_LINK;
+ else if (!bShift)
+ dwEffect = DROPEFFECT_MOVE;
+ else
+ dwEffect = DROPEFFECT_COPY;
+
+ hr = pDropTarget->Drop(pDataObject, dwKeyState, ptl, &dwEffect);
+ }
+ else
+ {
+ ERR("DragEnter: %08lX\n", hr);
+ pDropTarget->DragLeave();
+ }
+
+ return hr;
+}
+
+// get an IShellFolder from CSIDL
+IShellFolder *
+CSendToMenu::GetSpecialFolder(HWND hwnd, int csidl, LPITEMIDLIST *ppidl)
+{
+ if (ppidl)
+ *ppidl = NULL;
+
+ if (!m_pDesktop)
+ {
+ SHGetDesktopFolder(&m_pDesktop);
+ if (!m_pDesktop)
+ {
+ ERR("SHGetDesktopFolder\n");
+ return NULL;
+ }
+ }
+
+ LPITEMIDLIST pidl = NULL;
+ HRESULT hr = SHGetSpecialFolderLocation(hwnd, csidl, &pidl);
+ if (FAILED(hr))
+ {
+ ERR("SHGetSpecialFolderLocation: %08lX\n", hr);
+ return NULL;
+ }
+
+ IShellFolder *pFolder = NULL;
+ hr = m_pDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder,
&pFolder));
+
+ if (ppidl)
+ *ppidl = pidl;
+ else
+ CoTaskMemFree(pidl);
+
+ if (SUCCEEDED(hr))
+ return pFolder;
+
+ ERR("BindToObject: %08lX\n", hr);
+ return NULL;
+}
+
+// get a UI object from PIDL
+HRESULT CSendToMenu::GetUIObjectFromPidl(HWND hwnd, LPITEMIDLIST pidl,
+ REFIID riid, LPVOID *ppvOut)
+{
+ *ppvOut = NULL;
+
+ LPCITEMIDLIST pidlLast;
+ CComPtr<IShellFolder> pFolder;
+ HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &pFolder),
&pidlLast);
+ if (FAILED(hr))
+ {
+ ERR("SHBindToParent: %08lX\n", hr);
+ return hr;
+ }
+
+ hr = pFolder->GetUIObjectOf(hwnd, 1, &pidlLast, riid, NULL, ppvOut);
+ if (FAILED(hr))
+ {
+ ERR("GetUIObjectOf: %08lX\n", hr);
+ }
+ return hr;
+}
+
+void CSendToMenu::UnloadItem(SENDTO_ITEM *pItem)
+{
+ if (!pItem)
+ return;
+
+ CoTaskMemFree(pItem->pidlChild);
+ CoTaskMemFree(pItem->pszText);
+ DestroyIcon(pItem->hIcon);
+ HeapFree(GetProcessHeap(), 0, pItem);
+}
+
+void CSendToMenu::UnloadAllItems()
+{
+ SENDTO_ITEM *pItems = m_pItems;
+ m_pItems = NULL;
+ while (pItems)
+ {
+ SENDTO_ITEM *pCurItem = pItems;
+ pItems = pItems->pNext;
+ UnloadItem(pCurItem);
+ }
+}
+
+BOOL CSendToMenu::LoadAllItems(HWND hwnd)
+{
+ UnloadAllItems();
+
+ LPITEMIDLIST pidlSendTo;
+ m_pSendTo = GetSpecialFolder(hwnd, CSIDL_SENDTO, &pidlSendTo);
+ if (!m_pSendTo)
+ {
+ ERR("GetSpecialFolder\n");
+ return FALSE;
+ }
+
+ HRESULT hr;
+ CComPtr<IEnumIDList> pEnumIDList;
+ hr = m_pSendTo->EnumObjects(hwnd,
+ SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
+ &pEnumIDList);
+ if (FAILED(hr))
+ {
+ ERR("EnumObjects: %08lX\n", hr);
+ ILFree(pidlSendTo);
+ return FALSE;
+ }
+
+ BOOL bOK = TRUE;
+ LPITEMIDLIST pidlChild;
+ UINT nCount = 0;
+ while (pEnumIDList->Next(1, &pidlChild, NULL) == S_OK)
+ {
+ SENDTO_ITEM *pNewItem = (SENDTO_ITEM *)HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(SENDTO_ITEM));
+ if (!pNewItem)
+ {
+ ERR("HeapAlloc\n");
+ bOK = FALSE;
+ CoTaskMemFree(pidlChild);
+ break;
+ }
+
+ STRRET strret;
+ hr = m_pSendTo->GetDisplayNameOf(pidlChild, SHGDN_NORMAL, &strret);
+ if (SUCCEEDED(hr))
+ {
+ LPWSTR pszText = NULL;
+ hr = StrRetToStrW(&strret, pidlChild, &pszText);
+ if (SUCCEEDED(hr))
+ {
+ LPITEMIDLIST pidlAbsolute = ILCombine(pidlSendTo, pidlChild);
+
+ SHFILEINFOW fi = { NULL };
+ const UINT uFlags = SHGFI_PIDL | SHGFI_TYPENAME |
+ SHGFI_ICON | SHGFI_SMALLICON;
+ SHGetFileInfoW((LPCWSTR)pidlAbsolute, 0, &fi, sizeof(fi), uFlags);
+
+ ILFree(pidlAbsolute);
+
+ pNewItem->pidlChild = pidlChild;
+ pNewItem->pszText = pszText;
+ pNewItem->hIcon = fi.hIcon;
+ if (m_pItems)
+ {
+ pNewItem->pNext = m_pItems;
+ }
+ m_pItems = pNewItem;
+
+ // successful
+ ++nCount;
+ if (nCount >= MAX_ITEM_COUNT)
+ {
+ break;
+ }
+ continue;
+ }
+ else
+ {
+ ERR("StrRetToStrW: %08lX\n", hr);
+ }
+ }
+ else
+ {
+ ERR("GetDisplayNameOf: %08lX\n", hr);
+ }
+
+ UnloadItem(pNewItem);
+ CoTaskMemFree(pidlChild);
+ }
+
+ ILFree(pidlSendTo);
+
+ return bOK;
+}
+
+UINT CSendToMenu::InsertSendToItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
+{
+ if (m_pItems == NULL)
+ {
+ if (!LoadAllItems(NULL))
+ {
+ ERR("LoadAllItems\n");
+ return 0;
+ }
+ }
+
+ m_idCmdFirst = idCmdFirst;
+
+ UINT idCmd = idCmdFirst;
+ UINT nCount = 0;
+ for (SENDTO_ITEM *pCurItem = m_pItems; pCurItem; pCurItem = pCurItem->pNext)
+ {
+ const UINT uFlags = MF_BYPOSITION | MF_STRING | MF_ENABLED;
+ if (InsertMenuW(hMenu, Pos, uFlags, idCmd, pCurItem->pszText))
+ {
+ MENUITEMINFOW mii;
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA | MIIM_BITMAP;
+ mii.dwItemData = (ULONG_PTR)pCurItem;
+ mii.hbmpItem = HBMMENU_CALLBACK;
+ SetMenuItemInfoW(hMenu, idCmd, FALSE, &mii);
+ ++idCmd;
+
+ // successful
+ ++nCount;
+ if (nCount >= MAX_ITEM_COUNT)
+ {
+ break;
+ }
+ }
+ }
+
+ if (idCmd == idCmdFirst)
+ {
+ WCHAR szNone[64] = L"(None)";
+ LoadStringW(shell32_hInstance, IDS_NONE, szNone, _countof(szNone));
+
+ AppendMenuW(hMenu, MF_GRAYED | MF_DISABLED | MF_STRING, idCmd, szNone);
+ }
+
+ return idCmd - idCmdFirst;
+}
+
+CSendToMenu::SENDTO_ITEM *CSendToMenu::FindItemFromIdOffset(UINT IdOffset)
+{
+ UINT idCmd = m_idCmdFirst + IdOffset;
+
+ MENUITEMINFOW mii = { sizeof(mii) };
+ mii.fMask = MIIM_DATA;
+ if (GetMenuItemInfoW(m_hSubMenu, idCmd, FALSE, &mii))
+ return (SENDTO_ITEM *)mii.dwItemData;
+
+ ERR("GetMenuItemInfoW\n");
+ return NULL;
+}
+
+HRESULT CSendToMenu::DoSendToItem(SENDTO_ITEM *pItem, LPCMINVOKECOMMANDINFO lpici)
+{
+ if (!m_pDataObject)
+ {
+ ERR("!m_pDataObject\n");
+ return E_FAIL;
+ }
+
+ HRESULT hr;
+ CComPtr<IDropTarget> pDropTarget;
+ LPITEMIDLIST pidlChild = pItem->pidlChild;
+ hr = m_pSendTo->GetUIObjectOf(NULL, 1, &pidlChild, IID_IDropTarget,
+ NULL, (LPVOID *)&pDropTarget);
+ if (SUCCEEDED(hr))
+ {
+ hr = DoDrop(m_pDataObject, pDropTarget);
+ }
+ else
+ {
+ ERR("GetUIObjectOf: %08lX\n", hr);
+ }
+
+ return hr;
+}
+
+STDMETHODIMP CSendToMenu::SetSite(IUnknown *pUnkSite)
+{
+ m_pSite = pUnkSite;
+ return S_OK;
+}
+
+STDMETHODIMP CSendToMenu::GetSite(REFIID riid, void **ppvSite)
+{
+ if (!m_pSite)
+ return E_FAIL;
+
+ return m_pSite->QueryInterface(riid, ppvSite);
+}
+
+STDMETHODIMP
+CSendToMenu::QueryContextMenu(HMENU hMenu,
+ UINT indexMenu,
+ UINT idCmdFirst,
+ UINT idCmdLast,
+ UINT uFlags)
+{
+ TRACE("%p %p %u %u %u %u\n", this,
+ hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
+
+ WCHAR wszSendTo[64];
+ if (!LoadStringW(shell32_hInstance, IDS_SENDTO,
+ wszSendTo, _countof(wszSendTo)))
+ {
+ ERR("IDS_SENDTO\n");
+ return E_FAIL;
+ }
+
+ HMENU hSubMenu = CreateMenu();
+ if (!hSubMenu)
+ {
+ ERR("CreateMenu\n");
+ return E_FAIL;
+ }
+
+ UINT cItems = InsertSendToItems(hSubMenu, idCmdFirst, 0);
+
+ MENUITEMINFOW mii;
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE | MIIM_SUBMENU;
+ mii.fType = MFT_STRING;
+ mii.wID = -1;
+ mii.dwTypeData = wszSendTo;
+ mii.cch = wcslen(mii.dwTypeData);
+ mii.fState = MFS_ENABLED;
+ mii.hSubMenu = hSubMenu;
+ if (!InsertMenuItemW(hMenu, indexMenu, TRUE, &mii))
+ {
+ ERR("InsertMenuItemW\n");
+ return E_FAIL;
+ }
+
+ HMENU hOldSubMenu = m_hSubMenu;
+ m_hSubMenu = hSubMenu;
+ DestroyMenu(hOldSubMenu);
+
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cItems);
+}
+
+STDMETHODIMP
+CSendToMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
+{
+ HRESULT hr = E_FAIL;
+
+ WORD idCmd = LOWORD(lpici->lpVerb);
+ TRACE("idCmd: %d\n", idCmd);
+
+ SENDTO_ITEM *pItem = FindItemFromIdOffset(idCmd);
+ if (pItem)
+ {
+ hr = DoSendToItem(pItem, lpici);
+ }
+ else
+ {
+ ERR("FindItemFromIdOffset\n");
+ }
+
+ TRACE("CSendToMenu::InvokeCommand %x\n", hr);
+ return hr;
+}
+
+STDMETHODIMP
+CSendToMenu::GetCommandString(UINT_PTR idCmd,
+ UINT uType,
+ UINT *pwReserved,
+ LPSTR pszName,
+ UINT cchMax)
+{
+ FIXME("%p %lu %u %p %p %u\n", this,
+ idCmd, uType, pwReserved, pszName, cchMax);
+
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP
+CSendToMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ return S_OK;
+}
+
+STDMETHODIMP
+CSendToMenu::HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam,
+ LRESULT *plResult)
+{
+ UINT cxSmall = GetSystemMetrics(SM_CXSMICON);
+ UINT cySmall = GetSystemMetrics(SM_CYSMICON);
+
+ switch (uMsg)
+ {
+ case WM_MEASUREITEM:
+ {
+ MEASUREITEMSTRUCT* lpmis =
reinterpret_cast<MEASUREITEMSTRUCT*>(lParam);
+ if (!lpmis || lpmis->CtlType != ODT_MENU)
+ break;
+
+ UINT cxMenuCheck = GetSystemMetrics(SM_CXMENUCHECK);
+ if (lpmis->itemWidth < cxMenuCheck)
+ lpmis->itemWidth = cxMenuCheck;
+ if (lpmis->itemHeight < cySmall)
+ lpmis->itemHeight = cySmall;
+
+ if (plResult)
+ *plResult = TRUE;
+ break;
+ }
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT* lpdis = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
+ if (!lpdis || lpdis->CtlType != ODT_MENU)
+ break;
+
+ SENDTO_ITEM *pItem = (SENDTO_ITEM *)lpdis->itemData;
+ HICON hIcon = NULL;
+ if (pItem)
+ hIcon = pItem->hIcon;
+ if (!hIcon)
+ break;
+
+ RECT rcItem = lpdis->rcItem;
+ DrawIconEx(lpdis->hDC, 2,
+ lpdis->rcItem.top + (rcItem.bottom - rcItem.top - 16) / 2,
+ hIcon, cxSmall, cySmall, 0, NULL, DI_NORMAL);
+
+ if (plResult)
+ *plResult = TRUE;
+ }
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP
+CSendToMenu::Initialize(PCIDLIST_ABSOLUTE pidlFolder,
+ IDataObject *pdtobj, HKEY hkeyProgID)
+{
+ m_pDataObject = pdtobj;
+ return S_OK;
+}
diff --git a/dll/win32/shell32/CSendToMenu.h b/dll/win32/shell32/CSendToMenu.h
new file mode 100644
index 00000000000..b8a455e6630
--- /dev/null
+++ b/dll/win32/shell32/CSendToMenu.h
@@ -0,0 +1,99 @@
+/*
+ * provides new shell item service
+ *
+ * Copyright 2019 Katayama Hirofumi MZ.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _SHV_ITEM_SENDTO_H_
+#define _SHV_ITEM_SENDTO_H_
+
+extern "C" const GUID CLSID_SendToMenu;
+
+class CSendToMenu :
+ public CComCoClass<CSendToMenu, &CLSID_SendToMenu>,
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IObjectWithSite,
+ public IContextMenu3,
+ public IShellExtInit
+{
+private:
+ struct SENDTO_ITEM
+ {
+ LPITEMIDLIST pidlChild;
+ LPWSTR pszText;
+ HICON hIcon;
+ SENDTO_ITEM *pNext;
+ };
+
+ HMENU m_hSubMenu;
+ SENDTO_ITEM *m_pItems;
+ UINT m_idCmdFirst;
+
+ CComPtr<IUnknown> m_pSite;
+ CComPtr<IShellFolder> m_pDesktop;
+ CComPtr<IShellFolder> m_pSendTo;
+ CComPtr<IDataObject> m_pDataObject;
+
+ BOOL LoadAllItems(HWND hwnd);
+ void UnloadItem(SENDTO_ITEM *pItem);
+ void UnloadAllItems();
+
+ UINT InsertSendToItems(HMENU hMenu, UINT idFirst, UINT idMenu);
+
+ SENDTO_ITEM *FindItemFromIdOffset(UINT IdOffset);
+ HRESULT DoSendToItem(SENDTO_ITEM *pItem, LPCMINVOKECOMMANDINFO lpici);
+
+ HRESULT DoDrop(IDataObject *pDataObject, IDropTarget *pDropTarget);
+ IShellFolder *GetSpecialFolder(HWND hwnd, int csidl, LPITEMIDLIST *ppidl = NULL);
+ HRESULT GetUIObjectFromPidl(HWND hwnd, LPITEMIDLIST pidl, REFIID riid, LPVOID
*ppvOut);
+
+public:
+ CSendToMenu();
+ ~CSendToMenu();
+
+ // IObjectWithSite
+ STDMETHODIMP SetSite(IUnknown *pUnkSite);
+ STDMETHODIMP GetSite(REFIID riid, void **ppvSite);
+
+ // IContextMenu
+ STDMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT
idCmdLast, UINT uFlags);
+ STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
+ STDMETHODIMP GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved,
LPSTR lpszName, UINT uMaxNameLen);
+
+ // IContextMenu3
+ STDMETHODIMP HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT
*plResult);
+
+ // IContextMenu2
+ STDMETHODIMP HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ // IShellExtInit
+ STDMETHODIMP Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pdtobj, HKEY
hkeyProgID);
+
+ DECLARE_REGISTRY_RESOURCEID(IDR_SENDTOMENU)
+ DECLARE_NOT_AGGREGATABLE(CSendToMenu)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CSendToMenu)
+ COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
+ COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
+ END_COM_MAP()
+};
+
+#endif /* _SHV_ITEM_SENDTO_H_ */
diff --git a/dll/win32/shell32/lang/bg-BG.rc b/dll/win32/shell32/lang/bg-BG.rc
index 66935c43133..ac083431deb 100644
--- a/dll/win32/shell32/lang/bg-BG.rc
+++ b/dll/win32/shell32/lang/bg-BG.rc
@@ -873,6 +873,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Папка"
diff --git a/dll/win32/shell32/lang/ca-ES.rc b/dll/win32/shell32/lang/ca-ES.rc
index a8df7f1d04c..1a4ba5be874 100644
--- a/dll/win32/shell32/lang/ca-ES.rc
+++ b/dll/win32/shell32/lang/ca-ES.rc
@@ -815,7 +815,7 @@ BEGIN
IDS_FAVORITES "Favorites"
IDS_STARTUP "Start Menu\\Programs\\StartUp"
IDS_RECENT "Recent"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "Start Menu"
IDS_MYMUSIC "My Music"
IDS_MYVIDEO "My Videos"
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Folder"
diff --git a/dll/win32/shell32/lang/cs-CZ.rc b/dll/win32/shell32/lang/cs-CZ.rc
index 7df419e9e25..eb4da556af9 100644
--- a/dll/win32/shell32/lang/cs-CZ.rc
+++ b/dll/win32/shell32/lang/cs-CZ.rc
@@ -821,7 +821,7 @@ BEGIN
IDS_FAVORITES "Oblíbené"
IDS_STARTUP "Nabídka Start\\Programy\\Po spuštění"
IDS_RECENT "Poslední dokumenty"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "Nabídka Start"
IDS_MYMUSIC "Hudba"
IDS_MYVIDEO "Filmy"
@@ -878,6 +878,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Složka"
diff --git a/dll/win32/shell32/lang/da-DK.rc b/dll/win32/shell32/lang/da-DK.rc
index 58cb3d542cf..445c85a043e 100644
--- a/dll/win32/shell32/lang/da-DK.rc
+++ b/dll/win32/shell32/lang/da-DK.rc
@@ -878,6 +878,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Folder"
diff --git a/dll/win32/shell32/lang/de-DE.rc b/dll/win32/shell32/lang/de-DE.rc
index c27ddcc3605..0061ff76d81 100644
--- a/dll/win32/shell32/lang/de-DE.rc
+++ b/dll/win32/shell32/lang/de-DE.rc
@@ -873,6 +873,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Auswerfen des Mediums nicht möglich (Fehlercode:
%lu)."
IDS_CANTSHOWPROPERTIES "Anzeigen der Eigenschaften nicht möglich (Fehlercode:
%lu)."
IDS_CANTDISCONNECT "Trennen nicht möglich (Fehlercode: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Dateiordner"
diff --git a/dll/win32/shell32/lang/el-GR.rc b/dll/win32/shell32/lang/el-GR.rc
index 2f54284ad72..0240442978f 100644
--- a/dll/win32/shell32/lang/el-GR.rc
+++ b/dll/win32/shell32/lang/el-GR.rc
@@ -815,7 +815,7 @@ BEGIN
IDS_FAVORITES "Favorites"
IDS_STARTUP "Start Menu\\Programs\\StartUp"
IDS_RECENT "Recent"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "Start Menu"
IDS_MYMUSIC "My Music"
IDS_MYVIDEO "My Videos"
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Folder"
diff --git a/dll/win32/shell32/lang/en-GB.rc b/dll/win32/shell32/lang/en-GB.rc
index bd6f5bf13f0..80ae4fdfb72 100644
--- a/dll/win32/shell32/lang/en-GB.rc
+++ b/dll/win32/shell32/lang/en-GB.rc
@@ -815,7 +815,7 @@ BEGIN
IDS_FAVORITES "Favorites"
IDS_STARTUP "Start Menu\\Programs\\StartUp"
IDS_RECENT "Recent"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "Start Menu"
IDS_MYMUSIC "My Music"
IDS_MYVIDEO "My Videos"
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Folder"
diff --git a/dll/win32/shell32/lang/en-US.rc b/dll/win32/shell32/lang/en-US.rc
index ab0e99822f0..3e049ea5877 100644
--- a/dll/win32/shell32/lang/en-US.rc
+++ b/dll/win32/shell32/lang/en-US.rc
@@ -815,7 +815,7 @@ BEGIN
IDS_FAVORITES "Favorites"
IDS_STARTUP "Start Menu\\Programs\\StartUp"
IDS_RECENT "Recent"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "Start Menu"
IDS_MYMUSIC "My Music"
IDS_MYVIDEO "My Videos"
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Folder"
diff --git a/dll/win32/shell32/lang/es-ES.rc b/dll/win32/shell32/lang/es-ES.rc
index 99a3f9fe8fc..95c57999784 100644
--- a/dll/win32/shell32/lang/es-ES.rc
+++ b/dll/win32/shell32/lang/es-ES.rc
@@ -880,6 +880,7 @@ BEGIN
IDS_CANTEJECTMEDIA "No se pudo extraer la unidad (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "No se puede mostrar las propiedades (Error Code:
%lu)."
IDS_CANTDISCONNECT "No se pudo desconectar (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Directorio"
diff --git a/dll/win32/shell32/lang/et-EE.rc b/dll/win32/shell32/lang/et-EE.rc
index e3f70243acc..295b6f3a4a8 100644
--- a/dll/win32/shell32/lang/et-EE.rc
+++ b/dll/win32/shell32/lang/et-EE.rc
@@ -822,7 +822,7 @@ BEGIN
IDS_FAVORITES "Lemmikud"
IDS_STARTUP "Start Menu\\Programs\\StartUp"
IDS_RECENT "Hiljutised"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "Start Menüü"
IDS_MYMUSIC "Minu muusika"
IDS_MYVIDEO "Minu videod"
@@ -879,6 +879,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Ei saa meediumit väljutada (Veateade: %lu)."
IDS_CANTSHOWPROPERTIES "Ei saa atribuute näidata (Veateade: %lu)."
IDS_CANTDISCONNECT "Ei saa lahti ühendada (Veateade: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Kaust"
diff --git a/dll/win32/shell32/lang/fi-FI.rc b/dll/win32/shell32/lang/fi-FI.rc
index d45b70b30b4..c3d16d96d90 100644
--- a/dll/win32/shell32/lang/fi-FI.rc
+++ b/dll/win32/shell32/lang/fi-FI.rc
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Folder"
diff --git a/dll/win32/shell32/lang/fr-FR.rc b/dll/win32/shell32/lang/fr-FR.rc
index 50cbedfd9a0..f93ce816bb6 100644
--- a/dll/win32/shell32/lang/fr-FR.rc
+++ b/dll/win32/shell32/lang/fr-FR.rc
@@ -815,7 +815,7 @@ BEGIN
IDS_FAVORITES "Favoris"
IDS_STARTUP "Menu Démarrer\\Programmes\\Démarrage"
IDS_RECENT "Recent"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "Menu Démarrer"
IDS_MYMUSIC "Ma musique"
IDS_MYVIDEO "Mes vidéos"
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Impossible d'éjecter le média (code d'erreur :
%lu)."
IDS_CANTSHOWPROPERTIES "Impossible de montrer les propriétés (code d'erreur
: %lu)."
IDS_CANTDISCONNECT "Impossible de déconnecter (code d'erreur : %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Dossier"
diff --git a/dll/win32/shell32/lang/he-IL.rc b/dll/win32/shell32/lang/he-IL.rc
index 648e2870851..ff7da470c61 100644
--- a/dll/win32/shell32/lang/he-IL.rc
+++ b/dll/win32/shell32/lang/he-IL.rc
@@ -874,6 +874,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "תיקיה"
diff --git a/dll/win32/shell32/lang/hi-IN.rc b/dll/win32/shell32/lang/hi-IN.rc
index 10d651995c6..76e7cc2a6d0 100644
--- a/dll/win32/shell32/lang/hi-IN.rc
+++ b/dll/win32/shell32/lang/hi-IN.rc
@@ -867,6 +867,7 @@ BEGIN
IDS_CANTEJECTMEDIA "मीडिया को इजेक्ट करने में असमर्थ (एरर कोड: %lu)."
IDS_CANTSHOWPROPERTIES "गुण दिखाने में असमर्थ (एरर कोड: %lu)."
IDS_CANTDISCONNECT "डिस्कनेक्ट करने में असमर्थ (एरर कोड: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "फोल्डर"
diff --git a/dll/win32/shell32/lang/hu-HU.rc b/dll/win32/shell32/lang/hu-HU.rc
index c53607bca99..d840240b990 100644
--- a/dll/win32/shell32/lang/hu-HU.rc
+++ b/dll/win32/shell32/lang/hu-HU.rc
@@ -815,7 +815,7 @@ BEGIN
IDS_FAVORITES "Kedvencek"
IDS_STARTUP "Start Menu\\Programs\\Automatikus indítás" /* MS style:
Indítópult */
IDS_RECENT "Recent"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "Start Menu"
IDS_MYMUSIC "Zenék"
IDS_MYVIDEO "Videók"
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Folder"
diff --git a/dll/win32/shell32/lang/id-ID.rc b/dll/win32/shell32/lang/id-ID.rc
index 342e66f1053..4e9a7c654e2 100644
--- a/dll/win32/shell32/lang/id-ID.rc
+++ b/dll/win32/shell32/lang/id-ID.rc
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Tidak bisa mengeluarkan media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Tidak bisa menampilkan properti (Error Code:
%lu)."
IDS_CANTDISCONNECT "Tidak bisa memutuskan (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Folder"
diff --git a/dll/win32/shell32/lang/it-IT.rc b/dll/win32/shell32/lang/it-IT.rc
index 8816f1b0d4d..a109c0d74fc 100644
--- a/dll/win32/shell32/lang/it-IT.rc
+++ b/dll/win32/shell32/lang/it-IT.rc
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Cartella"
diff --git a/dll/win32/shell32/lang/ja-JP.rc b/dll/win32/shell32/lang/ja-JP.rc
index c6e8f3fb974..957ba56388a 100644
--- a/dll/win32/shell32/lang/ja-JP.rc
+++ b/dll/win32/shell32/lang/ja-JP.rc
@@ -812,7 +812,7 @@ BEGIN
IDS_FAVORITES "Favorites"
IDS_STARTUP "スタート メニュー\\プログラム\\スタートアップ"
IDS_RECENT "Recent"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "送る(&N)"
IDS_STARTMENU "スタート メニュー"
IDS_MYMUSIC "My Music"
IDS_MYVIDEO "My Videos"
@@ -869,6 +869,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "フォルダ"
diff --git a/dll/win32/shell32/lang/ko-KR.rc b/dll/win32/shell32/lang/ko-KR.rc
index 1f959484194..3647553a1f0 100644
--- a/dll/win32/shell32/lang/ko-KR.rc
+++ b/dll/win32/shell32/lang/ko-KR.rc
@@ -815,7 +815,7 @@ BEGIN
IDS_FAVORITES "Favorites"
IDS_STARTUP "Start Menu\\Programs\\StartUp"
IDS_RECENT "Recent"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "Start Menu"
IDS_MYMUSIC "My Music"
IDS_MYVIDEO "My Videos"
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Folder"
diff --git a/dll/win32/shell32/lang/nl-NL.rc b/dll/win32/shell32/lang/nl-NL.rc
index 2253aa474c7..db458b1b9e1 100644
--- a/dll/win32/shell32/lang/nl-NL.rc
+++ b/dll/win32/shell32/lang/nl-NL.rc
@@ -815,7 +815,7 @@ BEGIN
IDS_FAVORITES "Favorites"
IDS_STARTUP "Start Menu\\Programs\\StartUp"
IDS_RECENT "Recent"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "Start Menu"
IDS_MYMUSIC "My Music"
IDS_MYVIDEO "My Videos"
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Folder"
diff --git a/dll/win32/shell32/lang/no-NO.rc b/dll/win32/shell32/lang/no-NO.rc
index befbb8ec170..8dfeb901bba 100644
--- a/dll/win32/shell32/lang/no-NO.rc
+++ b/dll/win32/shell32/lang/no-NO.rc
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Mappe"
diff --git a/dll/win32/shell32/lang/pl-PL.rc b/dll/win32/shell32/lang/pl-PL.rc
index a97ee367e23..66461af8b7b 100644
--- a/dll/win32/shell32/lang/pl-PL.rc
+++ b/dll/win32/shell32/lang/pl-PL.rc
@@ -877,6 +877,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Nie można wysunąć nośnika (kod błędu: %lu)."
IDS_CANTSHOWPROPERTIES "Nie można pokazać właściwości (kod błędu: %lu)."
IDS_CANTDISCONNECT "Nie można odłączyć (kod błędu: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Katalog"
diff --git a/dll/win32/shell32/lang/pt-BR.rc b/dll/win32/shell32/lang/pt-BR.rc
index 75de4889eae..2e9abdc3702 100644
--- a/dll/win32/shell32/lang/pt-BR.rc
+++ b/dll/win32/shell32/lang/pt-BR.rc
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Pasta"
diff --git a/dll/win32/shell32/lang/pt-PT.rc b/dll/win32/shell32/lang/pt-PT.rc
index 7bd2cf27e61..26e26d915cf 100644
--- a/dll/win32/shell32/lang/pt-PT.rc
+++ b/dll/win32/shell32/lang/pt-PT.rc
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Pasta"
diff --git a/dll/win32/shell32/lang/ro-RO.rc b/dll/win32/shell32/lang/ro-RO.rc
index b38c1cdb31e..a53281668b8 100644
--- a/dll/win32/shell32/lang/ro-RO.rc
+++ b/dll/win32/shell32/lang/ro-RO.rc
@@ -874,6 +874,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Eșec la scoaterea mediului de stocare (Cod de eroare:
%lu)."
IDS_CANTSHOWPROPERTIES "Eșec la inspecția proprietăților (Cod de eroare:
%lu)."
IDS_CANTDISCONNECT "Eșec la deconectare (Cod de eroare: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Dosar"
diff --git a/dll/win32/shell32/lang/ru-RU.rc b/dll/win32/shell32/lang/ru-RU.rc
index cb72c7e7da1..2072afb9558 100644
--- a/dll/win32/shell32/lang/ru-RU.rc
+++ b/dll/win32/shell32/lang/ru-RU.rc
@@ -879,6 +879,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Не удалось извлечь носитель (код ошибки: %lu)."
IDS_CANTSHOWPROPERTIES "Не удалось вывести свойства (код ошибки: %lu)."
IDS_CANTDISCONNECT "Не удалось отсоединить сетевой диск (код ошибки:
%lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Папка с файлами"
diff --git a/dll/win32/shell32/lang/sk-SK.rc b/dll/win32/shell32/lang/sk-SK.rc
index 4801c057129..96f9637d067 100644
--- a/dll/win32/shell32/lang/sk-SK.rc
+++ b/dll/win32/shell32/lang/sk-SK.rc
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Priečinok"
diff --git a/dll/win32/shell32/lang/sl-SI.rc b/dll/win32/shell32/lang/sl-SI.rc
index 8865ff95873..01c5658256d 100644
--- a/dll/win32/shell32/lang/sl-SI.rc
+++ b/dll/win32/shell32/lang/sl-SI.rc
@@ -815,7 +815,7 @@ BEGIN
IDS_FAVORITES "Favorites"
IDS_STARTUP "Start Menu\\Programs\\StartUp"
IDS_RECENT "Recent"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "Start Menu"
IDS_MYMUSIC "My Music"
IDS_MYVIDEO "My Videos"
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Folder"
diff --git a/dll/win32/shell32/lang/sq-AL.rc b/dll/win32/shell32/lang/sq-AL.rc
index 6bd6e06a641..a7718e6dab9 100644
--- a/dll/win32/shell32/lang/sq-AL.rc
+++ b/dll/win32/shell32/lang/sq-AL.rc
@@ -876,6 +876,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Dosje"
diff --git a/dll/win32/shell32/lang/sv-SE.rc b/dll/win32/shell32/lang/sv-SE.rc
index 21d140c3078..029468c5ea6 100644
--- a/dll/win32/shell32/lang/sv-SE.rc
+++ b/dll/win32/shell32/lang/sv-SE.rc
@@ -815,7 +815,7 @@ BEGIN
IDS_FAVORITES "Favoriter"
IDS_STARTUP "Start-meny\\Program\\Autostart"
IDS_RECENT "Tidigare"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "Start-meny"
IDS_MYMUSIC "Min musik"
IDS_MYVIDEO "Mina videoklipp"
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Mapp"
diff --git a/dll/win32/shell32/lang/tr-TR.rc b/dll/win32/shell32/lang/tr-TR.rc
index 672d522488d..6b491372bf9 100644
--- a/dll/win32/shell32/lang/tr-TR.rc
+++ b/dll/win32/shell32/lang/tr-TR.rc
@@ -874,6 +874,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Unable to eject media (Error Code: %lu)."
IDS_CANTSHOWPROPERTIES "Unable to show properties (Error Code: %lu)."
IDS_CANTDISCONNECT "Unable to disconnect (Error Code: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Dizin"
diff --git a/dll/win32/shell32/lang/uk-UA.rc b/dll/win32/shell32/lang/uk-UA.rc
index 7c1de4f9dcd..96b20ade200 100644
--- a/dll/win32/shell32/lang/uk-UA.rc
+++ b/dll/win32/shell32/lang/uk-UA.rc
@@ -872,6 +872,7 @@ BEGIN
IDS_CANTEJECTMEDIA "Не вдалось відключити носій (код помилки: %lu)."
IDS_CANTSHOWPROPERTIES "Не вдалось відкрити властивості (код помилки:
%lu)."
IDS_CANTDISCONNECT "Не вдалось відключити (код помилки: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "Папка"
diff --git a/dll/win32/shell32/lang/zh-CN.rc b/dll/win32/shell32/lang/zh-CN.rc
index c8422233f31..b8881df8db0 100644
--- a/dll/win32/shell32/lang/zh-CN.rc
+++ b/dll/win32/shell32/lang/zh-CN.rc
@@ -825,7 +825,7 @@ BEGIN
IDS_FAVORITES "收藏夹"
IDS_STARTUP "「开始」菜单\\程序\\启动"
IDS_RECENT "Recent"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "「开始」菜单"
IDS_MYMUSIC "我的音乐"
IDS_MYVIDEO "我的视频"
@@ -882,6 +882,7 @@ BEGIN
IDS_CANTEJECTMEDIA "无法弹出媒体 (错误代码: %lu)."
IDS_CANTSHOWPROPERTIES "无法显示属性 (错误代码: %lu)."
IDS_CANTDISCONNECT "无法断开连接 (错误代码: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "文件夹"
diff --git a/dll/win32/shell32/lang/zh-TW.rc b/dll/win32/shell32/lang/zh-TW.rc
index 23d31c02a43..f3d35038a32 100644
--- a/dll/win32/shell32/lang/zh-TW.rc
+++ b/dll/win32/shell32/lang/zh-TW.rc
@@ -826,7 +826,7 @@ BEGIN
IDS_FAVORITES "我的最愛"
IDS_STARTUP "「開始」功能表\\程式\\啟動"
IDS_RECENT "Recent"
- IDS_SENDTO "SendTo"
+ IDS_SENDTO "Se&nd To"
IDS_STARTMENU "「開始」功能表"
IDS_MYMUSIC "我的音樂"
IDS_MYVIDEO "我的影片"
@@ -883,6 +883,7 @@ BEGIN
IDS_CANTEJECTMEDIA "無法退出媒體 (錯誤碼: %lu)."
IDS_CANTSHOWPROPERTIES "無法顯示內容 (錯誤碼: %lu)."
IDS_CANTDISCONNECT "無法中斷 (錯誤碼: %lu)."
+ IDS_NONE "(None)"
/* Friendly File Type Names */
IDS_DIRECTORY "資料夾"
diff --git a/dll/win32/shell32/precomp.h b/dll/win32/shell32/precomp.h
index 62aad907b1d..c58886e49ef 100644
--- a/dll/win32/shell32/precomp.h
+++ b/dll/win32/shell32/precomp.h
@@ -80,6 +80,7 @@
#include "droptargets/CFSDropTarget.h"
#include "COpenWithMenu.h"
#include "CNewMenu.h"
+#include "CSendToMenu.h"
#include "dialogs/filedefext.h"
#include "dialogs/drvdefext.h"
#include "CQueryAssociations.h"
diff --git a/dll/win32/shell32/res/rgs/sendtomenu.rgs
b/dll/win32/shell32/res/rgs/sendtomenu.rgs
new file mode 100644
index 00000000000..7b577b738c2
--- /dev/null
+++ b/dll/win32/shell32/res/rgs/sendtomenu.rgs
@@ -0,0 +1,26 @@
+HKCR
+{
+ NoRemove CLSID
+ {
+ ForceRemove {7BA4C740-9E81-11CF-99D3-00AA004AE837} = s 'ReactOS SendTo Object
Service'
+ {
+ val flags = d '1'
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'Apartment'
+ }
+ }
+ }
+ NoRemove AllFilesystemObjects
+ {
+ NoRemove shellex
+ {
+ NoRemove ContextMenuHandlers
+ {
+ ForceRemove SendTo = s '{7BA4C740-9E81-11CF-99D3-00AA004AE837}'
+ {
+ }
+ }
+ }
+ }
+}
diff --git a/dll/win32/shell32/rgs_res.rc b/dll/win32/shell32/rgs_res.rc
index c50480d3fd1..d46053ddd99 100644
--- a/dll/win32/shell32/rgs_res.rc
+++ b/dll/win32/shell32/rgs_res.rc
@@ -29,3 +29,4 @@ IDR_REBARBANDSITE REGISTRY "res/rgs/rebarbandsite.rgs"
IDR_USERNOTIFICATION REGISTRY "res/rgs/usernotification.rgs"
IDR_SHELL REGISTRY "res/rgs/shell.rgs"
IDR_ACTIVEDESKTOP REGISTRY "res/rgs/activedesktop.rgs"
+IDR_SENDTOMENU REGISTRY "res/rgs/sendtomenu.rgs"
diff --git a/dll/win32/shell32/shell32.cpp b/dll/win32/shell32/shell32.cpp
index d75dccd5968..c244477cf6b 100644
--- a/dll/win32/shell32/shell32.cpp
+++ b/dll/win32/shell32/shell32.cpp
@@ -289,6 +289,7 @@ BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_RecycleBin, CRecycleBin)
OBJECT_ENTRY(CLSID_OpenWithMenu, COpenWithMenu)
OBJECT_ENTRY(CLSID_NewMenu, CNewMenu)
+ OBJECT_ENTRY(CLSID_SendToMenu, CSendToMenu)
OBJECT_ENTRY(CLSID_StartMenu, CStartMenuDummy)
OBJECT_ENTRY(CLSID_MenuBandSite, CMenuSite)
OBJECT_ENTRY(CLSID_MenuBand, CMenuBand)
diff --git a/dll/win32/shell32/shresdef.h b/dll/win32/shell32/shresdef.h
index 9f7d6747cfb..766f32f07dc 100644
--- a/dll/win32/shell32/shresdef.h
+++ b/dll/win32/shell32/shresdef.h
@@ -140,6 +140,7 @@
#define IDS_CANTEJECTMEDIA 158
#define IDS_CANTSHOWPROPERTIES 159
#define IDS_CANTDISCONNECT 160
+#define IDS_NONE 161
/* Friendly File Type Names */
#define IDS_DIRECTORY 200
@@ -811,3 +812,4 @@
#define IDR_USERNOTIFICATION 155
#define IDR_SHELL 156
#define IDR_ACTIVEDESKTOP 157
+#define IDR_SENDTOMENU 158