Title: TreeView Items - Dynamic Context (Popup) Menus in Delphi
The TTreeView Delphi control wraps the Windows tree view control. TTreeView is comonly used when a hierarhical structure needs to be displayed to the user. By clicking an item, the user can expand and collapse the associated list of subitems.
In complex tree views, you might want to display customized - dynamic context menu for each tree node.
TreeView Popup Menu - Node "Aware"
The PopupMenu property, every Delphi control publishes, identifies the pop-up menu associated with the control.
When the user selects the control and clicks the right mouse button the pop-up menu (an instance of the TPopupMenu control) will popup.
Since you will, in most cases, predefine the items of the popup menu at design time, every time the user right-clicks the control the "static" context menu will pop-up.
For those Delphi controls that display "items" - as tree views and list views you might want to have different popup menus for each item.
Drop a TTreeView on a Delphi Form. Drop a TPopupMenu and let it have some items. Assign this popup menu for the PopupMenu property of the tree view.
Run the "program" - note how the popup menu pops-up whenever you righ-click on the tree view. It pops-up even when a tree node is not selected - or - when you right click on an area where there are no nodes.
To make the PopupMenu "node aware" you need to know if there's a node "below" the mouse pointer. Also, you migh want to select the node.
The OnContextPopup event is fired when the user right-clicks the control or otherwise invokes the popup menu (such as using the keyboard).
By handling the OnContextPopup for a tree view, you can locate the node under the mouse, make it selected and alter the popup menu to dynamically display node specific actions (relevant to your application). Here's how:
//handles TreeView's OnContextPopup
procedure TTreeViewForm.TreeView1ContextPopup(
Sender: TObject;
MousePos: TPoint;
var Handled: Boolean) ;
var
treeNode : TTreenode;
treeView : TTreeView;
begin
treeView := TTreeview(sender) ;
treeNode := treeView.GetNodeAt(MousePos.X, MousePos.Y) ;
if Assigned(treeNode) then
begin
treeView.Selected := treeNode;
// "mnuDoIt1" is the name of one of the popup menu items
mnuDoIt1.Caption := Format('Do For Item: %s', ) ;
//popup will display automatically
end
else
begin
//no node under mouse - do not display popup
Handled := true;
end;
end;
When the user right-click the tree view, before the context popup is displayed, the OnContextPopup will be fired.
Setting the Handled parameter to TRUE will suppress the default context menu.
By using the GetNodeAt you can check if there's a node under the mouse pointer. If there's a node under the mose - make it selected. Otherwise, set Handled to true.