TShellTreeView with CheckBoxes - Custom Delphi TShellTreeView Enhancement
Moving on with the TShellTreeView with CheckBoxes...
The OnCheckChanged event is then triggered. It passes the Node, the State and the list of files to the calling application. This process is repeated each time a node is clicked but the list of files presented to the user is updated each time by adding or removing files in the list..
The process is traightformard:
The second argument is set to faAnyFile that includes hidden files as well as the sub-directories "." and "..". If the search is successful, the file will be added or removed from the list depending on the value of State. If the file was a sub-directory, no action is taken. The search process is then repeated as long as FindNext() returns success. FindClose() is called to terminate the search process when the search has exhausted all the content.
The code for the component is available on this site for download. [lik url=/od/vclusing/ss/installbpld2005.htm]Put it in a package, compile it, install it and use it.
The OnCheckChanged event is then triggered. It passes the Node, the State and the list of files to the calling application. This process is repeated each time a node is clicked but the list of files presented to the user is updated each time by adding or removing files in the list..
Producing the list of files
As noted above, the enumeration of the files contained in the selected directories is performed using the EnumFiles() private method.The process is traightformard:
procedure TGtroCustomCheckShellTreeView.EnumFiles(ANode: TTreeNode; State: Boolean; var List: TStringList) ; var   Path: string;   Data: TSearchRec;   ds: longint; begin   Path:= GetNodePath(ANode) ;   ds:= FindFirst(Path + '\*.*', faAnyFile, data) ; // Fetch the first file   while ds = 0 do// continue as long as the result is successfull   begin     if (Data.Attr and faDirectory <> faDirectory) then// don't bother with directories       if State then         List.Add(Path + '\' + Data.Name) // add to the list       else         List.Delete(List.IndexOf(Path + '\' + Data.Name)) ; // delete from the list     ds:= FindNext(Data) ;   end;   FindClose(Data) ;   end; end;
The EnumFiles() method takes the Node, the state of the node (checked or unchecked) as input arguments and produces the list of files by using successive calls to the FindFirst(), FindNext() and FindClose() functions from SysUtils.pas. FindFirst() uses the path to the directory in order to define the pattern that is used to search for the first instance of a file name with a given set of attributes in a specified directory.The second argument is set to faAnyFile that includes hidden files as well as the sub-directories "." and "..". If the search is successful, the file will be added or removed from the list depending on the value of State. If the file was a sub-directory, no action is taken. The search process is then repeated as long as FindNext() returns success. FindClose() is called to terminate the search process when the search has exhausted all the content.
Saving and reloading selections
Most backup programs offer the capability of saving selections of files for future backups. The component was modified recently to add this capability: the selection of files can be saved to a file as patterns. In fact, when the user clicks on a check box next to a node in the component, a pattern (the path associated with the node) is generated and added to the private variable FPatterns (a stringlist). If the node was collapsed when the check box was clicked, it indicates that all the files in the corresponding directory and all of its subfolders are selected. In this case, the symbol "/s" is appended to the pattern. The SaveToFile() method saves this list of patterns as follows.procedure TGtroCustomCheckShellTreeView.SaveToFile(FileName: string) ; begin   FPatterns.SaveToFile(FileName) ; end;
In addition, the user can recall a selection of file saved during a previous backup using the LoadFromFile() public method of the component. During this procedure, the list of patterns is extracted from a text file through the LoadFromFile() method of TStringList. If the pattern is appended with "/s" then the variable IncludeSubs is set to true whereas the path of the folder (the pattern) is used to determine which node of the three corresponds to the path. This research is performed by the GetNodeFromPath() method. procedure TGtroCustomCheckShellTreeView.LoadFromFile(FileName: string) ; var   c: Integer;   Pattern: string;   ANode: TTreeNode;   OldState: Boolean;   IncludeSubs: Boolean;   FPatterns: TStringList; begin   FPatterns:= TStringlist.Create; // Create a local list of patterns   LockWindowUpdate(Handle) ; // prevents flicker   try     FPatterns.LoadFromFile(FileName) ; // Read patterns from file     for c:= 0 to FPatterns.Count - 1 do// scan all patterns     begin       // Check for inclusion of subdirectories (Patern terminaison = "/s")       Pattern:= FPatterns[c];       IncludeSubs := Pos('/s', Pattern) > 0;       // remove terminaison "/s"       if IncludeSubs then Pattern:= Copy(Pattern, 0, Length(Pattern) - 2) ;       ANode:= GetNodeFromPath(Pattern) ; // returns the node or nil       ifNOT Assigned(ANode) then// Node has been found       begin         if not IncludeSubs then ANode.Collapse(False) ;         OldState:= IsNodeChecked(ANode) ; // Check status of node         // Produce the list of files         CheckIt(ANode, IncludeSubs, not OldState) ;       end;     end;   finally     FPatterns.Free;     LockWindowUpdate(0) ;   end; end;
Conclusion
Since users can select any set of nodes to produce a list of files and that such selection can be fairly complex, the capability of saving a selection to a file and re-enacting it by reloading the file has been implemented.The code for the component is available on this site for download. [lik url=/od/vclusing/ss/installbpld2005.htm]Put it in a package, compile it, install it and use it.
Source...