1

也许这是一个愚蠢的问题,但我有一个与许多 TTreeViewItems 链接的弹出菜单。问题是 TTreeView.Selected 属性永远不会在右键单击时设置。GetMousePos 容易返回下一个或上一个 TTreeViewItem 的坐标。如何获取实际触发弹出窗口的项目?

4

2 回答 2

3

您可以像这样使用TPopupMenu的 OnPopup 事件:

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;
于 2013-12-25T14:06:42.833 回答
2

当您单击 PopupMenu 中的项目时似乎TPopupMenu.PopupPoint返回点(在 Delphi XE2中,docwiki 说它在内部用于设置菜单的位置,并且似乎在菜单消失时设置为 0)。所以在这种情况下,在我看来,最简单的方法是处理可以保存对选定项目的引用的位置,然后在弹出项目事件处理程序中使用它;(0,0)TreeView.OnMouseDown

因此,在下面的示例代码中,我已添加FClickedItem : TTreeViewItem到表单类中;

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;

更新:我刚刚浏览了源代码,私有变量TPopupMenu.FPopupPoint(只读属性)未在实现代码中使用,这就是为什么它总是 =(0,0)

于 2013-12-25T14:08:48.693 回答