add a column to TshellListView? lazarus / 7-LCL ---------------------------------------------------------------------- kormoran · 2015-04-04 13:51 Hello, I need to calc a value for each file in a directory and show it. TShellListView would be perfect, IF I could add another column to it... but I can't find a way. Can this be (easily) done or do I need to derive from TCustomShellListView and make my own? Thanks  (edit: OOPS wrong board... plz move to Lazarus->Programming->LCL) ---------------------------------------------------------------------- typo · 2015-04-04 17:40 Code: [Select]  ShellListView1.Columns.Add;   ShellListView1.Column[ShellListView1.ColumnCount - 1].Caption := 'abc';  You need to derive from TShellListView or TCustomShellListView and make property Columns public. Or make a Feature Request in BugTracker in order to make it public on TCustomListView source (since Column and ColumnCount are public too). ---------------------------------------------------------------------- howardpc · 2015-04-04 18:23 Here's an example of one way to achieve this. Code: [Select]unit Unit1; {$mode objfpc}{$H+} interface uses   Classes, SysUtils, Forms, Controls, ShellCtrls, ComCtrls; type   { TShellListViewEx }   TShellListViewEx = class(TShellListView)   private     FNewColumn: TListColumn;     FNewColumnCaption: string;     function FileStringFunction(const aFilePath: string): string; // supply your file processing logic here     procedure PopulateWithRootEx;   public     constructor CreateEx(AOwner: TComponent; const anExtraColumn: string);     property ExColumnCaption: string read FNewColumnCaption;   end;   { TForm1 }   TForm1 = class(TForm)     procedure FormCreate(Sender: TObject);     procedure FormDestroy(Sender: TObject);   private     slvEx: TShellListViewEx;   end; var   Form1: TForm1; implementation uses LazLogger; {$R *.lfm} { TShellListViewEx } function TShellListViewEx.FileStringFunction(const aFilePath: string): string; begin   if FileIsReadOnly(aFilePath) then     Result:='ReadOnly'   else Result:='Writeable'; end; procedure TShellListViewEx.PopulateWithRootEx; var   Files: TStringList;   i: integer;   li: TListItem;   curFilePath, filePath: string; begin   inherited PopulateWithRoot;   if (csDesigning in ComponentState) then Exit;   if Trim(Root) = '' then Exit;   Files := TStringList.Create;   try     TCustomShellTreeView.GetFilesInDir(Root, Mask, ObjectTypes, Files);     curFilePath:=IncludeTrailingPathDelimiter(Root);     for i := 0 to Files.Count - 1 do     begin       li:=Items.FindCaption(0,Files[i],False,True,true);       if (li <> nil) then begin         filePath:=curFilePath + Files[i];         li.SubItems.Add(FileStringFunction(filePath));       end       else DebugLn('Filename %s was not in items list',[Files[i]]);     end;   finally     Files.Free;   end; end; constructor TShellListViewEx.CreateEx(AOwner: TComponent;   const anExtraColumn: string); begin   inherited Create(AOwner);   FNewColumn:=Columns.Add;   FNewColumn.Caption:=anExtraColumn;   Root:='C:\';                      // customise these properties appropriately   Mask:='*.*';   ObjectTypes:=[otFolders, otNonFolders];   PopulateWithRootEx; end; { TForm1 } procedure TForm1.FormCreate(Sender: TObject); begin   slvEx:=TShellListViewEx.CreateEx(Self, 'Readonly attribute');   slvEx.Align:=alClient;   slvEx.Parent:=Self; end; procedure TForm1.FormDestroy(Sender: TObject); begin   FreeAndNil(slvEx); end; end. ---------------------------------------------------------------------- kormoran · 2015-04-04 21:05 Thank you guys, excellent answers. (Sorry for posting in the wrong place) ---------------------------------------------------------------------- typo · 2015-04-04 22:02 Making a Feature Request should result, see TCustomListView source: Code: [Select] TShellListView = class(TCustomShellListView)   published     { TCustomListView properties       The same as TListView excluding data properties }     property Align;     property Anchors;     property BorderSpacing;     property BorderStyle;     property BorderWidth; //    property Checkboxes;     property Color default clWindow; //    property Columns; All they need to do is uncomment that line. ---------------------------------------------------------------------- typo · 2015-04-04 22:17 http://bugs.freepascal.org/view.php?id=27786 ---------------------------------------------------------------------- Bart · 2015-04-04 22:42 There is a reason why it is not published. (See bugreport). Bart ---------------------------------------------------------------------- typo · 2015-04-04 22:49 Surely there is a reasonable reason why he/she should not delete the first 3 columns. ---------------------------------------------------------------------- Bart · 2015-04-04 22:52 Yes, and we like to not "help" people to shoot in their own foot (we're not C). Bart ---------------------------------------------------------------------- typo · 2015-04-05 00:02 Blocking access to Colums property does not seem a very smart solution. Maybe a block to the first 3 would be better. ---------------------------------------------------------------------- Timewarp · 2015-04-05 07:19 If all needed is to publish columns, just add this to project: Code: [Select]type   TShellListView = class(ShellCtrls.TShellListView)     published property Columns;   end; ---------------------------------------------------------------------- typo · 2015-04-05 07:46 I agree. ---------------------------------------------------------------------- Bart · 2015-04-05 08:58 Quote from: typo on April 05, 2015, 02:02:35 amBlocking access to Colums property does not seem a very smart solution. Maybe a block to the first 3 would be better. Yes. Not sure how to do that though. Any ideas? Bart ---------------------------------------------------------------------- typo · 2015-04-05 09:04 First idea: Code: [Select]    procedure AddColumn(ACaption :string);     procedure DeleteColumn(AIndex :integer); {...} procedure TCustomShellListView.AddColumn(ACaption :string); begin   Columns.Add;   Column[ColumnCount - 1].Caption := ACaption; end; procedure TCustomShellListView.DeleteColumn(AIndex :integer); begin   if AIndex > 2 then     Columns.Delete(AIndex); end; ---------------------------------------------------------------------- Bart · 2015-04-05 09:24 Still leaves the possibility to do Code: [Select]  ShellListView1.Columns.Delete(0); (If Columns were to be published.) While it is possible to replace TTreeNode with a subclass (which I have done), such a mechanisme is not provided for columns. But just introducing AddColumn and DeleteColumn might be a feasible idea. Bart ---------------------------------------------------------------------- typo · 2015-04-05 09:27 Quote from: Bart on April 05, 2015, 11:24:21 amStill leaves the possibility to do Code: [Select]  ShellListView1.Columns.Delete(0); (If Columns were to be published.) In this case don't publish them. No need to do so if AddColumn and DeleteColumn are used. ---------------------------------------------------------------------- Bart · 2015-04-05 09:31 Does anybody know if Delphi publishes TShellListView.Columns? If not, do they have a method of adding/deleting columns? If yes, can you delete all columns? While our implementation is far from D compatible, if we implement such a thing, we might try to follow (black box aproach) the Greek. Bart ---------------------------------------------------------------------- typo · 2015-04-05 11:55 I only found this in C++: http://godcom.googlecode.com/svn/trunk/ShellControls/ShellCtrls.hpp And it publics Columns. Code: [Select]public: __fastcall virtual TCustomShellListView(Classes::TComponent* AOwner); __fastcall virtual ~TCustomShellListView(void); void __fastcall Back(void); HIDESBASE void __fastcall Refresh(void); TShellFolder* __fastcall SelectedFolder(void); __property TShellFolder* Folders[int Index] = {read=GetFolder}; __property TShellFolder* RootFolder = {read=FRootFolder}; __property Items; __property Columns; I also found this unit, apparently from Delphi, and it does not public Columns. https://github.com/Baltimore99/delphi-drag- drop/blob/master/Demos/DetailedDemo/Extra/ShellCtrls.pas ---------------------------------------------------------------------- taazz · 2015-04-05 14:06 Oh wow, it seems that from delphi 2009 onwards the tshellxxx controls are not part of the default installation and are now published on their sourceforge project as samples on how to create controls that interact with windows shell. http://sourceforge.net/p/radstudiodemos/c ode/HEAD/tree/branches/RadStudio_XE6/Object%20Pascal/VCL/ShellControls / EDIT: sorry forgot that the columns seem to be public. ---------------------------------------------------------------------- typo · 2015-04-05 14:23 Code: [Select]public     constructor Create(AOwner: TComponent); override;     destructor Destroy; override;     procedure Back;     procedure Refresh;     function SelectedFolder: TShellFolder;     property Folders[Index: Integer]: TShellFolder read GetFolder;     property RootFolder: TShellFolder read FRootFolder;     property Items;     property Columns; Yes, thanks. So, yes, Delphi publics Columns. ---------------------------------------------------------------------- Bart · 2015-04-05 16:45 Quote from: typo on April 05, 2015, 04:23:27 pmSo, yes, Delphi publics Columns. I made them public. Bart