How to get the tree-view item which triggered a popup menu?

1.9k views Asked by At

Its a dumb question maybe but I have a popup menu which is linked with many TTreeViewItems. The problem is that the TTreeView.Selected property never gets set on right click. The GetMousePos is prone to returning the next or the previous TTreeViewItem's coordinates. How can I get the Item which actually triggered the popup?

2

There are 2 answers

3
teran On BEST ANSWER

seems TPopupMenu.PopupPoint returns (0,0) point when you click item in PopupMenu (In Delphi XE2, docwiki says that it is used internally to set position of menu, and seems it is set to 0 when menu dissapears). so in this situation, seems to me, the easiest way is to handle TreeView.OnMouseDown where you can save reference to selected item, and then use it in Popup item event handler;

so, in the exmaple code below i've added FClickedItem : TTreeViewItem into the form class;

procedure TSampleForm.SampleTreeViewMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
    if button = TMouseButton.mbRight then
         FClickedItem := SampleTreeView.ItemByPoint(x,y)
    else FClickedItem := nil;
end;

procedure TSampleForm.TestMenuItemClick(Sender: TObject);
begin
    if Assigned(FClickedItem) then
         ShowMessage(Format('Item `%s (%s)` was selected!', [FClickedItem.Text, FClickedItem.Name]))
    else ShowMessage('there is nothing to show');
end;

UPDATE: i've just browsed the source code, private variable TPopupMenu.FPopupPoint (readonly property) is not used in implementation code, thats why it is always = (0,0)

1
SimaWB On

You can use OnPopup event of TPopupMenu like this:

procedure TForm7.PopupMenu1Popup(Sender: TObject);
var
  aNode: TTreeNode;
  p: TPoint;
begin
  p := TreeView1.ScreenToClient(PopupMenu1.PopupPoint);
  aNode := TreeView1.GetNodeAt(p.X, p.Y);
  if aNode <> Nil then
    caption := aNode.Text;
end;