Solved

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

Posted on 2009-05-20
5
313 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

919 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now