[SHELL32] CDefView: Find a reasonable place to show a context menu

Previously, we would treat the input as unsigned coordinates, this is wrong!
If the coordinates are invalid, we try to find a focused or selected item.
The center of this item is where we'll show the menu.
When there is no item, we default to 0,0
This commit is contained in:
Mark Jansen 2019-01-14 21:49:59 +01:00 committed by Giannis Adamopoulos
parent f9e50f5471
commit 9ae373a023

View file

@ -1324,14 +1324,11 @@ cleanup:
*/
LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
WORD x, y;
int x, y;
UINT uCommand;
HRESULT hResult;
x = LOWORD(lParam);
y = HIWORD(lParam);
TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x, y);
TRACE("(%p)->()\n", this);
m_hContextMenu = CreatePopupMenu();
if (!m_hContextMenu)
@ -1348,6 +1345,43 @@ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b
if (FAILED_UNEXPECTEDLY(hResult))
goto cleanup;
/* There is no position requested, so try to find one */
if (lParam == ~0)
{
int lvIndex;
POINT pt;
/* Do we have a focused item, */
if ((lvIndex = m_ListView.GetNextItem(-1, LVIS_FOCUSED)) < 0)
{
/* or a selected item? */
lvIndex = m_ListView.GetNextItem(-1, LVIS_SELECTED);
}
/* We got something */
if (lvIndex > -1)
{
/* Let's find the center of the icon */
RECT rc = { LVIR_ICON };
m_ListView.SendMessage(LVM_GETITEMRECT, lvIndex, (LPARAM)&rc);
pt.x = (rc.right + rc.left) / 2;
pt.y = (rc.bottom + rc.top) / 2;
}
else
{
/* We have to drop it somewhere.. */
pt.x = pt.y = 0;
}
m_ListView.ClientToScreen(&pt);
x = pt.x;
y = pt.y;
}
else
{
x = GET_X_LPARAM(lParam);
y = GET_Y_LPARAM(lParam);
}
uCommand = TrackPopupMenu(m_hContextMenu,
TPM_LEFTALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
x, y, 0, m_hWnd, NULL);