mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 21:44:31 +00:00
[BROWSEUI]
- CExplorerBand: Implement showing the context menu on right click. - Part of the work submitted by Sylvain Deverre. CORE-10838 svn path=/trunk/; revision=72004
This commit is contained in:
parent
0c47416f5d
commit
37a1045d72
|
@ -142,6 +142,33 @@ CExplorerBand::NodeInfo* CExplorerBand::GetNodeInfo(HTREEITEM hItem)
|
|||
return reinterpret_cast<NodeInfo*>(tvItem.lParam);
|
||||
}
|
||||
|
||||
HRESULT CExplorerBand::ExecuteCommand(CComPtr<IContextMenu>& menu, UINT nCmd)
|
||||
{
|
||||
CComPtr<IOleWindow> pBrowserOleWnd;
|
||||
CMINVOKECOMMANDINFO cmi;
|
||||
HWND browserWnd;
|
||||
HRESULT hr;
|
||||
|
||||
hr = IUnknown_QueryService(pSite, SID_SShellBrowser, IID_PPV_ARG(IOleWindow, &pBrowserOleWnd));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
hr = pBrowserOleWnd->GetWindow(&browserWnd);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
ZeroMemory(&cmi, sizeof(cmi));
|
||||
cmi.cbSize = sizeof(cmi);
|
||||
cmi.lpVerb = MAKEINTRESOURCEA(nCmd);
|
||||
cmi.hwnd = browserWnd;
|
||||
if (GetKeyState(VK_SHIFT) & 0x8000)
|
||||
cmi.fMask |= CMIC_MASK_SHIFT_DOWN;
|
||||
if (GetKeyState(VK_CONTROL) & 0x8000)
|
||||
cmi.fMask |= CMIC_MASK_CONTROL_DOWN;
|
||||
|
||||
return menu->InvokeCommand(&cmi);
|
||||
}
|
||||
|
||||
HRESULT CExplorerBand::UpdateBrowser(LPITEMIDLIST pidlGoto)
|
||||
{
|
||||
CComPtr<IShellBrowser> pBrowserService;
|
||||
|
@ -197,17 +224,111 @@ void CExplorerBand::OnSelectionChanged(LPNMTREEVIEW pnmtv)
|
|||
{
|
||||
NodeInfo* pNodeInfo = GetNodeInfo(pnmtv->itemNew.hItem);
|
||||
|
||||
UpdateBrowser(pNodeInfo->absolutePidl);
|
||||
|
||||
/* Prevents navigation if selection is initiated inside the band */
|
||||
if (bNavigating)
|
||||
return;
|
||||
|
||||
UpdateBrowser(pNodeInfo->absolutePidl);
|
||||
|
||||
SetFocus();
|
||||
// Expand the node
|
||||
//TreeView_Expand(m_hWnd, pnmtv->itemNew.hItem, TVE_EXPAND);
|
||||
}
|
||||
|
||||
|
||||
// *** ATL event handlers ***
|
||||
LRESULT CExplorerBand::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
||||
{
|
||||
HTREEITEM item;
|
||||
NodeInfo *info;
|
||||
HMENU treeMenu;
|
||||
WORD x;
|
||||
WORD y;
|
||||
CComPtr<IShellFolder> pFolder;
|
||||
CComPtr<IContextMenu> contextMenu;
|
||||
HRESULT hr;
|
||||
UINT uCommand;
|
||||
LPITEMIDLIST pidlChild;
|
||||
|
||||
treeMenu = NULL;
|
||||
item = TreeView_GetSelection(m_hWnd);
|
||||
bHandled = TRUE;
|
||||
if (!item)
|
||||
{
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
x = LOWORD(lParam);
|
||||
y = HIWORD(lParam);
|
||||
if (x == -1 && y == -1)
|
||||
{
|
||||
// TODO: grab position of tree item and position it correctly
|
||||
}
|
||||
|
||||
info = GetNodeInfo(item);
|
||||
if (!info)
|
||||
{
|
||||
ERR("No node data, something has gone wrong !\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
hr = SHBindToParent(info->absolutePidl, IID_PPV_ARG(IShellFolder, &pFolder),
|
||||
(LPCITEMIDLIST*)&pidlChild);
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
ERR("Can't bind to folder!\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
hr = pFolder->GetUIObjectOf(m_hWnd, 1, (LPCITEMIDLIST*)&pidlChild, IID_IContextMenu,
|
||||
NULL, reinterpret_cast<void**>(&contextMenu));
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
ERR("Can't get IContextMenu interface\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
treeMenu = CreatePopupMenu();
|
||||
hr = contextMenu->QueryContextMenu(treeMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST,
|
||||
CMF_EXPLORE);
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
WARN("Can't get context menu for item\n");
|
||||
DestroyMenu(treeMenu);
|
||||
goto Cleanup;
|
||||
}
|
||||
uCommand = TrackPopupMenu(treeMenu, TPM_LEFTALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
|
||||
x, y, 0, m_hWnd, NULL);
|
||||
|
||||
ExecuteCommand(contextMenu, uCommand);
|
||||
Cleanup:
|
||||
if (treeMenu)
|
||||
DestroyMenu(treeMenu);
|
||||
bNavigating = TRUE;
|
||||
TreeView_SelectItem(m_hWnd, oldSelected);
|
||||
bNavigating = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LRESULT CExplorerBand::ContextMenuHack(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
||||
{
|
||||
bHandled = FALSE;
|
||||
if (uMsg == WM_RBUTTONDOWN)
|
||||
{
|
||||
TVHITTESTINFO info;
|
||||
info.pt.x = LOWORD(lParam);
|
||||
info.pt.y = HIWORD(lParam);
|
||||
info.flags = TVHT_ONITEM;
|
||||
info.hItem = NULL;
|
||||
|
||||
// Save the current location
|
||||
oldSelected = TreeView_GetSelection(m_hWnd);
|
||||
|
||||
// Move to the item selected by the treeview (don't change right pane)
|
||||
TreeView_HitTest(m_hWnd, &info);
|
||||
bNavigating = TRUE;
|
||||
TreeView_SelectItem(m_hWnd, info.hItem);
|
||||
bNavigating = FALSE;
|
||||
}
|
||||
return FALSE; /* let the wndproc process the message */
|
||||
}
|
||||
// *** Helper functions ***
|
||||
HTREEITEM CExplorerBand::InsertItem(HTREEITEM hParent, IShellFolder *psfParent, LPITEMIDLIST pElt, LPITEMIDLIST pEltRelative, BOOL bSort)
|
||||
{
|
||||
|
@ -723,6 +844,7 @@ HRESULT STDMETHODCALLTYPE CExplorerBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
|
|||
// *** IWinEventHandler methods ***
|
||||
HRESULT STDMETHODCALLTYPE CExplorerBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
|
||||
{
|
||||
BOOL bHandled;
|
||||
if (uMsg == WM_NOTIFY)
|
||||
{
|
||||
NMHDR *pNotifyHeader = (NMHDR*)lParam;
|
||||
|
@ -734,6 +856,74 @@ HRESULT STDMETHODCALLTYPE CExplorerBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM
|
|||
case TVN_SELCHANGED:
|
||||
OnSelectionChanged((LPNMTREEVIEW)lParam);
|
||||
break;
|
||||
case NM_RCLICK:
|
||||
OnContextMenu(WM_CONTEXTMENU, (WPARAM)m_hWnd, GetMessagePos(), bHandled);
|
||||
*theResult = 1;
|
||||
break;
|
||||
case TVN_BEGINLABELEDITW:
|
||||
{
|
||||
// TODO: put this in a function ? (mostly copypasta from CDefView)
|
||||
DWORD dwAttr = SFGAO_CANRENAME;
|
||||
LPNMTVDISPINFO dispInfo = (LPNMTVDISPINFO)lParam;
|
||||
CComPtr<IShellFolder> pParent;
|
||||
LPCITEMIDLIST pChild;
|
||||
HRESULT hr;
|
||||
|
||||
*theResult = 1;
|
||||
NodeInfo *info = GetNodeInfo(dispInfo->item.hItem);
|
||||
if (!info)
|
||||
return E_FAIL;
|
||||
hr = SHBindToParent(info->absolutePidl, IID_PPV_ARG(IShellFolder, &pParent), &pChild);
|
||||
if (!SUCCEEDED(hr) || !pParent.p)
|
||||
return E_FAIL;
|
||||
|
||||
hr = pParent->GetAttributesOf(1, &pChild, &dwAttr);
|
||||
if (SUCCEEDED(hr) && (dwAttr & SFGAO_CANRENAME))
|
||||
*theResult = 0;
|
||||
return S_OK;
|
||||
}
|
||||
case TVN_ENDLABELEDITW:
|
||||
{
|
||||
LPNMTVDISPINFO dispInfo = (LPNMTVDISPINFO)lParam;
|
||||
NodeInfo *info = GetNodeInfo(dispInfo->item.hItem);
|
||||
HRESULT hr;
|
||||
|
||||
*theResult = 0;
|
||||
if (dispInfo->item.pszText)
|
||||
{
|
||||
LPITEMIDLIST pidlNew;
|
||||
CComPtr<IShellFolder> pParent;
|
||||
LPCITEMIDLIST pidlChild;
|
||||
|
||||
hr = SHBindToParent(info->absolutePidl, IID_PPV_ARG(IShellFolder, &pParent), &pidlChild);
|
||||
if (!SUCCEEDED(hr) || !pParent.p)
|
||||
return E_FAIL;
|
||||
|
||||
hr = pParent->SetNameOf(0, pidlChild, dispInfo->item.pszText, SHGDN_INFOLDER, &pidlNew);
|
||||
if(SUCCEEDED(hr) && pidlNew)
|
||||
{
|
||||
CComPtr<IPersistFolder2> pPersist;
|
||||
LPITEMIDLIST pidlParent, pidlNewAbs;
|
||||
|
||||
hr = pParent->QueryInterface(IID_PPV_ARG(IPersistFolder2, &pPersist));
|
||||
if(!SUCCEEDED(hr))
|
||||
return E_FAIL;
|
||||
|
||||
hr = pPersist->GetCurFolder(&pidlParent);
|
||||
if(!SUCCEEDED(hr))
|
||||
return E_FAIL;
|
||||
pidlNewAbs = ILCombine(pidlParent, pidlNew);
|
||||
|
||||
// Navigate to our new location
|
||||
UpdateBrowser(pidlNewAbs);
|
||||
|
||||
ILFree(pidlNewAbs);
|
||||
ILFree(pidlNew);
|
||||
*theResult = 1;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ private:
|
|||
DWORD dwBandID;
|
||||
HIMAGELIST hImageList;
|
||||
HTREEITEM hRoot;
|
||||
HTREEITEM oldSelected;
|
||||
|
||||
// *** notification cookies ***
|
||||
DWORD adviseCookie;
|
||||
|
@ -68,10 +69,15 @@ private:
|
|||
|
||||
void InitializeExplorerBand();
|
||||
void DestroyExplorerBand();
|
||||
HRESULT ExecuteCommand(CComPtr<IContextMenu>& menu, UINT nCmd);
|
||||
|
||||
BOOL OnTreeItemExpanding(LPNMTREEVIEW pnmtv);
|
||||
void OnSelectionChanged(LPNMTREEVIEW pnmtv);
|
||||
|
||||
// *** ATL event handlers ***
|
||||
LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT ContextMenuHack(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
|
||||
// *** Helper functions ***
|
||||
NodeInfo* GetNodeInfo(HTREEITEM hItem);
|
||||
HRESULT UpdateBrowser(LPITEMIDLIST pidlGoto);
|
||||
|
@ -174,6 +180,8 @@ public:
|
|||
END_COM_MAP()
|
||||
|
||||
BEGIN_MSG_MAP(CExplorerBand)
|
||||
MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu)
|
||||
MESSAGE_HANDLER(WM_RBUTTONDOWN, ContextMenuHack)
|
||||
END_MSG_MAP()
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue