Author: gadamopoulos Date: Thu Nov 17 14:35:19 2016 New Revision: 73243
URL: http://svn.reactos.org/svn/reactos?rev=73243&view=rev Log: [SHELL32] - CDefaultContextMenu: Add rudimentary support for callbacks so as to let folders have item specific commands and remove all item specific code from this class. - Implement context menu callbacks for CFSFolder, CRegFolder, CDrivesFolder in order to let them handle the properties item and let the CDrivesFolder add and handle the Format item itself.
Modified: trunk/reactos/dll/win32/shell32/CDefaultContextMenu.cpp trunk/reactos/dll/win32/shell32/dialogs/drive.cpp trunk/reactos/dll/win32/shell32/dialogs/fprop.cpp trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp trunk/reactos/dll/win32/shell32/folders/CFSFolder.h trunk/reactos/dll/win32/shell32/folders/CNetFolder.cpp trunk/reactos/dll/win32/shell32/folders/CRecycleBin.cpp trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp trunk/reactos/dll/win32/shell32/shfldr.h trunk/reactos/dll/win32/shell32/shlfolder.cpp trunk/reactos/dll/win32/shell32/wine/shell32_main.h
Modified: trunk/reactos/dll/win32/shell32/CDefaultContextMenu.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/CDefaultC... ============================================================================== --- trunk/reactos/dll/win32/shell32/CDefaultContextMenu.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/CDefaultContextMenu.cpp [iso-8859-1] Thu Nov 17 14:35:19 2016 @@ -61,6 +61,8 @@ private: CComPtr<IUnknown> m_site; CComPtr<IShellFolder> m_psf; + CComPtr<IContextMenuCB> m_pmcb; + LPFNDFMCALLBACK m_pfnmcb; UINT m_cidl; PCUITEMID_CHILD_ARRAY m_apidl; CComPtr<IDataObject> m_pDataObj; @@ -75,6 +77,7 @@ UINT m_iIdSCMFirst; /* first static used id */ UINT m_iIdSCMLast; /* last static used id */
+ HRESULT _DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam); void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb); void AddStaticEntriesForKey(HKEY hKey); BOOL IsShellExtensionAlreadyLoaded(const CLSID *pclsid); @@ -93,7 +96,6 @@ HRESULT DoCopyOrCut(LPCMINVOKECOMMANDINFO lpcmi, BOOL bCopy); HRESULT DoRename(LPCMINVOKECOMMANDINFO lpcmi); HRESULT DoProperties(LPCMINVOKECOMMANDINFO lpcmi); - HRESULT DoFormat(LPCMINVOKECOMMANDINFO lpcmi); HRESULT DoCreateNewFolder(LPCMINVOKECOMMANDINFO lpici); HRESULT DoDynamicShellExtensions(LPCMINVOKECOMMANDINFO lpcmi); HRESULT DoStaticShellExtensions(LPCMINVOKECOMMANDINFO lpcmi); @@ -106,7 +108,7 @@ public: CDefaultContextMenu(); ~CDefaultContextMenu(); - HRESULT WINAPI Initialize(const DEFCONTEXTMENU *pdcm); + HRESULT WINAPI Initialize(const DEFCONTEXTMENU *pdcm, LPFNDFMCALLBACK lpfn);
// IContextMenu virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags); @@ -133,6 +135,8 @@
CDefaultContextMenu::CDefaultContextMenu() : m_psf(NULL), + m_pmcb(NULL), + m_pfnmcb(NULL), m_cidl(0), m_apidl(NULL), m_pDataObj(NULL), @@ -180,7 +184,7 @@ _ILFreeaPidl(const_cast<PITEMID_CHILD *>(m_apidl), m_cidl); }
-HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm) +HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm, LPFNDFMCALLBACK lpfn) { TRACE("cidl %u\n", pdcm->cidl);
@@ -189,6 +193,8 @@ if (m_cidl && !m_apidl) return E_OUTOFMEMORY; m_psf = pdcm->psf; + m_pmcb = pdcm->pcmcb; + m_pfnmcb = lpfn;
m_cKeys = pdcm->cKeys; if (pdcm->cKeys) @@ -214,6 +220,20 @@ ERR("GetCurFolder failed\n"); } TRACE("pidlFolder %p\n", m_pidlFolder); + } + + return S_OK; +} + +HRESULT CDefaultContextMenu::_DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam) +{ + if (m_pmcb) + { + return m_pmcb->CallBack(m_psf, NULL, m_pDataObj, uMsg, wParam, (LPARAM)lParam); + } + else if(m_pfnmcb) + { + return m_pfnmcb(m_psf, NULL, m_pDataObj, uMsg, wParam, (LPARAM)lParam); }
return S_OK; @@ -712,23 +732,15 @@ IndexMenu = InsertMenuItemsOfDynamicContextMenuExtension(hMenu, IndexMenu, iIdCmdFirst, iIdCmdLast); TRACE("IndexMenu %d\n", IndexMenu);
- if (_ILIsDrive(m_apidl[0])) - { - char szDrive[8] = {0}; - DWORD dwFlags; - - _ILGetDrive(m_apidl[0], szDrive, sizeof(szDrive)); - if (GetVolumeInformationA(szDrive, NULL, 0, NULL, NULL, &dwFlags, NULL, 0)) - { - /* Disable format if read only */ - if (!(dwFlags & FILE_READ_ONLY_VOLUME)) - { - _InsertMenuItemW(hMenu, IndexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); - _InsertMenuItemW(hMenu, IndexMenu++, TRUE, 0x7ABC, MFT_STRING, MAKEINTRESOURCEW(IDS_FORMATDRIVE), MFS_ENABLED); - bAddSep = TRUE; - } - } - } + /* Now let the callback add its own items */ + QCMINFO qcminfo; + qcminfo.hmenu = hMenu; + qcminfo.indexMenu = IndexMenu; + qcminfo.idCmdFirst = iIdCmdFirst; + qcminfo.idCmdLast = iIdCmdLast; + qcminfo.pIdMap = NULL; + _DoCallback(DFM_MERGECONTEXTMENU, uFlags, &qcminfo); + IndexMenu = GetMenuItemCount(hMenu);
BOOL bClipboardData = (HasClipboardData() && (rfg & SFGAO_FILESYSTEM)); if (rfg & (SFGAO_CANCOPY | SFGAO_CANMOVE) || bClipboardData) @@ -971,105 +983,8 @@ CDefaultContextMenu::DoProperties( LPCMINVOKECOMMANDINFO lpcmi) { - HRESULT hr = S_OK; - const ITEMIDLIST *pidlParent = m_pidlFolder, *pidlChild; - - if (!pidlParent) - { - CComPtr<IPersistFolder2> pf; - - /* pidlFolder is optional */ - if (SUCCEEDED(m_psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &pf)))) - { - pf->GetCurFolder((_ITEMIDLIST**)&pidlParent); - } - } - - if (m_cidl > 0) - pidlChild = m_apidl[0]; - else - { - /* Set pidlChild to last pidl of current folder */ - if (pidlParent == m_pidlFolder) - pidlParent = (ITEMIDLIST*)ILClone(pidlParent); - - pidlChild = (ITEMIDLIST*)ILClone(ILFindLastID(pidlParent)); - ILRemoveLastID((ITEMIDLIST*)pidlParent); - } - - if (_ILIsMyComputer(pidlChild)) - { - if (32 >= (UINT)ShellExecuteW(lpcmi->hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl", NULL, NULL, SW_SHOWNORMAL)) - hr = E_FAIL; - } - else if (_ILIsDesktop(pidlChild)) - { - if (32 >= (UINT)ShellExecuteW(lpcmi->hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL, NULL, SW_SHOWNORMAL)) - hr = E_FAIL; - } - else if (_ILIsDrive(pidlChild)) - { - WCHAR wszBuf[MAX_PATH]; - ILGetDisplayName(pidlChild, wszBuf); - if (!SH_ShowDriveProperties(wszBuf, pidlParent, &pidlChild)) - hr = E_FAIL; - } - else if (_ILIsNetHood(pidlChild)) - { - // FIXME path! - if (32 >= (UINT)ShellExecuteW(NULL, L"open", L"explorer.exe", - L"::{7007ACC7-3202-11D1-AAD2-00805FC1270E}", - NULL, SW_SHOWDEFAULT)) - hr = E_FAIL; - } - else if (_ILIsBitBucket(pidlChild)) - { - /* FIXME: detect the drive path of bitbucket if appropiate */ - if (!SH_ShowRecycleBinProperties(L'C')) - hr = E_FAIL; - } - else - { - if (m_cidl > 1) - WARN("SHMultiFileProperties is not yet implemented\n"); - - STRRET strFile; - hr = m_psf->GetDisplayNameOf(pidlChild, SHGDN_FORPARSING, &strFile); - if (SUCCEEDED(hr)) - { - WCHAR wszBuf[MAX_PATH]; - hr = StrRetToBufW(&strFile, pidlChild, wszBuf, _countof(wszBuf)); - if (SUCCEEDED(hr)) - hr = SH_ShowPropertiesDialog(wszBuf, pidlParent, &pidlChild); - else - ERR("StrRetToBufW failed\n"); - } - else - ERR("IShellFolder_GetDisplayNameOf failed for apidl\n"); - } - - /* Free allocated PIDLs */ - if (pidlParent != m_pidlFolder) - ILFree((ITEMIDLIST*)pidlParent); - if (m_cidl < 1 || pidlChild != m_apidl[0]) - ILFree((ITEMIDLIST*)pidlChild); - - return hr; -} - -HRESULT -CDefaultContextMenu::DoFormat( - LPCMINVOKECOMMANDINFO lpcmi) -{ - char szDrive[8] = {0}; - - if (!_ILGetDrive(m_apidl[0], szDrive, sizeof(szDrive))) - { - ERR("pidl is not a drive\n"); - return E_FAIL; - } - - SHFormatDrive(lpcmi->hwnd, szDrive[0] - 'A', SHFMT_ID_DEFAULT, 0); + _DoCallback(DFM_INVOKECOMMAND, DFM_CMD_PROPERTIES, NULL); + return S_OK; }
@@ -1411,13 +1326,13 @@ case FCIDM_SHVIEW_PROPERTIES: Result = DoProperties(&LocalInvokeInfo); break; - case 0x7ABC: - Result = DoFormat(&LocalInvokeInfo); - break; case FCIDM_SHVIEW_NEWFOLDER: Result = DoCreateNewFolder(&LocalInvokeInfo); break; default: + + _DoCallback(DFM_INVOKECOMMAND, LOWORD(LocalInvokeInfo.lpVerb), NULL); + Result = E_UNEXPECTED; break; } @@ -1561,9 +1476,9 @@
static HRESULT -CDefaultContextMenu_CreateInstance(const DEFCONTEXTMENU *pdcm, REFIID riid, void **ppv) -{ - return ShellObjectCreatorInit<CDefaultContextMenu>(pdcm, riid, ppv); +CDefaultContextMenu_CreateInstance(const DEFCONTEXTMENU *pdcm, LPFNDFMCALLBACK lpfn, REFIID riid, void **ppv) +{ + return ShellObjectCreatorInit<CDefaultContextMenu>(pdcm, lpfn, riid, ppv); }
/************************************************************************* @@ -1575,7 +1490,7 @@ WINAPI SHCreateDefaultContextMenu(const DEFCONTEXTMENU *pdcm, REFIID riid, void **ppv) { - HRESULT hr = CDefaultContextMenu_CreateInstance(pdcm, riid, ppv); + HRESULT hr = CDefaultContextMenu_CreateInstance(pdcm, NULL, riid, ppv); if (FAILED_UNEXPECTEDLY(hr)) return hr;
@@ -1600,20 +1515,20 @@ const HKEY *ahkeyClsKeys, IContextMenu **ppcm) { - DEFCONTEXTMENU pdcm; - pdcm.hwnd = hwnd; - pdcm.pcmcb = NULL; - pdcm.pidlFolder = pidlFolder; - pdcm.psf = psf; - pdcm.cidl = cidl; - pdcm.apidl = apidl; - pdcm.punkAssociationInfo = NULL; - pdcm.cKeys = nKeys; - pdcm.aKeys = ahkeyClsKeys; - - HRESULT hr = SHCreateDefaultContextMenu(&pdcm, IID_PPV_ARG(IContextMenu, ppcm)); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - return S_OK; -} + DEFCONTEXTMENU dcm; + dcm.hwnd = hwnd; + dcm.pcmcb = NULL; + dcm.pidlFolder = pidlFolder; + dcm.psf = psf; + dcm.cidl = cidl; + dcm.apidl = apidl; + dcm.punkAssociationInfo = NULL; + dcm.cKeys = nKeys; + dcm.aKeys = ahkeyClsKeys; + + HRESULT hr = CDefaultContextMenu_CreateInstance(&dcm, lpfn, IID_PPV_ARG(IContextMenu, ppcm)); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + return S_OK; +}
Modified: trunk/reactos/dll/win32/shell32/dialogs/drive.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/dialogs/d... ============================================================================== --- trunk/reactos/dll/win32/shell32/dialogs/drive.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/dialogs/drive.cpp [iso-8859-1] Thu Nov 17 14:35:19 2016 @@ -123,7 +123,7 @@ } DRIVE_PROP_PAGE;
BOOL -SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl) +SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl) { HPSXA hpsx = NULL; HPROPSHEETPAGE hpsp[MAX_PROPERTY_SHEET_PAGE];
Modified: trunk/reactos/dll/win32/shell32/dialogs/fprop.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/dialogs/f... ============================================================================== --- trunk/reactos/dll/win32/shell32/dialogs/fprop.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/dialogs/fprop.cpp [iso-8859-1] Thu Nov 17 14:35:19 2016 @@ -95,7 +95,7 @@ */
BOOL -SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl) +SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl) { HPSXA hpsxa[3] = {NULL, NULL, NULL}; CComObject<CFileDefExt> *pFileDefExt = NULL;
Modified: trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/C... ============================================================================== --- trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp [iso-8859-1] Thu Nov 17 14:35:19 2016 @@ -133,8 +133,8 @@
CComPtr<IDefaultExtractIconInit> initIcon; HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon)); - if (FAILED(hr)) - return NULL; + if (FAILED_UNEXPECTEDLY(hr)) + return hr;
initIcon->SetNormalIcon(pData->szName, (int)pData->iconIdx != -1 ? pData->iconIdx : 0);
Modified: trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/C... ============================================================================== --- trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp [iso-8859-1] Thu Nov 17 14:35:19 2016 @@ -39,6 +39,69 @@ * IShellFolder implementation */
+HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf, + HWND hwnd, + IDataObject *pdtobj, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND) + return S_OK; + + PIDLIST_ABSOLUTE pidlFolder; + PUITEMID_CHILD *apidl; + UINT cidl; + HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + char szDrive[8] = {0}; + if (!_ILGetDrive(apidl[0], szDrive, sizeof(szDrive))) + { + ERR("pidl is not a drive\n"); + SHFree(pidlFolder); + _ILFreeaPidl(apidl, cidl); + return E_FAIL; + } + + if (uMsg == DFM_MERGECONTEXTMENU) + { + QCMINFO *pqcminfo = (QCMINFO *)lParam; + DWORD dwFlags; + + if (GetVolumeInformationA(szDrive, NULL, 0, NULL, NULL, &dwFlags, NULL, 0)) + { + /* Disable format if read only */ + if (!(dwFlags & FILE_READ_ONLY_VOLUME) && GetDriveTypeA(szDrive) != DRIVE_REMOTE) + { + _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); + _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0x7ABC, MFT_STRING, MAKEINTRESOURCEW(IDS_FORMATDRIVE), MFS_ENABLED); + } + } + } + else if (uMsg == DFM_INVOKECOMMAND) + { + if(wParam == 0x7ABC) + { + SHFormatDrive(hwnd, szDrive[0] - 'A', SHFMT_ID_DEFAULT, 0); + } + else if (wParam == DFM_CMD_PROPERTIES) + { + WCHAR wszBuf[4]; + wcscpy(wszBuf, L"A:\"); + wszBuf[0] = (WCHAR)szDrive[0]; + if (!SH_ShowDriveProperties(wszBuf, pidlFolder, apidl)) + hr = E_FAIL; + } + } + + SHFree(pidlFolder); + _ILFreeaPidl(apidl, cidl); + + return hr; +} + HRESULT CDrivesContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder, HWND hwnd, UINT cidl, @@ -51,16 +114,15 @@ AddClassKeyToArray(L"Drive", hKeys, &cKeys); AddClassKeyToArray(L"Folder", hKeys, &cKeys);
- /* TODO: also pass a callback here */ - return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, NULL, cKeys, hKeys, ppcm); + return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, DrivesContextMenuCallback, cKeys, hKeys, ppcm); }
HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut) { CComPtr<IDefaultExtractIconInit> initIcon; HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon)); - if (FAILED(hr)) - return NULL; + if (FAILED_UNEXPECTEDLY(hr)) + return hr;
CHAR* pszDrive = _ILGetDataPointer(pidl)->u.drive.szDriveName; WCHAR wTemp[MAX_PATH];
Modified: trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/C... ============================================================================== --- trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp [iso-8859-1] Thu Nov 17 14:35:19 2016 @@ -489,12 +489,21 @@
if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1)) { - IContextMenu * pCm = NULL; HKEY hKeys[16]; UINT cKeys = 0; AddFSClassKeysToArray(apidl[0], hKeys, &cKeys); - hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), NULL, cKeys, hKeys, &pCm); - pObj = pCm; + + DEFCONTEXTMENU dcm; + dcm.hwnd = hwndOwner; + dcm.pcmcb = this; + dcm.pidlFolder = pidlRoot; + dcm.psf = this; + dcm.cidl = cidl; + dcm.apidl = apidl; + dcm.cKeys = cKeys; + dcm.aKeys = hKeys; + dcm.punkAssociationInfo = NULL; + hr = SHCreateDefaultContextMenu (&dcm, riid, &pObj); } else if (IsEqualIID (riid, IID_IDataObject)) { @@ -1088,4 +1097,38 @@ return hr; } return hr; -} +} + +HRESULT WINAPI CFSFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES) + return S_OK; + + PIDLIST_ABSOLUTE pidlFolder; + PUITEMID_CHILD *apidl; + UINT cidl; + HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + if (cidl > 1) + ERR("SHMultiFileProperties is not yet implemented\n"); + + STRRET strFile; + hr = GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strFile); + if (SUCCEEDED(hr)) + { + hr = SH_ShowPropertiesDialog(strFile.pOleStr, pidlFolder, apidl); + if (FAILED(hr)) + ERR("SH_ShowPropertiesDialog failed\n"); + } + else + { + ERR("Failed to get display name\n"); + } + + SHFree(pidlFolder); + _ILFreeaPidl(apidl, cidl); + + return hr; +}
Modified: trunk/reactos/dll/win32/shell32/folders/CFSFolder.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/C... ============================================================================== --- trunk/reactos/dll/win32/shell32/folders/CFSFolder.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/CFSFolder.h [iso-8859-1] Thu Nov 17 14:35:19 2016 @@ -27,7 +27,8 @@ public CComCoClass<CFSFolder, &CLSID_ShellFSFolder>, public CComObjectRootEx<CComMultiThreadModelNoCS>, public IShellFolder2, - public IPersistFolder3 + public IPersistFolder3, + public IContextMenuCB { private: CLSID *pclsid; @@ -80,6 +81,9 @@ virtual HRESULT WINAPI InitializeEx(IBindCtx *pbc, LPCITEMIDLIST pidlRoot, const PERSIST_FOLDER_TARGET_INFO *ppfti); virtual HRESULT WINAPI GetFolderTargetInfo(PERSIST_FOLDER_TARGET_INFO *ppfti);
+ // IContextMenuCB + virtual HRESULT WINAPI CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam); + DECLARE_REGISTRY_RESOURCEID(IDR_SHELLFSFOLDER) DECLARE_NOT_AGGREGATABLE(CFSFolder)
Modified: trunk/reactos/dll/win32/shell32/folders/CNetFolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/C... ============================================================================== --- trunk/reactos/dll/win32/shell32/folders/CNetFolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/CNetFolder.cpp [iso-8859-1] Thu Nov 17 14:35:19 2016 @@ -53,8 +53,8 @@ { CComPtr<IDefaultExtractIconInit> initIcon; HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon)); - if (FAILED(hr)) - return NULL; + if (FAILED_UNEXPECTEDLY(hr)) + return hr;
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_NETWORK_FOLDER);
Modified: trunk/reactos/dll/win32/shell32/folders/CRecycleBin.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/C... ============================================================================== --- trunk/reactos/dll/win32/shell32/folders/CRecycleBin.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/CRecycleBin.cpp [iso-8859-1] Thu Nov 17 14:35:19 2016 @@ -67,8 +67,8 @@ { CComPtr<IDefaultExtractIconInit> initIcon; HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon)); - if (FAILED(hr)) - return NULL; + if (FAILED_UNEXPECTEDLY(hr)) + return hr;
/* FIXME: This is completely unimplemented */ initIcon->SetNormalIcon(swShell32Name, 0);
Modified: trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/C... ============================================================================== --- trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp [iso-8859-1] Thu Nov 17 14:35:19 2016 @@ -22,6 +22,54 @@
WINE_DEFAULT_DEBUG_CHANNEL (shell);
+HRESULT CALLBACK RegFolderContextMenuCallback(IShellFolder *psf, + HWND hwnd, + IDataObject *pdtobj, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES) + return S_OK; + + PIDLIST_ABSOLUTE pidlFolder; + PUITEMID_CHILD *apidl; + UINT cidl; + HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + if (_ILIsMyComputer(apidl[0])) + { + if (32 >= (UINT)ShellExecuteW(hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl", NULL, NULL, SW_SHOWNORMAL)) + hr = E_FAIL; + } + else if (_ILIsDesktop(apidl[0])) + { + if (32 >= (UINT)ShellExecuteW(hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL, NULL, SW_SHOWNORMAL)) + hr = E_FAIL; + } + else if (_ILIsNetHood(apidl[0])) + { + // FIXME path! + if (32 >= (UINT)ShellExecuteW(NULL, L"open", L"explorer.exe", + L"::{7007ACC7-3202-11D1-AAD2-00805FC1270E}", + NULL, SW_SHOWDEFAULT)) + hr = E_FAIL; + } + else if (_ILIsBitBucket(apidl[0])) + { + /* FIXME: detect the drive path of bitbucket if appropiate */ + if (!SH_ShowRecycleBinProperties(L'C')) + hr = E_FAIL; + } + + SHFree(pidlFolder); + _ILFreeaPidl(apidl, cidl); + + return hr; +} + HRESULT CGuidItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder, HWND hwnd, UINT cidl, @@ -48,7 +96,7 @@ } AddClassKeyToArray(L"Folder", hKeys, &cKeys);
- return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, NULL, cKeys, hKeys, ppcm); + return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, RegFolderContextMenuCallback, cKeys, hKeys, ppcm); }
HRESULT CGuidItemExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut) @@ -397,6 +445,10 @@ }
hr = CGuidItemContextMenu_CreateInstance(m_pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), (IContextMenu**)&pObj); + } + else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1)) + { + hr = IDataObject_Constructor (hwndOwner, m_pidlRoot, apidl, cidl, (IDataObject **)&pObj); } else {
Modified: trunk/reactos/dll/win32/shell32/shfldr.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shfldr.h?... ============================================================================== --- trunk/reactos/dll/win32/shell32/shfldr.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/shfldr.h [iso-8859-1] Thu Nov 17 14:35:19 2016 @@ -63,6 +63,8 @@
void AddFSClassKeysToArray(PCUITEMID_CHILD pidl, HKEY* array, UINT* cKeys);
+HRESULT SH_GetApidlFromDataObject(IDataObject *pDataObject, PIDLIST_ABSOLUTE* ppidlfolder, PUITEMID_CHILD **apidlItems, UINT *pcidl); + static __inline int SHELL32_GUIDToStringA (REFGUID guid, LPSTR str) { return sprintf(str, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
Modified: trunk/reactos/dll/win32/shell32/shlfolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shlfolder... ============================================================================== --- trunk/reactos/dll/win32/shell32/shlfolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/shlfolder.cpp [iso-8859-1] Thu Nov 17 14:35:19 2016 @@ -547,6 +547,49 @@ } }
+HRESULT SH_GetApidlFromDataObject(IDataObject *pDataObject, PIDLIST_ABSOLUTE* ppidlfolder, PUITEMID_CHILD **apidlItems, UINT *pcidl) +{ + UINT cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST); + if (!cfShellIDList) + return E_FAIL; + + FORMATETC fmt; + InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL); + + HRESULT hr = pDataObject->QueryGetData(&fmt); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + STGMEDIUM medium; + hr = pDataObject->GetData(&fmt, &medium); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + /* lock the handle */ + LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal); + if (!lpcida) + { + ReleaseStgMedium(&medium); + return E_FAIL; + } + + /* convert the data into pidl */ + LPITEMIDLIST pidl; + LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida); + if (!apidl) + { + ReleaseStgMedium(&medium); + return E_OUTOFMEMORY; + } + + *ppidlfolder = pidl; + *apidlItems = apidl; + *pcidl = lpcida->cidl; + + ReleaseStgMedium(&medium); + return S_OK; +} + /*********************************************************************** * SHCreateLinks *
Modified: trunk/reactos/dll/win32/shell32/wine/shell32_main.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/wine/shel... ============================================================================== --- trunk/reactos/dll/win32/shell32/wine/shell32_main.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/wine/shell32_main.h [iso-8859-1] Thu Nov 17 14:35:19 2016 @@ -189,10 +189,9 @@ INT_PTR CALLBACK SH_FileGeneralDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK SH_FileVersionDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); HPROPSHEETPAGE SH_CreatePropertySheetPage(WORD wDialogId, DLGPROC pfnDlgProc, LPARAM lParam, LPCWSTR pwszTitle); -BOOL SH_ShowDriveProperties(WCHAR *drive, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl); +BOOL SH_ShowDriveProperties(WCHAR *drive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl); BOOL SH_ShowRecycleBinProperties(WCHAR sDrive); -BOOL SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl); -BOOL SH_ShowFolderProperties(LPWSTR pwszFolder, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl); +BOOL SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl); LPWSTR SH_FormatFileSizeWithBytes(PULARGE_INTEGER lpQwSize, LPWSTR pszBuf, UINT cchBuf);
HRESULT WINAPI DoRegisterServer(void);