Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Del-key deletes whole treeview, when the shortcut is re-defined dynamically

I have following code:

procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
var
  m: TMenuItem;
begin
  // Here, some dynamic stuff is done, so every node gets individual items in the mainmenu
  Node1.Clear;

  m := TMenuItem.Create(Self);
  m.Caption := 'Delete';
  m.ShortCut := VK_DELETE;
  m.OnClick := AcDelete;
  Node1.Add(m);
end;

procedure TForm1.AcDelete(Sender: TObject);
begin
  if not Assigned(TreeView1.Selected) then Exit;
  TreeView1.Selected.Delete;
end;

procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
  // Only when I do this, the "Del"-key-loop will break. But then, the new
  // selected item won't get new menu individual items.
  // TreeView1.OnChange := nil;
end;

At the form there is a TMainMenu and a TTreeView .

Whenever something is selected in the treeview, an individual menu will be created for each node. This created menu usually includes "Delete node" which has the shortcut [Del]. However, this must be dynamically created too.

When I press the [Del] key, the item gets deleted by AcDelete and the follower node will be selected of course. Due to the selection of the follower node, TreeView1Change gets invoked which creates a new individual menu. It is all fine until then.

The problem is, that the VCL still thinks that the [DEL] key is pressed, so the follower node will be deleted too. And its follower too. And so on, until the whole list is empty. So, deleting one item with the [Del] key deletes everything. This does not happen when I use the mouse, of course.

What can I do to tell the VCL that the [Del] key is not pressed anymore, when the new menu is created? Some workaround I could do in TreeView1Deletion?


The DFM code:

object Form1: TForm1
  Left = 192
  Top = 107
  Width = 1305
  Height = 750
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  Menu = MainMenu1
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object TreeView1: TTreeView
    Left = 128
    Top = 56
    Width = 233
    Height = 193
    Indent = 19
    TabOrder = 0
    OnChange = TreeView1Change
    OnDeletion = TreeView1Deletion
    Items.Data = {
      04000000220000000000000000000000FFFFFFFFFFFFFFFF0000000000000000
      09323334323334323334210000000000000000000000FFFFFFFFFFFFFFFF0000
      0000000000000832336173647361641F0000000000000000000000FFFFFFFFFF
      FFFFFF0000000000000000067274656574721E0000000000000000000000FFFF
      FFFFFFFFFFFF0000000000000000053333333333}
  end
  object MainMenu1: TMainMenu
    Left = 88
    Top = 80
    object Node1: TMenuItem
      Caption = 'Node'
    end
  end
end
like image 342
Daniel Marschall Avatar asked Dec 05 '25 16:12

Daniel Marschall


1 Answers

Add 1 action DeleteAction: TAction with shortcut assigned (DEL). Change code like this:

procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
var
  m: TMenuItem;
begin
  // Here, some dynamic stuff is done, so every node gets individual items in the mainmenu
  Node1.Clear;

  m := TMenuItem.Create(Self);
  m.Caption := 'Delete';
  m.Action := DeleteAction;
  DeleteAction.OnExecute := AcDelete;
  Node1.Add(m);
end;

procedure TForm1.AcDelete(Sender: TObject);
begin
  if not Assigned(TreeView1.Selected) then Exit;
  TreeView1.Selected.Delete;
end;

procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
  // Only when I do this, the "Del"-key-loop will break. But then, the new
  // selected item won't get new menu individual items.
  // TreeView1.OnChange := nil;
end;

It should help (because we don't create items with same shortcut in run-time anymore).

like image 95
Andrei Galatyn Avatar answered Dec 09 '25 09:12

Andrei Galatyn