voodoo22
asked on
Using TTreeView
I am pretty new to using the TTreeView component and while I have figued out some of it on my own I still can't seem to find any information on the following things so if one of the experts could help me out it would be great.
1.) How to get the count of items per level (ie. level0 items count = 44 level1 items count = 212...)
2.) How do you load (specific information)from a text file when you click on an node/subnode.
1.) How to get the count of items per level (ie. level0 items count = 44 level1 items count = 212...)
2.) How do you load (specific information)from a text file when you click on an node/subnode.
listening . . . no time yet
Hope this helps a little...
grtz.
//Code
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, Menus, ExtCtrls;
type
TForm1 = class(TForm)
TreeView1: TTreeView;
Panel1: TPanel;
RichEdit1: TRichEdit;
Button2: TButton;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
I,J: Integer;
aTreeNodes : TTreeNodes;
aTreeNode : TTreeNode;
begin
aTreeNodes := TTreeNodes.Create(TreeView 1);
for I := 1 to 10 do
begin
aTreeNode := TreeView1.Items.Add( TTreeNode.Create(aTreeNode s), 'DEMO' + IntToStr(I) );
for J := 1 to random(10)+1 do
TreeView1.Items.AddChild(a TreeNode, 'TEST' + IntToStr(J));
end;
end;
procedure TForm1.Button1Click(Sender : TObject);
begin
RichEdit1.Lines.LoadFromFi le(
TreeView1.Items.Item[TreeV iew1.Selec ted.Absolu teIndex].T ext + '.txt' );
end;
procedure TForm1.Button2Click(Sender : TObject);
begin
ShowMessage( 'Counted subitems : ' +
IntToStr(TreeView1.Selecte d.Count) );
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
I,J: Integer;
begin
for I := 1 to 10 do
begin
for J := 0 to (TreeView1.Items[I-1].Coun t - 1) do
TreeView1.Items.Item[J].Fr ee;
TreeView1.Items[I-1].Free;
end;
end;
end.
grtz.
//Code
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, Menus, ExtCtrls;
type
TForm1 = class(TForm)
TreeView1: TTreeView;
Panel1: TPanel;
RichEdit1: TRichEdit;
Button2: TButton;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
I,J: Integer;
aTreeNodes : TTreeNodes;
aTreeNode : TTreeNode;
begin
aTreeNodes := TTreeNodes.Create(TreeView
for I := 1 to 10 do
begin
aTreeNode := TreeView1.Items.Add( TTreeNode.Create(aTreeNode
for J := 1 to random(10)+1 do
TreeView1.Items.AddChild(a
end;
end;
procedure TForm1.Button1Click(Sender
begin
RichEdit1.Lines.LoadFromFi
TreeView1.Items.Item[TreeV
end;
procedure TForm1.Button2Click(Sender
begin
ShowMessage( 'Counted subitems : ' +
IntToStr(TreeView1.Selecte
end;
procedure TForm1.FormDestroy(Sender:
var
I,J: Integer;
begin
for I := 1 to 10 do
begin
for J := 0 to (TreeView1.Items[I-1].Coun
TreeView1.Items.Item[J].Fr
TreeView1.Items[I-1].Free;
end;
end;
end.
procedure TForm1.Button1Click(Sender : TObject);
var
I: Integer;
J: Integer;
K: Integer;
L: Integer;
begin
with TreeView1 do
begin
K := -1;
for I := 0 to 2 do
begin
Inc(K);
L := 0;
Items.AddObject(nil, 'Item ' + IntToStr(I), nil);
for J := 0 to I do
begin
Items.AddChild(Items[K], 'Item ' + IntToStr(I) + '.' + IntToStr(L));
Inc(K);
Inc(L);
end;
end;
end;
end;
procedure TForm1.Button2Click(Sender : TObject);
var
I: Integer;
begin
Memo1.Clear;
for I := 0 to TreeView1.Items.Count-1 do
begin
Memo1.Lines.Add(TreeView1. Items[I].T ext + ' contains ' + IntToStr(TreeView1.Items[I ].Count) + ' Children');
end;
end;
emil
var
I: Integer;
J: Integer;
K: Integer;
L: Integer;
begin
with TreeView1 do
begin
K := -1;
for I := 0 to 2 do
begin
Inc(K);
L := 0;
Items.AddObject(nil, 'Item ' + IntToStr(I), nil);
for J := 0 to I do
begin
Items.AddChild(Items[K], 'Item ' + IntToStr(I) + '.' + IntToStr(L));
Inc(K);
Inc(L);
end;
end;
end;
end;
procedure TForm1.Button2Click(Sender
var
I: Integer;
begin
Memo1.Clear;
for I := 0 to TreeView1.Items.Count-1 do
begin
Memo1.Lines.Add(TreeView1.
end;
end;
emil
ASKER
pcools
The Items I need to count need to be counted when the form is created so using the TreeView1.Selected.Count stuff will not work. Also the code for opening the file would open the entire contents of a file and as stated in my original post I want to open the file but only show part of the information that it contains not the entire contents of the file.
Here is an example file (test.txt)
__________________________ __________ __
The quick brown fox jumped over the lazy dog.
Old McDonald had a farm.
Jack and Jill went up the hill.
Green eggs and ham.
Basketball is a fun sport.
__________________________ __________ _
Now what I want to do is extract out of that text file the line that reads "Green eggs and ham." and only that line will show in the RichEdit Control. That is what I meant when I said "specific information" in my original post.
esoftbg
Your code is way too confusing for me to work from. Maybe if you removed that code that creates the nodes and combine the procedures into 1 which will.
1.)Count the number of Root Nodes and
2.)Count the Number of Items In a Root Node
It might help to say that the deepest level the nodes will go will be Level1 so all you will have to count for is Level0 (RootNodes) and Level1(RootNodeItems) and they have to be counted when the form is created.
here is an example of my treeview (I hope EE does not mess with the formatting)
[]
|_[]
|
|_[]
|
|_[]
|
[]
|
[]
|_[]
|
|_[]
So for this example the RootNode count would be 3 and the and the RootNodeItems count would be 5 and that is all the info I need.
The Items I need to count need to be counted when the form is created so using the TreeView1.Selected.Count stuff will not work. Also the code for opening the file would open the entire contents of a file and as stated in my original post I want to open the file but only show part of the information that it contains not the entire contents of the file.
Here is an example file (test.txt)
__________________________
The quick brown fox jumped over the lazy dog.
Old McDonald had a farm.
Jack and Jill went up the hill.
Green eggs and ham.
Basketball is a fun sport.
__________________________
Now what I want to do is extract out of that text file the line that reads "Green eggs and ham." and only that line will show in the RichEdit Control. That is what I meant when I said "specific information" in my original post.
esoftbg
Your code is way too confusing for me to work from. Maybe if you removed that code that creates the nodes and combine the procedures into 1 which will.
1.)Count the number of Root Nodes and
2.)Count the Number of Items In a Root Node
It might help to say that the deepest level the nodes will go will be Level1 so all you will have to count for is Level0 (RootNodes) and Level1(RootNodeItems) and they have to be counted when the form is created.
here is an example of my treeview (I hope EE does not mess with the formatting)
[]
|_[]
|
|_[]
|
|_[]
|
[]
|
[]
|_[]
|
|_[]
So for this example the RootNode count would be 3 and the and the RootNodeItems count would be 5 and that is all the info I need.
hello voodoo22, Here is some code that works for me to count the Nodes in each level of a TreeView, it is a button Click -
procedure TForm1.button_GetTreeNodes Click(Send er: TObject);
var
Nodes: Array of Integer;
TreeItem1: TTVItem;
i: Integer;
hItem: HTREEITEM;
GotItem: Boolean;
OutStr: String;
function GetTItem(hTItem: HTREEITEM; Level: Cardinal): Boolean;
var
hItemC, hReItem: HTREEITEM;
begin
Result := False;
if hTItem <> nil then
begin
TreeItem1.hItem := hTItem;
if TreeView_GetItem(TreeView1 .Handle,Tr eeItem1) then
begin
Result := True;
if Level > Length(Nodes) then
SetLength(Nodes, Level);
Inc(Nodes[Level-1]);
end;
hItemC := TreeView_GetChild(TreeView 1.Handle, hTItem);
GetTItem(hItemC, Level+1);
hReItem := TreeView_GetNextSibling(Tr eeView1.Ha ndle, hTItem);
if hReItem <> nil then
GetTItem(hReItem, Level);
end;
end;
begin
hItem := TreeView_GetNextItem(TreeV iew1.Handl e, hItem, TVGN_ROOT);
if hItem = nil then
begin
Showmessage(' No Root');
Exit;
end;
SetLength(Nodes, 1);
TreeItem1.mask := TVIF_CHILDREN;
TreeItem1.cChildren := 0;
GotItem := GetTItem(hItem, 1);
if GotItem then
begin
for i := 0 to High(Nodes) do
OutStr := OutStr+' Level '+IntToStr(i)+' - count '+IntToStr(Nodes[i])+',';
Label1.Caption := OutStr;
end
end;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
and I do NOT understand what you are tring to do with the text extraction from a Text file, if you already have the text you want "Green eggs and ham.", then why are you extracting it? Or if you do not have the text, then how do you know what text to extract? Can you use a Line index, like line index 5 for "Green eggs and ham."
procedure TForm1.button_GetTreeNodes
var
Nodes: Array of Integer;
TreeItem1: TTVItem;
i: Integer;
hItem: HTREEITEM;
GotItem: Boolean;
OutStr: String;
function GetTItem(hTItem: HTREEITEM; Level: Cardinal): Boolean;
var
hItemC, hReItem: HTREEITEM;
begin
Result := False;
if hTItem <> nil then
begin
TreeItem1.hItem := hTItem;
if TreeView_GetItem(TreeView1
begin
Result := True;
if Level > Length(Nodes) then
SetLength(Nodes, Level);
Inc(Nodes[Level-1]);
end;
hItemC := TreeView_GetChild(TreeView
GetTItem(hItemC, Level+1);
hReItem := TreeView_GetNextSibling(Tr
if hReItem <> nil then
GetTItem(hReItem, Level);
end;
end;
begin
hItem := TreeView_GetNextItem(TreeV
if hItem = nil then
begin
Showmessage(' No Root');
Exit;
end;
SetLength(Nodes, 1);
TreeItem1.mask := TVIF_CHILDREN;
TreeItem1.cChildren := 0;
GotItem := GetTItem(hItem, 1);
if GotItem then
begin
for i := 0 to High(Nodes) do
OutStr := OutStr+' Level '+IntToStr(i)+' - count '+IntToStr(Nodes[i])+',';
Label1.Caption := OutStr;
end
end;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
and I do NOT understand what you are tring to do with the text extraction from a Text file, if you already have the text you want "Green eggs and ham.", then why are you extracting it? Or if you do not have the text, then how do you know what text to extract? Can you use a Line index, like line index 5 for "Green eggs and ham."
voodo22..
If this ain't what you want, then I think I'll never get it :-))
grtz.
//CODE
function TForm1.TotalRootNodes(ATre eView: TTreeview): Integer;
var
I,ANodes : Integer;
begin
ANodes := 0;
for I := 0 to ATreeView.Items.Count-1 do
if ATreeView.Items[I].Parent = nil then
inc(ANodes);
Result := ANodes;
end;
function TForm1.NumberOfItems(ATree View : TTreeView;ARootNumber: Integer) : Integer;
var
I,ANodes,AnItem : Integer;
begin
ANodes := 0; AnItem := 0;
for I := 0 to ATreeView.Items.Count - 1 do
begin
if ATreeView.Items[I].Parent = nil then
begin
Inc(ANodes);
if ANodes = ARootNumber then
begin
ANodes := I;
Break;
end;
end;
end;
for I := 0 to ATreeView.Items.Count-1 do
if ATreeView.Items[I].HasAsPa rent(ATree View.Items [ANodes]) then
inc(AnItem);
Result := AnItem;
end;
function TForm1.ShowLine(AFileName: AnsiString; ALine: Integer) : AnsiString;
var
aStringList: TStringList;
begin
aStringList := TStringList.Create;
aStringList.LoadFromFile(E xtractFile Path(Appli cation.Exe Name) + AFileName);
Result := aStringList[ALine-1];
aStringList.Free;
end;
procedure TForm1.Button1Click(Sender : TObject);
var
I: Integer;
begin
//Counts all nodes and items
for I := 1 to TotalRootNodes(TreeView1) do
ShowMessage('NODE ' + IntToStr(I) + ' HAS ' + IntToStr(NumberOfItems(Tre eView1,I)) + ' ITEMS');
//Shows line 2 of your text file
ShowMessage(ShowLine('test .txt',2));
end;
If this ain't what you want, then I think I'll never get it :-))
grtz.
//CODE
function TForm1.TotalRootNodes(ATre
var
I,ANodes : Integer;
begin
ANodes := 0;
for I := 0 to ATreeView.Items.Count-1 do
if ATreeView.Items[I].Parent = nil then
inc(ANodes);
Result := ANodes;
end;
function TForm1.NumberOfItems(ATree
var
I,ANodes,AnItem : Integer;
begin
ANodes := 0; AnItem := 0;
for I := 0 to ATreeView.Items.Count - 1 do
begin
if ATreeView.Items[I].Parent = nil then
begin
Inc(ANodes);
if ANodes = ARootNumber then
begin
ANodes := I;
Break;
end;
end;
end;
for I := 0 to ATreeView.Items.Count-1 do
if ATreeView.Items[I].HasAsPa
inc(AnItem);
Result := AnItem;
end;
function TForm1.ShowLine(AFileName:
var
aStringList: TStringList;
begin
aStringList := TStringList.Create;
aStringList.LoadFromFile(E
Result := aStringList[ALine-1];
aStringList.Free;
end;
procedure TForm1.Button1Click(Sender
var
I: Integer;
begin
//Counts all nodes and items
for I := 1 to TotalRootNodes(TreeView1) do
ShowMessage('NODE ' + IntToStr(I) + ' HAS ' + IntToStr(NumberOfItems(Tre
//Shows line 2 of your text file
ShowMessage(ShowLine('test
end;
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hello Slick812,
When I tried to test your code delphi gives me these errors and does not compile:
[Error] Unit1.pas(79): Undeclared identifier: 'HTREEITEM'
[Error] Unit1.pas(88): Undeclared identifier: 'TTVItem'
[Error] Unit1.pas(115): Operator not applicable to this operand type
[Error] Unit1.pas(117): Missing operator or semicolon
[Error] Unit1.pas(118): Undeclared identifier: 'TreeView_GetItem'
[Error] Unit1.pas(118): Undeclared identifier: 'TreeView1'
[Warning] Unit1.pas(121): Comparing signed and unsigned types - widened both operands
[Error] Unit1.pas(125): Undeclared identifier: 'TreeView_GetChild'
[Error] Unit1.pas(125): Missing operator or semicolon
[Error] Unit1.pas(128): Missing operator or semicolon
[Error] Unit1.pas(128): Operator not applicable to this operand type
[Error] Unit1.pas(131): '.' expected but ';' found
[Error] Unit1.pas(239): Undeclared identifier: 'TreeView_GetNextItem'
[Error] Unit1.pas(239): Undeclared identifier: 'TVGN_ROOT'
[Error] Unit1.pas(240): Operator not applicable to this operand type
[Error] Unit1.pas(246): Missing operator or semicolon
[Error] Unit1.pas(247): Missing operator or semicolon
[Warning] Unit1.pas(251): For loop control variable must be simple local variable
[Error] Unit1.pas(253): Undeclared identifier: 'Label1'
[Error] Unit1.pas(79): Unsatisfied forward or external declaration: 'TForm1.GetTItem'
[Fatal Error] Project1.dpr(6): Could not compile used unit 'Unit1.pas'
I guess this kind of thing is not what the TreeView was made for so upon further thinking I am going to do my project a different (better) way and since nobody really came up with an answer that worked I am going to ask that this question be deleted. Thanks for trying though.
When I tried to test your code delphi gives me these errors and does not compile:
[Error] Unit1.pas(79): Undeclared identifier: 'HTREEITEM'
[Error] Unit1.pas(88): Undeclared identifier: 'TTVItem'
[Error] Unit1.pas(115): Operator not applicable to this operand type
[Error] Unit1.pas(117): Missing operator or semicolon
[Error] Unit1.pas(118): Undeclared identifier: 'TreeView_GetItem'
[Error] Unit1.pas(118): Undeclared identifier: 'TreeView1'
[Warning] Unit1.pas(121): Comparing signed and unsigned types - widened both operands
[Error] Unit1.pas(125): Undeclared identifier: 'TreeView_GetChild'
[Error] Unit1.pas(125): Missing operator or semicolon
[Error] Unit1.pas(128): Missing operator or semicolon
[Error] Unit1.pas(128): Operator not applicable to this operand type
[Error] Unit1.pas(131): '.' expected but ';' found
[Error] Unit1.pas(239): Undeclared identifier: 'TreeView_GetNextItem'
[Error] Unit1.pas(239): Undeclared identifier: 'TVGN_ROOT'
[Error] Unit1.pas(240): Operator not applicable to this operand type
[Error] Unit1.pas(246): Missing operator or semicolon
[Error] Unit1.pas(247): Missing operator or semicolon
[Warning] Unit1.pas(251): For loop control variable must be simple local variable
[Error] Unit1.pas(253): Undeclared identifier: 'Label1'
[Error] Unit1.pas(79): Unsatisfied forward or external declaration: 'TForm1.GetTItem'
[Fatal Error] Project1.dpr(6): Could not compile used unit 'Unit1.pas'
I guess this kind of thing is not what the TreeView was made for so upon further thinking I am going to do my project a different (better) way and since nobody really came up with an answer that worked I am going to ask that this question be deleted. Thanks for trying though.
guessing you missed to include the unit commctrl -> just add it in your uses-clause
ASKER
pcools,
Don't mind that last post I did not see your code when I made it. I did decided to use another method for all this stuff but I am going to award you the points anyway so it's not a complete waste of time.
Don't mind that last post I did not see your code when I made it. I did decided to use another method for all this stuff but I am going to award you the points anyway so it's not a complete waste of time.
procedure TForm1.Button1Click(Sender : TObject);
var
I: Integer;
J: Integer;
S: string;
const
N = 2;
NN = 9;
begin
Randomize;
TreeView1.Items.Clear;
ListBox1.Clear;
with TreeView1 do
begin
for I := 0 to N do
begin
S := IntToStr(I);
ListBox1.Items.Add(S);
Items.AddObject(nil, S + '.txt', TObject(ListBox1.Items[I]) );
Create_File(I, S + '.txt');
end;
for J := N+1 to NN do
begin
I := Random(TreeView1.Items.Cou nt-1);
S := IntToStr(J);
ListBox1.Items.Add(S);
Items.AddChildObject(Items [I], S + '.txt', TObject(ListBox1.Items[J]) );
Create_File(J, S + '.txt');
end;
end;
end;
procedure TForm1.Button2Click(Sender : TObject);
var
I: Integer;
L: Integer;
M: Integer;
begin
M := 0;
for I := 0 to TreeView1.Items.Count-1 do
RecArr[I].Count := 0;
for I := 0 to TreeView1.Items.Count-1 do
begin
L := TreeView1.Items[I].Level;
if (M<L) then
M := L;
RecArr[L].Count := RecArr[L].Count + 1;
end;
Memo1.Clear;
for I := 0 to M do
Memo1.Lines.Add('Level ' + IntToStr(I) + '; Count = ' + IntToStr(RecArr[I].Count)) ;
end;
emil
var
I: Integer;
J: Integer;
S: string;
const
N = 2;
NN = 9;
begin
Randomize;
TreeView1.Items.Clear;
ListBox1.Clear;
with TreeView1 do
begin
for I := 0 to N do
begin
S := IntToStr(I);
ListBox1.Items.Add(S);
Items.AddObject(nil, S + '.txt', TObject(ListBox1.Items[I])
Create_File(I, S + '.txt');
end;
for J := N+1 to NN do
begin
I := Random(TreeView1.Items.Cou
S := IntToStr(J);
ListBox1.Items.Add(S);
Items.AddChildObject(Items
Create_File(J, S + '.txt');
end;
end;
end;
procedure TForm1.Button2Click(Sender
var
I: Integer;
L: Integer;
M: Integer;
begin
M := 0;
for I := 0 to TreeView1.Items.Count-1 do
RecArr[I].Count := 0;
for I := 0 to TreeView1.Items.Count-1 do
begin
L := TreeView1.Items[I].Level;
if (M<L) then
M := L;
RecArr[L].Count := RecArr[L].Count + 1;
end;
Memo1.Clear;
for I := 0 to M do
Memo1.Lines.Add('Level ' + IntToStr(I) + '; Count = ' + IntToStr(RecArr[I].Count))
end;
emil
ASKER