Your mistake is to access the node, to get its index, that you've deleted: SelNode
in your example. It's causing an AV.
Assuming your question is about the Lazarus's TreeView control (as mentioned in the question), you can follow Kobik's suggestion in the comments and find the node to be selected before you delete the item. Or, which I find simpler, you can implement your logic in the OnDeletion
event of the TreeView. This event is fired just before the item is actually destroyed.
procedure TForm1.actDeleteExecute(Sender: TObject);
begin
if Assigned(TreeView1.Selected) then begin
TreeView1.Selected.Delete;
TreeView1.SetFocus;
end;
end;
procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
if Assigned(TreeView1.Selected.GetPrevSibling) then
TreeView1.Selected := TreeView1.Selected.GetPrevSibling
else if Assigned(TreeView1.Selected.GetNextSibling) then
TreeView1.Selected := TreeView1.Selected.GetNextSibling
else if Assigned(TreeView1.Selected.GetPrev) then
TreeView1.Selected := TreeView1.Selected.GetPrev
else
TreeView1.Selected := TreeView1.Selected.GetNext; // can be nil
end;
Note that I was unable to follow your logic regarding which item to select when one is deleted, primarily because when a node is deleted all of its children is deleted as well. You can adjust the above to suit your needs.