mirror of
https://github.com/reactos/reactos.git
synced 2024-09-27 21:16:34 +00:00
[SHELL32] Show file / drive properties at the position where the mouse was.
CORE-18386
This commit is contained in:
parent
26408144a1
commit
6a1f287820
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
CDataObjectHIDA cida(pDataObj);
|
||||
if (FAILED_UNEXPECTEDLY(cida.hr()))
|
||||
return cida.hr();
|
||||
|
||||
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, rcPosition, NULL, style, exstyle))
|
||||
{
|
||||
ERR("StubWindow32 creation failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PROPSHEETHEADERW psh = {sizeof(PROPSHEETHEADERW)};
|
||||
psh.dwFlags = PSH_PROPTITLE;
|
||||
psh.pszCaption = pwszDrive;
|
||||
psh.hwndParent = stub;
|
||||
psh.nStartPage = 0;
|
||||
psh.phpage = hpsp;
|
||||
|
||||
LPITEMIDLIST completePidl = ILCombine(pidlFolder, apidl[0]);
|
||||
if (!completePidl)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (ILGetDisplayNameExW(NULL, completePidl, wszName, ILGDN_NORMAL))
|
||||
{
|
||||
psh.pszCaption = wszName;
|
||||
psh.dwFlags |= PSH_PROPTITLE;
|
||||
}
|
||||
|
||||
ILFree(completePidl);
|
||||
|
||||
CComPtr<IDataObject> pDataObj;
|
||||
HRESULT hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_PPV_ARG(IDataObject, &pDataObj));
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = CComObject<CDrvDefExt>::CreateInstance(&pDrvDefExt);
|
||||
HRESULT hr = CComObject<CDrvDefExt>::CreateInstance(&pDrvDefExt);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
pDrvDefExt->AddRef(); // CreateInstance returns object with 0 ref count
|
||||
hr = pDrvDefExt->Initialize(pidlFolder, pDataObj, NULL);
|
||||
hr = pDrvDefExt->Initialize(HIDA_GetPIDLFolder(cida), pDataObj, NULL);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pDrvDefExt->AddPages(AddPropSheetPageCallback, (LPARAM)&psh);
|
||||
if (FAILED(hr))
|
||||
ERR("AddPages failed\n");
|
||||
} else
|
||||
}
|
||||
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.
|
||||
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
|
||||
|
|
|
@ -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,16 +141,11 @@ 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));
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = CComObject<CFileDefExt>::CreateInstance(&pFileDefExt);
|
||||
HRESULT hr = CComObject<CFileDefExt>::CreateInstance(&pFileDefExt);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
pFileDefExt->AddRef(); // CreateInstance returns object with 0 ref count
|
||||
hr = pFileDefExt->Initialize(pidlFolder, pDataObj, NULL);
|
||||
hr = pFileDefExt->Initialize(HIDA_GetPIDLFolder(cida), pDataObj, NULL);
|
||||
if (!FAILED_UNEXPECTEDLY(hr))
|
||||
{
|
||||
hr = pFileDefExt->AddPages(AddPropSheetPageCallback, (LPARAM)&Header);
|
||||
|
@ -149,7 +163,6 @@ SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, PCUITEMID_CH
|
|||
}
|
||||
|
||||
LoadPropSheetHandlers(wszPath, &Header, MAX_PROPERTY_SHEET_PAGE - 1, hpsxa, pDataObj);
|
||||
}
|
||||
|
||||
INT_PTR Result = PropertySheetW(&Header);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
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");
|
||||
ILFree(pidlChild);
|
||||
ILFree(pidlParent);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (uMsg == DFM_MERGECONTEXTMENU)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
CComHeapPtr<ITEMIDLIST> completePidl(ILCombine(HIDA_GetPIDLFolder(cida), HIDA_GetPIDLItem(cida, 0)));
|
||||
CComHeapPtr<WCHAR> wszName;
|
||||
if (FAILED_UNEXPECTEDLY(SHGetNameFromIDList(completePidl, SIGDN_PARENTRELATIVEPARSING, &wszName)))
|
||||
return 0;
|
||||
|
||||
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);
|
||||
BOOL bSuccess = SH_ShowPropertiesDialog(wszName, pDataObject);
|
||||
if (!bSuccess)
|
||||
ERR("SH_ShowPropertiesDialog failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Failed to get display name\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue