Hi sfeinst/KpjComp,
I got it working last night. I went with a TStringList to store the GUIDs.
procedure TTreeListForm.LoadFromQuery(var TV: TTreeView; const DS: TDataSet; const TN: TTreeNode;
const F: array of string; const L: array of byte);
// The arrarys above are zero offset
const
CB: array[0..2] of byte = (%100,%10,%1); //Binary 100, 10, 1
var
I: integer; //Index of recently added TGUIDStrings
C: byte; //Case value
begin
// It should be noted that loop invariants checks for F1 thru F3 now reside
// outside the while loop. Doing this should make the while loop more efficient.
// I'm concerned that if the data sets grow too large, this could slow down the
// tree building. The case statement gets rid of all the if/then/else logic
// and makes it a two step process. Jump to correct 'C' value and add string
// to tree.
C := 0;
for I := 0 to 2 do
if F[I] <> '' then C := C + CB[I]; //Figure out which fields are needed to build string
DS.Active := false;
DS.Active := true; //Refresh DataSet
DS.First; //Retrieve 1st record
while not DS.EOF do //Loop until we hit End Of File
begin
I := GUIDStrings.Add(DS.FieldByName('KID').AsString);
case C of //Build String and Add string as child of node, TN
%100: TV.Items.AddChildObject(TN,LeftStr(DS.FieldByName(F[0]).AsString,L[0]),
pointer(GUIDStrings.Strings[I]));
%010: TV.Items.AddChildObject(TN,LeftStr(DS.FieldByName(F[1]).AsString,L[1]),
pointer(GUIDStrings.Strings[I]));
%001: TV.Items.AddChildObject(TN,LeftStr(DS.FieldByName(F[2]).AsString,L[2]),
pointer(GUIDStrings.Strings[I]));
%110: TV.Items.AddChildObject(TN,LeftStr(DS.FieldByName(F[0]).AsString,L[0])+'/'
+LeftStr(DS.FieldByName(F[1]).AsString,L[1]),
pointer(GUIDStrings.Strings[I]));
%101: TV.Items.AddChildObject(TN,LeftStr(DS.FieldByName(F[0]).AsString,L[0])+'/'
+LeftStr(DS.FieldByName(F[2]).AsString,L[2]),
pointer(GUIDStrings.Strings[I]));
%011: TV.Items.AddChildObject(TN,LeftStr(DS.FieldByName(F[1]).AsString,L[1])+'/'
+LeftStr(DS.FieldByName(F[2]).AsString,L[2]),
pointer(GUIDStrings.Strings[I]));
%111: TV.Items.AddChildObject(TN,LeftStr(DS.FieldByName(F[0]).AsString,L[0])+'/'
+LeftStr(DS.FieldByName(F[1]).AsString,L[1])+'/'
+LeftStr(DS.FieldByName(F[2]).AsString,L[2]),
pointer(GUIDStrings.Strings[I]));
otherwise TV.Items.AddChildObject(TN,'',pointer(GUIDStrings.Strings[I]))
end;
DS.Next //Retrieve next record in DataSet
end
end;
It greatly simplified my code through the unit. As an example, before I was storing the GUID in a child node that had to betrieved with extra steps:
procedure TTreeListForm.MenuItemModInvestorClick(Sender: TObject);
var
N: TTreeNode;
begin
//Level KIDLevel is where the KID is stored. If its missing, then we have real issues
//When entering here, we are either on Level 1 or 2, not zero.
N := HMLTV.Selected;
while N.HasChildren and (N.Level < KIDLevel) do
N := N.GetFirstChild;
if N.Level = KIDLevel then
begin
with RefInvestorsEditEntryForm do
begin
EditEntryMode := eeModify;
InvestorID := RightStr(N.Text, TGUIDStrLen);
ShowModal
end;
BuildTreeList
end
end;
Now it looks like this:
procedure TTreeListForm.MenuItemModInvestorClick(Sender: TObject);
begin
with RefInvestorsEditEntryForm do
begin
EditEntryMode := eeModify;
InvestorID := PChar(HMLTV.Selected.Data);
ShowModal
end;
BuildTreeList
end;
Thanks for you help.
KpjComp, I will look at your proposed solution when I free up some time. It looks interesting. I just more comfortable of a TStringList.
Thanks
Knipfty