Solved

Displaying all content in a treeview instead of a treeview listview display

Posted on 2009-05-20
5
314 Views
Last Modified: 2012-05-07
Hello all,
I am using the component WMISet to retrieve the Group Policy of a computer, the component came with a demo showing you how to do it... but it uses a listview in conjunction with a treeview to display the GRoup Policy. And I have been trying to get rid of the listview and keep all the displayed information in the treeview. Rights now the treeview displays the folder structure, and the listview displays the subfolder/file/item info. I want everything to be displayed in the treeview and get rid of the listview ll together.

Reason why, is I want to be able save all the information to an xml file or clientdataset. And I thought it would be easier to do that if I only had to deal with one component instead of two.

Anyways I have not been able to figure out the treeview to get to to display the file/item info in the treeview along with the folder structure. Most of the code is below:

tvCategories = the treeview
lvPolicies = listview

remove the listview completely, and just use the treeview
tia
Frank



procedure TFormMain.LoadGpoData;
var
  vWasCursor: TCursor;
begin
  vWasCursor := Screen.Cursor;
  Screen.Cursor := crHourGlass; 
  try
    LoadCategoryTree;
    LoadLinks;
    UpdateCaption;
    SetButtonStates;
  finally
    Screen.Cursor := vWasCursor;
  end;
end;
 
procedure TFormMain.LoadCategoryTree;
var
  vList: TStringList;
  vPolicy: TNTRegistryPolicy;
  i: integer;
begin
  tvCategories.Items.Clear;
  vList := TStringList.Create;
  try
    GroupPolicy.ListRegistryPolicies(vList);
    FUserPolicies.Clear;
    FMachinePolicies.Clear;
    for i := 0 to vList.Count - 1 do
    begin
      Application.ProcessMessages;
      vPolicy := TNTRegistryPolicy(vList.Objects[i]);
      if vPolicy.Section = secUser then
        FUserPolicies.AddObject(vPolicy.Category, vPolicy)
          else FMachinePolicies.AddObject(vPolicy.Category, vPolicy)
    end;
 
    FMachineRoot := tvCategories.Items.Add(nil, COMPUTER_CONFIG);
    FUserRoot := tvCategories.Items.Add(nil, USER_CONFIG);
    LoadTreeBranch(FMachineRoot, FMachinePolicies);
    LoadTreeBranch(FUserRoot, FUserPolicies);
  finally
    vList.Free;
  end;
end;
 
procedure TFormMain.LoadLinks;
var
  i: integer;
  vItem: TListItem;
  vLink: TNTGpoLink;
begin
  lvLinks.Items.Clear;
  pnlLinksMessage.Visible := GroupPolicy.GpoType <> GPOTypeDS;
  pnlLinks.Visible := not pnlLinksMessage.Visible;
  if GroupPolicy.GpoType = GPOTypeDS then
  for i := 0 to GroupPolicy.GpoLinks.Count - 1 do
  begin
    Application.ProcessMessages;
    vLink := GroupPolicy.GpoLinks[i];
    vItem := lvLinks.Items.Add;
    vItem.Caption := vLink.ContainerName;
    vItem.SubItems.Add(BooleanToStr((vLink.Options and GPOLINK_DISABLED) <> 0));
    vItem.SubItems.Add(BooleanToStr((vLink.Options and GPOLINK_NO_OVERRIDE) <> 0));
  end;
end;
 
procedure TFormMain.UpdateCaption;
begin
  Caption := GROUP_POLICY_EDITOR + ': ' + GroupPolicy.GpoDisplayName;
end;
 
procedure TFormMain.SetButtonStates;
begin
  btnRemoveLink.Enabled  := lvLinks.Selected <> nil;
  btnLinkOptions.Enabled := btnRemoveLink.Enabled;
  //tlbDeleteGroup.Enabled := GroupPolicy.GpoType = GPOTypeDS;
end;
 
procedure TFormMain.LoadTreeBranch(ARoot: TTreeNode; APolicies: TStrings);
var
  i: integer;
  vPolicy: TNTRegistryPolicy;
begin
  for i := 0 to APolicies.Count - 1 do
  begin
    vPolicy := TNTRegistryPolicy(APolicies.Objects[i]);
    FindOrCreateCategoryNode(ARoot, vPolicy.Category);
  end;
 
  for i := 0 to tvCategories.Items.Count - 1 do
  begin
    if tvCategories.Items[i].HasChildren then
    begin
      {$IFDEF Delhi6}
      tvCategories.Items[i].AlphaSort(false);
      {$ELSE}
      tvCategories.Items[i].AlphaSort();
      {$ENDIF}
    end;
  end;
 
  ARoot.Expand(false);
end;
 
function TFormMain.FindOrCreateCategoryNode(ARoot: TTreeNode; ACategoryPath: widestring): TTreeNode;
var
  vChildNode: TTreeNode;
  vTokenizer: TNTStringTokenizer;
  vPathElement: widestring;
