Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

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

Posted on 2009-05-20
5
Medium Priority
?
335 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 2000 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

Ask an Anonymous Question!

Don't feel intimidated by what you don't know. Ask your question anonymously. It's easy! Learn more and upgrade.

Question has a verified solution.

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

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
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…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses

886 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