https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6a1f287820e6ada7d957a6...
commit 6a1f287820e6ada7d957a6451a7ecc54f73c1876 Author: Mark Jansen mark.jansen@reactos.org AuthorDate: Thu Sep 22 19:27:33 2022 +0200 Commit: Mark Jansen mark.jansen@reactos.org CommitDate: Fri Oct 14 21:02:33 2022 +0200
[SHELL32] Show file / drive properties at the position where the mouse was.
CORE-18386 --- dll/win32/shell32/CDefView.cpp | 36 +++++++------ dll/win32/shell32/CDefaultContextMenu.cpp | 76 ++++++++++++++------------- dll/win32/shell32/dialogs/drive.cpp | 79 +++++++++++++++-------------- dll/win32/shell32/dialogs/fprop.cpp | 61 +++++++++++++--------- dll/win32/shell32/folders/CDrivesFolder.cpp | 4 +- dll/win32/shell32/folders/CFSFolder.cpp | 24 ++++++--- dll/win32/shell32/shlfolder.cpp | 27 +++------- dll/win32/shell32/wine/shell32_main.h | 4 +- sdk/include/reactos/shellutils.h | 26 ++++++++++ 9 files changed, 196 insertions(+), 141 deletions(-)
diff --git a/dll/win32/shell32/CDefView.cpp b/dll/win32/shell32/CDefView.cpp index 0bff83e1c9f..fbee323ee7d 100644 --- a/dll/win32/shell32/CDefView.cpp +++ b/dll/win32/shell32/CDefView.cpp @@ -197,7 +197,7 @@ class CDefView : void OnDeactivate(); void DoActivate(UINT uState); HRESULT drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); - HRESULT InvokeContextMenuCommand(CComPtr<IContextMenu> &pCM, UINT uCommand); + HRESULT InvokeContextMenuCommand(CComPtr<IContextMenu> &pCM, UINT uCommand, POINT* pt); LRESULT OnExplorerCommand(UINT uCommand, BOOL bUseSelection);
// *** IOleWindow methods *** @@ -1496,9 +1496,9 @@ UINT CDefView::GetSelections() return m_cidl; }
-HRESULT CDefView::InvokeContextMenuCommand(CComPtr<IContextMenu> &pCM, UINT uCommand) +HRESULT CDefView::InvokeContextMenuCommand(CComPtr<IContextMenu> &pCM, UINT uCommand, POINT* pt) { - CMINVOKECOMMANDINFO cmi; + CMINVOKECOMMANDINFOEX cmi;
ZeroMemory(&cmi, sizeof(cmi)); cmi.cbSize = sizeof(cmi); @@ -1511,7 +1511,13 @@ HRESULT CDefView::InvokeContextMenuCommand(CComPtr<IContextMenu> &pCM, UINT uCom if (GetKeyState(VK_CONTROL) & 0x8000) cmi.fMask |= CMIC_MASK_CONTROL_DOWN;
- HRESULT hr = pCM->InvokeCommand(&cmi); + if (pt) + { + cmi.fMask |= CMIC_MASK_PTINVOKE; + cmi.ptInvoke = *pt; + } + + HRESULT hr = m_pCM->InvokeCommand((LPCMINVOKECOMMANDINFO)&cmi); // Most of our callers will do this, but in case they don't do that (File menu!) IUnknown_SetSite(pCM, NULL); pCM.Release(); @@ -1560,7 +1566,7 @@ HRESULT CDefView::OpenSelectedItems() return E_FAIL; }
- InvokeContextMenuCommand(pCM, uCommand); + InvokeContextMenuCommand(pCM, uCommand, NULL);
return hResult; } @@ -1570,7 +1576,7 @@ HRESULT CDefView::OpenSelectedItems() */ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { - int x, y; + POINT pt; UINT uCommand; HRESULT hResult;
@@ -1588,10 +1594,10 @@ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b
if (lParam != ~0) // unless app key (menu key) was pressed { - x = GET_X_LPARAM(lParam); - y = GET_Y_LPARAM(lParam); + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam);
- LV_HITTESTINFO hittest = { { x, y } }; + LV_HITTESTINFO hittest = { pt }; ScreenToClient(&hittest.pt); m_ListView.HitTest(&hittest);
@@ -1621,7 +1627,6 @@ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b { HWND hFocus = ::GetFocus(); int lvIndex = -1; - POINT pt;
if (hFocus == m_ListView.m_hWnd || m_ListView.IsChild(hFocus)) { @@ -1648,21 +1653,19 @@ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b }
m_ListView.ClientToScreen(&pt); - x = pt.x; - y = pt.y; }
// This runs the message loop, calling back to us with f.e. WM_INITPOPUP (hence why m_hContextMenu and m_pCM exist) uCommand = TrackPopupMenu(m_hContextMenu, TPM_LEFTALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, - x, y, 0, m_hWnd, NULL); + pt.x, pt.y, 0, m_hWnd, NULL); if (uCommand == 0) return 0;
if (uCommand == FCIDM_SHVIEW_OPEN && OnDefaultCommand() == S_OK) return 0;
- InvokeContextMenuCommand(m_pCM, uCommand - CONTEXT_MENU_BASE_ID); + InvokeContextMenuCommand(m_pCM, uCommand - CONTEXT_MENU_BASE_ID, &pt);
return 0; } @@ -1710,7 +1713,8 @@ LRESULT CDefView::OnExplorerCommand(UINT uCommand, BOOL bUseSelection) return 0; }
- InvokeContextMenuCommand(pCM, uCommand); + // FIXME: We should probably use the objects position? + InvokeContextMenuCommand(pCM, uCommand, NULL); return 0; }
@@ -1950,7 +1954,7 @@ LRESULT CDefView::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHand { HMENU Dummy = NULL; MenuCleanup _(m_pFileMenu, Dummy); - InvokeContextMenuCommand(m_pFileMenu, dwCmdID); + InvokeContextMenuCommand(m_pFileMenu, dwCmdID, NULL); } }
diff --git a/dll/win32/shell32/CDefaultContextMenu.cpp b/dll/win32/shell32/CDefaultContextMenu.cpp index 6bddfafcb35..55aa8022af6 100644 --- a/dll/win32/shell32/CDefaultContextMenu.cpp +++ b/dll/win32/shell32/CDefaultContextMenu.cpp @@ -86,21 +86,21 @@ class CDefaultContextMenu : BOOL EnumerateDynamicContextHandlerForKey(HKEY hRootKey); UINT AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UINT idCmdFirst, UINT idCmdLast); UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT* IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast); - HRESULT DoPaste(LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink); - HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFO lpcmi); - HRESULT DoCreateLink(LPCMINVOKECOMMANDINFO lpcmi); - HRESULT DoDelete(LPCMINVOKECOMMANDINFO lpcmi); - HRESULT DoCopyOrCut(LPCMINVOKECOMMANDINFO lpcmi, BOOL bCopy); - HRESULT DoRename(LPCMINVOKECOMMANDINFO lpcmi); - HRESULT DoProperties(LPCMINVOKECOMMANDINFO lpcmi); - HRESULT DoUndo(LPCMINVOKECOMMANDINFO lpcmi); - HRESULT DoCreateNewFolder(LPCMINVOKECOMMANDINFO lpici); - HRESULT DoCopyToMoveToFolder(LPCMINVOKECOMMANDINFO lpici, BOOL bCopy); - HRESULT InvokeShellExt(LPCMINVOKECOMMANDINFO lpcmi); - HRESULT InvokeRegVerb(LPCMINVOKECOMMANDINFO lpcmi); - DWORD BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFO lpcmi, PStaticShellEntry pEntry); - HRESULT TryToBrowse(LPCMINVOKECOMMANDINFO lpcmi, LPCITEMIDLIST pidl, DWORD wFlags); - HRESULT InvokePidl(LPCMINVOKECOMMANDINFO lpcmi, LPCITEMIDLIST pidl, PStaticShellEntry pEntry); + HRESULT DoPaste(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bLink); + HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFOEX lpcmi); + HRESULT DoCreateLink(LPCMINVOKECOMMANDINFOEX lpcmi); + HRESULT DoDelete(LPCMINVOKECOMMANDINFOEX lpcmi); + HRESULT DoCopyOrCut(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bCopy); + HRESULT DoRename(LPCMINVOKECOMMANDINFOEX lpcmi); + HRESULT DoProperties(LPCMINVOKECOMMANDINFOEX lpcmi); + HRESULT DoUndo(LPCMINVOKECOMMANDINFOEX lpcmi); + HRESULT DoCreateNewFolder(LPCMINVOKECOMMANDINFOEX lpici); + HRESULT DoCopyToMoveToFolder(LPCMINVOKECOMMANDINFOEX lpici, BOOL bCopy); + HRESULT InvokeShellExt(LPCMINVOKECOMMANDINFOEX lpcmi); + HRESULT InvokeRegVerb(LPCMINVOKECOMMANDINFOEX lpcmi); + DWORD BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFOEX lpcmi, PStaticShellEntry pEntry); + HRESULT TryToBrowse(LPCMINVOKECOMMANDINFOEX lpcmi, LPCITEMIDLIST pidl, DWORD wFlags); + HRESULT InvokePidl(LPCMINVOKECOMMANDINFOEX lpcmi, LPCITEMIDLIST pidl, PStaticShellEntry pEntry); PDynamicShellEntry GetDynamicEntry(UINT idCmd); BOOL MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode);
@@ -695,7 +695,7 @@ CDefaultContextMenu::QueryContextMenu( return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds); }
-HRESULT CDefaultContextMenu::DoPaste(LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink) +HRESULT CDefaultContextMenu::DoPaste(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bLink) { HRESULT hr;
@@ -748,13 +748,13 @@ HRESULT CDefaultContextMenu::DoPaste(LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink) }
HRESULT -CDefaultContextMenu::DoOpenOrExplore(LPCMINVOKECOMMANDINFO lpcmi) +CDefaultContextMenu::DoOpenOrExplore(LPCMINVOKECOMMANDINFOEX lpcmi) { UNIMPLEMENTED; return E_FAIL; }
-HRESULT CDefaultContextMenu::DoCreateLink(LPCMINVOKECOMMANDINFO lpcmi) +HRESULT CDefaultContextMenu::DoCreateLink(LPCMINVOKECOMMANDINFOEX lpcmi) { if (!m_cidl || !m_pDataObj) return E_FAIL; @@ -769,7 +769,7 @@ HRESULT CDefaultContextMenu::DoCreateLink(LPCMINVOKECOMMANDINFO lpcmi) return S_OK; }
-HRESULT CDefaultContextMenu::DoDelete(LPCMINVOKECOMMANDINFO lpcmi) +HRESULT CDefaultContextMenu::DoDelete(LPCMINVOKECOMMANDINFOEX lpcmi) { if (!m_cidl || !m_pDataObj) return E_FAIL; @@ -785,7 +785,7 @@ HRESULT CDefaultContextMenu::DoDelete(LPCMINVOKECOMMANDINFO lpcmi) return S_OK; }
-HRESULT CDefaultContextMenu::DoCopyOrCut(LPCMINVOKECOMMANDINFO lpcmi, BOOL bCopy) +HRESULT CDefaultContextMenu::DoCopyOrCut(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bCopy) { if (!m_cidl || !m_pDataObj) return E_FAIL; @@ -808,7 +808,7 @@ HRESULT CDefaultContextMenu::DoCopyOrCut(LPCMINVOKECOMMANDINFO lpcmi, BOOL bCopy return S_OK; }
-HRESULT CDefaultContextMenu::DoRename(LPCMINVOKECOMMANDINFO lpcmi) +HRESULT CDefaultContextMenu::DoRename(LPCMINVOKECOMMANDINFOEX lpcmi) { CComPtr<IShellBrowser> psb; HRESULT hr; @@ -836,7 +836,7 @@ HRESULT CDefaultContextMenu::DoRename(LPCMINVOKECOMMANDINFO lpcmi)
HRESULT CDefaultContextMenu::DoProperties( - LPCMINVOKECOMMANDINFO lpcmi) + LPCMINVOKECOMMANDINFOEX lpcmi) { HRESULT hr = _DoCallback(DFM_INVOKECOMMAND, DFM_CMD_PROPERTIES, NULL);
@@ -850,14 +850,14 @@ CDefaultContextMenu::DoProperties( }
HRESULT -CDefaultContextMenu::DoUndo(LPCMINVOKECOMMANDINFO lpcmi) +CDefaultContextMenu::DoUndo(LPCMINVOKECOMMANDINFOEX lpcmi) { ERR("TODO: Undo\n"); return E_NOTIMPL; }
HRESULT -CDefaultContextMenu::DoCopyToMoveToFolder(LPCMINVOKECOMMANDINFO lpici, BOOL bCopy) +CDefaultContextMenu::DoCopyToMoveToFolder(LPCMINVOKECOMMANDINFOEX lpici, BOOL bCopy) { HRESULT hr = E_FAIL; if (!m_pDataObj) @@ -890,13 +890,13 @@ CDefaultContextMenu::DoCopyToMoveToFolder(LPCMINVOKECOMMANDINFO lpici, BOOL bCop else lpici->lpVerb = "moveto";
- return pContextMenu->InvokeCommand(lpici); + return pContextMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)lpici); }
// This code is taken from CNewMenu and should be shared between the 2 classes HRESULT CDefaultContextMenu::DoCreateNewFolder( - LPCMINVOKECOMMANDINFO lpici) + LPCMINVOKECOMMANDINFOEX lpici) { WCHAR wszPath[MAX_PATH]; WCHAR wszName[MAX_PATH]; @@ -1009,7 +1009,7 @@ CDefaultContextMenu::MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode)
HRESULT CDefaultContextMenu::InvokeShellExt( - LPCMINVOKECOMMANDINFO lpcmi) + LPCMINVOKECOMMANDINFOEX lpcmi) { TRACE("verb %p first %x last %x\n", lpcmi->lpVerb, m_iIdSHEFirst, m_iIdSHELast);
@@ -1020,11 +1020,11 @@ CDefaultContextMenu::InvokeShellExt(
/* invoke the dynamic context menu */ lpcmi->lpVerb = MAKEINTRESOURCEA(idCmd - pEntry->iIdCmdFirst); - return pEntry->pCM->InvokeCommand(lpcmi); + return pEntry->pCM->InvokeCommand((LPCMINVOKECOMMANDINFO)lpcmi); }
DWORD -CDefaultContextMenu::BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFO lpcmi, PStaticShellEntry pEntry) +CDefaultContextMenu::BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFOEX lpcmi, PStaticShellEntry pEntry) { CComPtr<IShellBrowser> psb; HWND hwndTree; @@ -1064,7 +1064,7 @@ CDefaultContextMenu::BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFO lpcmi, PStaticSh
HRESULT CDefaultContextMenu::TryToBrowse( - LPCMINVOKECOMMANDINFO lpcmi, LPCITEMIDLIST pidl, DWORD wFlags) + LPCMINVOKECOMMANDINFOEX lpcmi, LPCITEMIDLIST pidl, DWORD wFlags) { CComPtr<IShellBrowser> psb; HRESULT hr; @@ -1081,7 +1081,7 @@ CDefaultContextMenu::TryToBrowse( }
HRESULT -CDefaultContextMenu::InvokePidl(LPCMINVOKECOMMANDINFO lpcmi, LPCITEMIDLIST pidl, PStaticShellEntry pEntry) +CDefaultContextMenu::InvokePidl(LPCMINVOKECOMMANDINFOEX lpcmi, LPCITEMIDLIST pidl, PStaticShellEntry pEntry) { LPITEMIDLIST pidlFull = ILCombine(m_pidlFolder, pidl); if (pidlFull == NULL) @@ -1127,7 +1127,7 @@ CDefaultContextMenu::InvokePidl(LPCMINVOKECOMMANDINFO lpcmi, LPCITEMIDLIST pidl,
HRESULT CDefaultContextMenu::InvokeRegVerb( - LPCMINVOKECOMMANDINFO lpcmi) + LPCMINVOKECOMMANDINFOEX lpcmi) { INT iCmd = LOWORD(lpcmi->lpVerb); HRESULT hr; @@ -1174,13 +1174,13 @@ WINAPI CDefaultContextMenu::InvokeCommand( LPCMINVOKECOMMANDINFO lpcmi) { - CMINVOKECOMMANDINFO LocalInvokeInfo; + CMINVOKECOMMANDINFOEX LocalInvokeInfo = {}; HRESULT Result; UINT CmdId;
/* Take a local copy of the fixed members of the struct as we might need to modify the verb */ - LocalInvokeInfo = *lpcmi; + memcpy(&LocalInvokeInfo, lpcmi, min(sizeof(LocalInvokeInfo), lpcmi->cbSize));
/* Check if this is a string verb */ if (HIWORD(LocalInvokeInfo.lpVerb)) @@ -1219,6 +1219,14 @@ CDefaultContextMenu::InvokeCommand( CmdId += 0x7000; }
+ if (LocalInvokeInfo.cbSize >= sizeof(CMINVOKECOMMANDINFOEX) && (LocalInvokeInfo.fMask & CMIC_MASK_PTINVOKE)) + { + if (FAILED_UNEXPECTEDLY(DataObject_SetOffset(m_pDataObj, &LocalInvokeInfo.ptInvoke))) + { + ERR("Unable to add OFFSET to DataObject!\n"); + } + } + /* Check if this is a Id */ switch (CmdId) { diff --git a/dll/win32/shell32/dialogs/drive.cpp b/dll/win32/shell32/dialogs/drive.cpp index 8f2484e298a..1a09a6ed712 100644 --- a/dll/win32/shell32/dialogs/drive.cpp +++ b/dll/win32/shell32/dialogs/drive.cpp @@ -166,59 +166,62 @@ typedef struct _DRIVE_PROP_PAGE UINT DriveType; } DRIVE_PROP_PAGE;
-HRESULT -SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl) +BOOL +SH_ShowDriveProperties(WCHAR *pwszDrive, IDataObject *pDataObj) { HPSXA hpsx = NULL; HPROPSHEETPAGE hpsp[MAX_PROPERTY_SHEET_PAGE]; - PROPSHEETHEADERW psh; CComObject<CDrvDefExt> *pDrvDefExt = NULL; - WCHAR wszName[256];
- ZeroMemory(&psh, sizeof(PROPSHEETHEADERW)); - psh.dwSize = sizeof(PROPSHEETHEADERW); - psh.dwFlags = 0; // FIXME: make it modeless - psh.hwndParent = NULL; - psh.nStartPage = 0; - psh.phpage = hpsp; + CDataObjectHIDA cida(pDataObj); + if (FAILED_UNEXPECTEDLY(cida.hr())) + return cida.hr();
- LPITEMIDLIST completePidl = ILCombine(pidlFolder, apidl[0]); - if (!completePidl) - return E_OUTOFMEMORY; - - if (ILGetDisplayNameExW(NULL, completePidl, wszName, ILGDN_NORMAL)) + RECT rcPosition = {CW_USEDEFAULT, CW_USEDEFAULT, 0, 0}; + POINT pt; + if (SUCCEEDED(DataObject_GetOffset(pDataObj, &pt))) { - psh.pszCaption = wszName; - psh.dwFlags |= PSH_PROPTITLE; + rcPosition.left = pt.x; + rcPosition.top = pt.y; }
- ILFree(completePidl); + DWORD style = WS_DISABLED | WS_CLIPSIBLINGS | WS_CAPTION; + DWORD exstyle = WS_EX_WINDOWEDGE | WS_EX_APPWINDOW; + CStubWindow32 stub; + if (!stub.Create(NULL, rcPosition, NULL, style, exstyle)) + { + ERR("StubWindow32 creation failed\n"); + return FALSE; + }
- CComPtr<IDataObject> pDataObj; - HRESULT hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_PPV_ARG(IDataObject, &pDataObj)); + PROPSHEETHEADERW psh = {sizeof(PROPSHEETHEADERW)}; + psh.dwFlags = PSH_PROPTITLE; + psh.pszCaption = pwszDrive; + psh.hwndParent = stub; + psh.nStartPage = 0; + psh.phpage = hpsp;
+ HRESULT hr = CComObject<CDrvDefExt>::CreateInstance(&pDrvDefExt); if (SUCCEEDED(hr)) { - hr = CComObject<CDrvDefExt>::CreateInstance(&pDrvDefExt); + pDrvDefExt->AddRef(); // CreateInstance returns object with 0 ref count + hr = pDrvDefExt->Initialize(HIDA_GetPIDLFolder(cida), pDataObj, NULL); if (SUCCEEDED(hr)) { - pDrvDefExt->AddRef(); // CreateInstance returns object with 0 ref count - hr = pDrvDefExt->Initialize(pidlFolder, pDataObj, NULL); - if (SUCCEEDED(hr)) - { - hr = pDrvDefExt->AddPages(AddPropSheetPageCallback, (LPARAM)&psh); - if (FAILED(hr)) - ERR("AddPages failed\n"); - } else - ERR("Initialize failed\n"); + hr = pDrvDefExt->AddPages(AddPropSheetPageCallback, (LPARAM)&psh); + if (FAILED(hr)) + ERR("AddPages failed\n"); + } + else + { + ERR("Initialize failed\n"); } - - hpsx = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"Drive", MAX_PROPERTY_SHEET_PAGE, pDataObj); - if (hpsx) - SHAddFromPropSheetExtArray(hpsx, (LPFNADDPROPSHEETPAGE)AddPropSheetPageCallback, (LPARAM)&psh); }
- // NOTE: Currently property sheet is modal. If we make it modeless, then it returns HWND. + hpsx = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"Drive", MAX_PROPERTY_SHEET_PAGE, pDataObj); + if (hpsx) + SHAddFromPropSheetExtArray(hpsx, (LPFNADDPROPSHEETPAGE)AddPropSheetPageCallback, (LPARAM)&psh); + INT_PTR ret = PropertySheetW(&psh);
if (hpsx) @@ -226,9 +229,9 @@ SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHI if (pDrvDefExt) pDrvDefExt->Release();
- if (ret >= 0) - return S_OK; - return E_FAIL; + stub.DestroyWindow(); + + return ret != -1; }
static VOID diff --git a/dll/win32/shell32/dialogs/fprop.cpp b/dll/win32/shell32/dialogs/fprop.cpp index b43ee566e85..68872bc4c69 100644 --- a/dll/win32/shell32/dialogs/fprop.cpp +++ b/dll/win32/shell32/dialogs/fprop.cpp @@ -80,7 +80,7 @@ LoadPropSheetHandlers(LPCWSTR pwszPath, PROPSHEETHEADERW *pHeader, UINT cMaxPage */
BOOL -SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl) +SH_ShowPropertiesDialog(LPCWSTR pwszPath, IDataObject *pDataObj) { HPSXA hpsxa[3] = {NULL, NULL, NULL}; CComObject<CFileDefExt> *pFileDefExt = NULL; @@ -100,14 +100,33 @@ SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, PCUITEMID_CH /* remove trailing \ at the end of path */ PathRemoveBackslashW(wszPath);
+ CDataObjectHIDA cida(pDataObj); + if (FAILED_UNEXPECTEDLY(cida.hr())) + return FALSE; + + if (cida->cidl == 0) + { + ERR("Empty HIDA\n"); + return FALSE; + } + /* Handle drives */ - if (PathIsRootW(wszPath)) - return SUCCEEDED(SH_ShowDriveProperties(wszPath, pidlFolder, apidl)); + if (_ILIsDrive(HIDA_GetPIDLItem(cida, 0))) + return SH_ShowDriveProperties(wszPath, pDataObj); + + + RECT rcPosition = {CW_USEDEFAULT, CW_USEDEFAULT, 0, 0}; + POINT pt; + if (SUCCEEDED(DataObject_GetOffset(pDataObj, &pt))) + { + rcPosition.left = pt.x; + rcPosition.top = pt.y; + }
DWORD style = WS_DISABLED | WS_CLIPSIBLINGS | WS_CAPTION; DWORD exstyle = WS_EX_WINDOWEDGE | WS_EX_APPWINDOW; CStubWindow32 stub; - if (!stub.Create(NULL, NULL, NULL, style, exstyle)) + if (!stub.Create(NULL, rcPosition, NULL, style, exstyle)) { ERR("StubWindow32 creation failed\n"); return FALSE; @@ -122,35 +141,29 @@ SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, PCUITEMID_CH Header.phpage = hppages; Header.pszCaption = PathFindFileNameW(wszPath);
- CComPtr<IDataObject> pDataObj; - HRESULT hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_PPV_ARG(IDataObject, &pDataObj)); - + HRESULT hr = CComObject<CFileDefExt>::CreateInstance(&pFileDefExt); if (SUCCEEDED(hr)) { - hr = CComObject<CFileDefExt>::CreateInstance(&pFileDefExt); - if (SUCCEEDED(hr)) + pFileDefExt->AddRef(); // CreateInstance returns object with 0 ref count + hr = pFileDefExt->Initialize(HIDA_GetPIDLFolder(cida), pDataObj, NULL); + if (!FAILED_UNEXPECTEDLY(hr)) { - pFileDefExt->AddRef(); // CreateInstance returns object with 0 ref count - hr = pFileDefExt->Initialize(pidlFolder, pDataObj, NULL); - if (!FAILED_UNEXPECTEDLY(hr)) - { - hr = pFileDefExt->AddPages(AddPropSheetPageCallback, (LPARAM)&Header); - if (FAILED_UNEXPECTEDLY(hr)) - { - ERR("AddPages failed\n"); - return FALSE; - } - } - else + hr = pFileDefExt->AddPages(AddPropSheetPageCallback, (LPARAM)&Header); + if (FAILED_UNEXPECTEDLY(hr)) { - ERR("Initialize failed\n"); + ERR("AddPages failed\n"); return FALSE; } } - - LoadPropSheetHandlers(wszPath, &Header, MAX_PROPERTY_SHEET_PAGE - 1, hpsxa, pDataObj); + else + { + ERR("Initialize failed\n"); + return FALSE; + } }
+ LoadPropSheetHandlers(wszPath, &Header, MAX_PROPERTY_SHEET_PAGE - 1, hpsxa, pDataObj); + INT_PTR Result = PropertySheetW(&Header);
for (UINT i = 0; i < 3; ++i) diff --git a/dll/win32/shell32/folders/CDrivesFolder.cpp b/dll/win32/shell32/folders/CDrivesFolder.cpp index b8ef36e2ea0..805bfee1ac0 100644 --- a/dll/win32/shell32/folders/CDrivesFolder.cpp +++ b/dll/win32/shell32/folders/CDrivesFolder.cpp @@ -329,7 +329,9 @@ HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf,
if (wParam == DFM_CMD_PROPERTIES) { - hr = SH_ShowDriveProperties(wszBuf, pidlFolder, apidl); + // pdtobj should be valid at this point! + ATLASSERT(pdtobj); + hr = SH_ShowDriveProperties(wszBuf, pdtobj); if (FAILED(hr)) { dwError = ERROR_CAN_NOT_COMPLETE; diff --git a/dll/win32/shell32/folders/CFSFolder.cpp b/dll/win32/shell32/folders/CFSFolder.cpp index cf8d0c99233..4b7d8b3990b 100644 --- a/dll/win32/shell32/folders/CFSFolder.cpp +++ b/dll/win32/shell32/folders/CFSFolder.cpp @@ -1811,14 +1811,24 @@ HRESULT WINAPI CFSFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObjec { if (uMsg == DFM_INVOKECOMMAND && wParam == 0) { - PUITEMID_CHILD pidlChild = ILClone(ILFindLastID(m_pidlRoot)); - LPITEMIDLIST pidlParent = ILClone(m_pidlRoot); + // Create an data object + CComHeapPtr<ITEMID_CHILD> pidlChild(ILClone(ILFindLastID(m_pidlRoot))); + CComHeapPtr<ITEMIDLIST> pidlParent(ILClone(m_pidlRoot)); ILRemoveLastID(pidlParent); - BOOL bSuccess = SH_ShowPropertiesDialog(m_sPathTarget, pidlParent, &pidlChild); - if (!bSuccess) - ERR("SH_ShowPropertiesDialog failed\n"); - ILFree(pidlChild); - ILFree(pidlParent); + + CComPtr<IDataObject> pDataObj; + HRESULT hr = SHCreateDataObject(pidlParent, 1, &pidlChild, NULL, IID_PPV_ARG(IDataObject, &pDataObj)); + if (!FAILED_UNEXPECTEDLY(hr)) + { + // Ask for a title to display + CComHeapPtr<WCHAR> wszName; + if (!FAILED_UNEXPECTEDLY(SHGetNameFromIDList(m_pidlRoot, SIGDN_PARENTRELATIVEPARSING, &wszName))) + { + BOOL bSuccess = SH_ShowPropertiesDialog(wszName, pDataObj); + if (!bSuccess) + ERR("SH_ShowPropertiesDialog failed\n"); + } + } } else if (uMsg == DFM_MERGECONTEXTMENU) { diff --git a/dll/win32/shell32/shlfolder.cpp b/dll/win32/shell32/shlfolder.cpp index 01018b44ede..315ad7d74c1 100644 --- a/dll/win32/shell32/shlfolder.cpp +++ b/dll/win32/shell32/shlfolder.cpp @@ -460,25 +460,14 @@ _ShowPropertiesDialogThread(LPVOID lpParameter) return E_FAIL; }
- PCUIDLIST_ABSOLUTE pidlFolder = HIDA_GetPIDLFolder(cida); - CComPtr<IShellFolder> psfParent; - HRESULT hr = _SHBindToFolder(pidlFolder, &psfParent); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - STRRET strFile; - PCUIDLIST_RELATIVE apidl = HIDA_GetPIDLItem(cida, 0); - hr = psfParent->GetDisplayNameOf(apidl, SHGDN_FORPARSING, &strFile); - if (!FAILED_UNEXPECTEDLY(hr)) - { - BOOL bSuccess = SH_ShowPropertiesDialog(strFile.pOleStr, pidlFolder, &apidl); - if (!bSuccess) - ERR("SH_ShowPropertiesDialog failed\n"); - } - else - { - ERR("Failed to get display name\n"); - } + CComHeapPtr<ITEMIDLIST> completePidl(ILCombine(HIDA_GetPIDLFolder(cida), HIDA_GetPIDLItem(cida, 0))); + CComHeapPtr<WCHAR> wszName; + if (FAILED_UNEXPECTEDLY(SHGetNameFromIDList(completePidl, SIGDN_PARENTRELATIVEPARSING, &wszName))) + return 0; + + BOOL bSuccess = SH_ShowPropertiesDialog(wszName, pDataObject); + if (!bSuccess) + ERR("SH_ShowPropertiesDialog failed\n");
return 0; } diff --git a/dll/win32/shell32/wine/shell32_main.h b/dll/win32/shell32/wine/shell32_main.h index 1585f60aedd..a9da0b2e10f 100644 --- a/dll/win32/shell32/wine/shell32_main.h +++ b/dll/win32/shell32/wine/shell32_main.h @@ -186,9 +186,9 @@ BOOL SHELL_IsShortcut(LPCITEMIDLIST) DECLSPEC_HIDDEN; 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); -HRESULT SH_ShowDriveProperties(WCHAR *drive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl); +BOOL SH_ShowDriveProperties(WCHAR *drive, IDataObject *pDataObj); BOOL SH_ShowRecycleBinProperties(WCHAR sDrive); -BOOL SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl); +BOOL SH_ShowPropertiesDialog(LPCWSTR pwszPath, IDataObject *pDataObj); LPWSTR SH_FormatFileSizeWithBytes(PULARGE_INTEGER lpQwSize, LPWSTR pszBuf, UINT cchBuf);
HRESULT WINAPI DoRegisterServer(void); diff --git a/sdk/include/reactos/shellutils.h b/sdk/include/reactos/shellutils.h index 7a3c7265059..f516d8c6830 100644 --- a/sdk/include/reactos/shellutils.h +++ b/sdk/include/reactos/shellutils.h @@ -560,6 +560,7 @@ static inline PCUIDLIST_RELATIVE HIDA_GetPIDLItem(CIDA const* pida, SIZE_T i) #ifdef __cplusplus
DECLSPEC_SELECTANY CLIPFORMAT g_cfHIDA = NULL; +DECLSPEC_SELECTANY CLIPFORMAT g_cfShellIdListOffsets = NULL;
// Allow to use the HIDA from an IDataObject without copying it struct CDataObjectHIDA @@ -684,6 +685,31 @@ HRESULT DataObject_SetData(IDataObject* pDataObject, CLIPFORMAT clipformat, PVOI return hr; }
+ +inline HRESULT +DataObject_GetOffset(IDataObject *pDataObject, POINT *point) +{ + if (g_cfShellIdListOffsets == NULL) + { + g_cfShellIdListOffsets = (CLIPFORMAT)RegisterClipboardFormatW(CFSTR_SHELLIDLISTOFFSETW); + } + + point->x = point->y = 0; + + return DataObject_GetData(pDataObject, g_cfShellIdListOffsets, point, sizeof(point[0])); +} + +inline HRESULT +DataObject_SetOffset(IDataObject* pDataObject, POINT* point) +{ + if (g_cfShellIdListOffsets == NULL) + { + g_cfShellIdListOffsets = (CLIPFORMAT)RegisterClipboardFormatW(CFSTR_SHELLIDLISTOFFSETW); + } + + return DataObject_SetData(pDataObject, g_cfShellIdListOffsets, point, sizeof(point[0])); +} + #endif