begin
  vTokenizer := TNTStringTokenizer.Create(ACategoryPath, PATH_SEPARATOR);
  try
    while not vTokenizer.EndOfString do
    begin
      vPathElement := vTokenizer.NextToken;
      vChildNode := FindOrCreateChildByName(ARoot, vPathElement);
      ARoot := vChildNode;
    end;
    Result := ARoot; 
  finally
    vTokenizer.Free;
  end;
end;
 
function TFormMain.FindOrCreateChildByName(ANode: TTreeNode; AName: widestring): TTreeNode;
var
  i: integer;
begin
  Result := nil;
  for i := 0 to ANode.Count - 1 do
    if ANode[i].Text = AName then
    begin
      Result := ANode[i];
      Break;
    end;
 
  if Result = nil then
  begin
    Result := tvCategories.Items.AddChild(ANode, AName);
  end;
end;
 
procedure TFormMain.tvCategoriesChange(Sender: TObject; Node: TTreeNode);
begin
  if (tvCategories.Selected = FUserRoot) or
     (tvCategories.Selected = FMachineRoot)  then
  begin
    lvPolicies.Items.Clear;
    LoadSubCategoriesForCategory
  end else
  begin
    LoadPoliciesForCategory;
  end;
end;
 
procedure TFormMain.tvCategoriesGetImageIndex(Sender: TObject;
  Node: TTreeNode);
begin
  if Node.Expanded then Node.ImageIndex := IMAGE_INDEX_FOLDER_OPEN
    else Node.ImageIndex := IMAGE_INDEX_FOLDER_OPEN;
  Node.SelectedIndex := Node.ImageIndex;
end;
 
procedure TFormMain.LoadSubCategoriesForCategory;
var
  i: integer;
  vItem     : TListItem;
  vNode,xNode     : TTreeNode;
begin
    vNode := tvCategories.Selected;
    for i := 0 to vNode.Count - 1 do
    begin
      vItem := lvPolicies.Items.Add;
      vItem.Caption := vNode.Item[i].Text;
    end;
end;
 
procedure TFormMain.LoadPoliciesForCategory;
var
  vCategory : widestring;
  vSection  : TNTPolicySection;
  vList     : TStrings;
  vPolicy   : TNTRegistryPolicy;
  i: integer;
  vItem     : TListItem;
 
begin
  lvPolicies.Items.Clear;
  GetSelectedCategory(vCategory, vSection);
  if vCategory <> '' then
  begin
    // 1) load sub categories
    LoadSubCategoriesForCategory;
    // 2) Load policies
 
    vList := GetPoliciesForSection(vSection);
    for i := 0 to vList.Count - 1 do
    begin
      vPolicy := TNTRegistryPolicy(vList.Objects[i]);
      if vPolicy.Category = vCategory then
      begin
        vItem := lvPolicies.Items.Add;
 
        vItem.Caption := vPolicy.PolicyName;
        GroupPolicy.RegistryPolicy.PolicyName := vPolicy.PolicyName;
        vItem.SubItems.Add(PolicyStatusToString(GroupPolicy.RegistryPolicy.Status))
      end;
    end;
  end;
end;
 
function TFormMain.GetPoliciesForSection(ASection: TNTPolicySection): TStrings;
begin
  if ASection = secUser then Result := FUserPolicies
    else Result := FMachinePolicies;
end;
 
procedure TFormMain.GetSelectedCategory(out ACategory: widestring;
                                         out ASection: TNTPolicySection);
var
  vNode: TTreeNode;
begin
  ACategory := '';
  ASection  := secUser;
 
  if tvCategories.Selected <> nil then
  begin
    vNode := tvCategories.Selected;
    while vNode.Parent <> nil do
    begin
      if ACategory <> '' then ACategory := '\' + ACategory;
      ACategory := vNode.Text + ACategory;
      vNode := vNode.Parent;
    end;
    if vNode = FUserRoot then ASection := secUser
      else ASection := secMachine;
  end;
 
end;
 
procedure TFormMain.lvPoliciesChange(Sender: TObject; Item: TListItem;
  Change: TItemChange);
var
  vPolicy: TNTRegistryPolicy;
begin
  memHelp.Lines.Clear;
  vPolicy := FindPolicy(lvPolicies.Selected);
  if vPolicy <> nil then
  begin
    memHelp.Lines.Text := FormatHelpString(vPolicy.HelpString);
  end;
end;
procedure TFormMain.lvPoliciesDblClick(Sender: TObject);
begin
  if IsPolicy(lvPolicies.Selected) then EditSelectedPolicy else
  if IsCategory(lvPolicies.Selected) then NavigateToSelectedCategory;
end;
procedure TFormMain.lvPoliciesGetImageIndex(Sender: TObject;
  Item: TListItem);
var
  vIndex: integer;
begin
  if Item.SubItems.Count = 0 then
    vIndex := IMAGE_INDEX_FOLDER_CLOSED
    else vIndex := IMAGE_INDEX_POLICY;
 
  if Item.ImageIndex <> vIndex then
    Item.ImageIndex := vIndex
end;
 
