Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - TTreeView Rekursiv befüllen


Tilman - Do 17.11.05 17:47
Titel: TTreeView Rekursiv befüllen
Ich möchte für ein vorgegebenes Window alle ChildWindows in einem TreeView darstellen. zu diesem Zweck wird die API-CallBack-Funktion EnumChildWindows bemüht. Funktioniert soweit auch ganz gut, ich füge dem treeView einen neuen Node hinzu mit dem Namen des Window und in der CallBack-Funktion jeweils einen ChildNode mit den namen der entsprechenden child-windows.

Nun möchte ich jedoch auch die ganzen Child-Childs durchgehen. Das heißt, ich müsste die EnumChildWindows dann rekursiv mit den neuen handles durchgehen. Wie würdet ihr das mit dem TreeView machen? ich habe bisher nur ein globales TTreeNode-Object, an welches die childs angehängt werden.

// Edit:
Ich kann in der Callback-Funktion einen Integer-Wert mitgeben, über den könnte ich also die "Ebene" erfragen. ich kann aber keine anderen Parameter übergeben, also keine Zeiger oder so.


tgr - Do 17.11.05 18:01

An eine CallBack-Funktion übergibt man als bestes immer eine Referenz auf sich selbst,
also Integer(Self).
Damit hat man vollen Zugriff auf das Objekt, bzw. kann aus der CallBack-Routine eine Objekt-Routine aufrufen.


Tilman - Do 17.11.05 18:43

Zur veranschaulichung mal mein Code (verinfacht, aber lauffähig):
Unw wie gesagt, ich möchte für jedes Child alle weiteren Childs ermitteln und einfügen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
var
  Form1: TForm1;
  a: tTreeNode;
implementation

{$R *.dfm}

function EnumWins(hwnd: Hwnd; lparam: Lparam): Boolean; stdcall;

begin
  form1.listbox1.items.Add(IntToStr(hwnd));
  result := true;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
listbox1.Clear;
enumWindows(@enumwins,0);
end;

function EnumChilds(hwnd: Hwnd; lparam: Lparam): Boolean; stdcall;
var pText: PChar;
    var B: TTreeNode;
begin
ptext := strAlloc(124);
getWindowText(hwnd,ptext,124);
b := form1.TreeView1.Items.AddChild(a,ptext);
result := true;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
form1.TreeView1.Items.Clear;
a := TTreeNode.Create(treeview1.Items);
a := treeview1.Items.Add(a,listbox1.Items[listbox1.itemindex]);

enumChildWindows(StrToInt(listbox1.Items[listbox1.ItemIndex]),@enumchilds,0);
end;
end.


Tilman - Do 17.11.05 18:59

Frage hat sich erledigt, ich mach es jetzt doch anders :roll: