From: Vadim Zeitlin Date: Sun, 7 Jan 2007 15:43:22 +0000 (+0000) Subject: return correct item and position from wxTreeEvent::GetItem/Point() (patch 1622166) X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/8f6dc819f8e5042e76ba641c63d2c1b7de7af40c?ds=sidebyside return correct item and position from wxTreeEvent::GetItem/Point() (patch 1622166) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44118 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/samples/treectrl/treetest.cpp b/samples/treectrl/treetest.cpp index 31666e9df6..70988cda7c 100644 --- a/samples/treectrl/treetest.cpp +++ b/samples/treectrl/treetest.cpp @@ -1084,8 +1084,12 @@ void MyTreeCtrl::OnBeginDrag(wxTreeEvent& event) { m_draggedItem = event.GetItem(); - wxLogMessage(wxT("OnBeginDrag: started dragging %s"), - GetItemText(m_draggedItem).c_str()); + wxPoint clientpt = event.GetPoint(); + wxPoint screenpt = ClientToScreen(clientpt); + + wxLogMessage(wxT("OnBeginDrag: started dragging %s at screen coords (%i,%i)"), + GetItemText(m_draggedItem).c_str(), + screenpt.x, screenpt.y); event.Allow(); } @@ -1195,45 +1199,21 @@ void MyTreeCtrl::OnItemMenu(wxTreeEvent& event) wxTreeItemId itemId = event.GetItem(); MyTreeItemData *item = itemId.IsOk() ? (MyTreeItemData *)GetItemData(itemId) : NULL; + wxPoint clientpt = event.GetPoint(); + wxPoint screenpt = ClientToScreen(clientpt); - wxLogMessage(wxT("OnItemMenu for item \"%s\""), item ? item->GetDesc() - : _T("")); + wxLogMessage(wxT("OnItemMenu for item \"%s\" at screen coords (%i, %i)"), + item ? item->GetDesc() : _T(""), screenpt.x, screenpt.y); + ShowMenu(itemId, clientpt); event.Skip(); } void MyTreeCtrl::OnContextMenu(wxContextMenuEvent& event) { wxPoint pt = event.GetPosition(); - wxTreeItemId item; - wxLogMessage(wxT("OnContextMenu at screen coords (%i, %i)"), pt.x, pt.y); - - // check if event was generated by keyboard (MSW-specific?) - if ( pt.x == -1 && pt.y == -1 ) //(this is how MSW indicates it) - { - if ( !HasFlag(wxTR_MULTIPLE) ) - item = GetSelection(); - - // attempt to guess where to show the menu - if ( item.IsOk() ) - { - // if an item was clicked, show menu to the right of it - wxRect rect; - GetBoundingRect(item, rect, true /* only the label */); - pt = wxPoint(rect.GetRight(), rect.GetTop()); - } - else - { - pt = wxPoint(0, 0); - } - } - else // event was generated by mouse, use supplied coords - { - pt = ScreenToClient(pt); - item = HitTest(pt); - } - ShowMenu(item, pt); + wxLogMessage(wxT("OnContextMenu at screen coords (%i, %i)"), pt.x, pt.y); } void MyTreeCtrl::ShowMenu(wxTreeItemId id, const wxPoint& pt) diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index 8eb9799301..b44bf35a7d 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -2009,31 +2009,46 @@ WXLRESULT wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara { int x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam); - // Convert the screen point to a client point - wxPoint MenuPoint = ScreenToClient(wxPoint(x, y)); - - // can't use GetSelection() here as it would assert in multiselect mode - wxTreeEvent event(wxEVT_COMMAND_TREE_ITEM_MENU, this, - wxTreeItemId(TreeView_GetSelection(GetHwnd()))); - - // Get the bounding rectangle for the item, including the non-text areas - wxRect ItemRect; - GetBoundingRect(event.m_item, ItemRect, false); - // If the point is inside the bounding rectangle, use it as the click position. - // This should be the case for WM_CONTEXTMENU as the result of a right-click - if (ItemRect.Contains(MenuPoint)) + + // the item for which the menu should be shown + wxTreeItemId item; + + // the position where the menu should be shown in client coordinates + // (so that it can be passed directly to PopupMenu()) + wxPoint pt; + + if ( x == -1 || y == -1 ) { - event.m_pointDrag = MenuPoint; + // this means that the event was generated from keyboard (e.g. with + // Shift-F10 or special Windows menu key) + // + // use the Explorer standard of putting the menu at the left edge + // of the text, in the vertical middle of the text + item = wxTreeItemId(TreeView_GetSelection(GetHwnd())); + if ( item.IsOk() ) + { + // Use the bounding rectangle of only the text part + wxRect rect; + GetBoundingRect(item, rect, true); + pt = wxPoint(rect.GetX(), rect.GetY() + rect.GetHeight() / 2); + } } - // Use the Explorer standard of putting the menu at the left edge of the text, - // in the vertical middle of the text. Should be the case for the "menu" key - else + else // event from mouse, use mouse position { - // Use the bounding rectangle of only the text part - GetBoundingRect(event.m_item, ItemRect, true); - event.m_pointDrag = wxPoint(ItemRect.GetX(), ItemRect.GetY() + ItemRect.GetHeight() / 2); + pt = ScreenToClient(wxPoint(x, y)); + + TV_HITTESTINFO tvhti; + tvhti.pt.x = pt.x; + tvhti.pt.y = pt.y; + if ( TreeView_HitTest(GetHwnd(), &tvhti) ) + item = wxTreeItemId(tvhti.hItem); } + // create the event + wxTreeEvent event(wxEVT_COMMAND_TREE_ITEM_MENU, this, item); + + event.m_pointDrag = pt; + if ( GetEventHandler()->ProcessEvent(event) ) processed = true; //else: continue with generating wxEVT_CONTEXT_MENU in base class code