function TFormMain.FindPolicy(AItem: TListItem): TNTRegistryPolicy;
var
  vCategory : widestring;
  vSection  : TNTPolicySection;
  vList     : TStrings;
begin
  Result := nil;
  if AItem <> nil then
  begin
    GetSelectedCategory(vCategory, vSection);
    vList  := GetPoliciesForSection(vSection);
    Result := FindRegistryPolicyByName(vList, AItem.Caption);
  end;  
end;
 
function TFormMain.FindRegistryPolicyByName(AList: TStrings; AName: widestring): TNTRegistryPolicy;
var
  i: integer;
  vPolicy: TNTRegistryPolicy;
begin
  Result := nil;
  for i := 0 to AList.Count - 1 do
  begin
    vPolicy := TNTRegistryPolicy(AList.Objects[i]);
    if vPolicy.PolicyName = AName then
    begin
      Result := vPolicy;
      Exit;
    end;
  end;
end;
 
function TFormMain.FormatHelpString(AString: string): string;
var
  vPos: integer;
begin
  vPos := Pos('\n', AString);
  while vPos > 0 do
  begin
    AString[vPos] := #$0D;
    AString[vPos + 1] := #$0A;
    vPos := Pos('\n', AString);
  end;
  Result := AString;
end;
 
function TFormMain.IsPolicy(AItem: TListItem): boolean;
begin
  Result := (AItem <> nil) and (AItem.SubItems.Count > 0);
end;
 
function TFormMain.IsCategory(AItem: TListItem): boolean;
begin
  Result := (AItem <> nil) and (AItem.SubItems.Count = 0);
end;
 
procedure TFormMain.EditSelectedPolicy;
{var
  vDlg: TFrmEditPolicyDialog;
  vCategory: widestring;
  vSection: TNTPolicySection;}
begin
  {GetSelectedCategory(vCategory, vSection);
  GroupPolicy.RegistryPolicy.Section := vSection;
  GroupPolicy.RegistryPolicy.PolicyName := lvPolicies.Selected.Caption;
  vDlg := TFrmEditPolicyDialog.Create(GroupPolicy);
  try
    if vDlg.ShowModal = mrOk then RefreshPolicies;
  finally
    vDlg.Free;
  end; }
end;
 
{procedure TFormMain.RefreshPolicies;
var
  i: integer;
begin
  GroupPolicy.RegistryPolicy.Refresh;
  for i := 0 to lvPolicies.Items.Count - 1 do
  begin
    if isPolicy(lvPolicies.Items[i]) then
    begin
      GroupPolicy.RegistryPolicy.PolicyName := lvPolicies.Items[i].Caption;
      lvPolicies.Items[i].SubItems[0] := PolicyStatusToString(GroupPolicy.RegistryPolicy.Status);
    end;
  end;
end;  }
 
procedure TFormMain.NavigateToSelectedCategory;
var
  i: integer;
begin
  if (tvCategories.Selected <> nil) and (lvPolicies.Selected <> nil) then
    for i := 0 to tvCategories.Selected.Count - 1 do
      if tvCategories.Selected.Item[i].Text = lvPolicies.Selected.Caption then
      begin
        tvCategories.Selected := tvCategories.Selected.Item[i];
        Exit;
      end;
end;

Open in new window

tv-lv.jpg
0
Comment
Question by:LMuadDIb
  • 3
  • 2
5 Comments
 
LVL 14

Accepted Solution

by:
SteveBay earned 500 total points
ID: 24436088
It seem like it should be as simple as just creating tree nodes instead of ListView items for the policies. Though it's a little tricky because you will still have to make a distinction between tree node that represent SubCategories and and tree nodes that represent Policies.  
When you consider that, you may find that it is less complicated to change your save/load strategy than it is to change your display strategy.
Why do you think that it will simplify storage to have it all presented in one component? The way I see it, your data structure remains the same no matter how you display it.

0
 
LVL 4

Author Comment

by:LMuadDIb
ID: 24436459
hmmmmm
you got me thinking,  theres plenty of code for exporting a treeview out as as xml, and parsing xml seems alot easier (for me anyways) to do then actually trying to parse the treeview and listview at the same time.

maybe I should be looking at it in a different way like you said.
maybe create an xml doc or cds at the same time the data is being inserted into the treeview/listview, and load the data into the xml doc/cds and NOT after the fact. But at the same time.

0
 
LVL 4

Author Comment

by:LMuadDIb
ID: 24454296
SteveBay
Thank you for you answer, it led me to a better approach than what I was thinking previously.
Sense you didnt  answer my question but did help me,  can I give some points (partial-100) and have this this question closed?
0
 
LVL 14

Expert Comment

by:SteveBay
ID: 24454501
You are free to do as you believe is best.
People come to EE for solutions and you have found one. I could have answered your question but would that actually have been the best solution? That's for you to decide. I don't particiapate here because of point's I do it because It helps me expand my skills so it certainly won't ruin my day if you decide to discount this question/solution.

0
 
LVL 4

Author Comment

by:LMuadDIb
ID: 24456153
Your post changed the whole way I looked at my project, and I thank you again.
0

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question