Recent

Author Topic: TShellListView  (Read 2066 times)

Aruna

  • Hero Member
  • *****
  • Posts: 813
TShellListView
« on: November 24, 2025, 03:59:37 pm »
Hello everyone,

I’m working on a very simple utility to back up my files. The expected workflow is:
  • I launch my Lazarus application.
  • I plug in a USB stick or SD card.
  • The app automatically detects the newly plugged-in device.
  • From there, I decide what to copy.
I’ve successfully implemented steps 1 through 3. My question now is about improving two things:

1. Auto-detecting removable devices
My current device-detection code works, but I suspect there may be a cleaner or more reliable method. If anyone knows a better approach, I’d appreciate the advice.

2. Adding columns to TShellListView
The TShellListView shows only three columns by default: Name, Size, and Type. I haven’t been able to add columns like Date, Time, Owner, or Last Modified.
Is it possible to extend TShellListView to show additional file metadata without too much trouble?

I’ve attached a small demo project. Please start the program first, then plug in your USB device to see the detection in action. This is still an early prototype and far from perfect, but I wanted to ask for guidance before going further.

Thank you!

EDIT: This is currently Linux only!

wp

  • Hero Member
  • *****
  • Posts: 13622
Re: TShellListView
« Reply #1 on: November 24, 2025, 05:02:51 pm »
The TShellListView shows only three columns by default: Name, Size, and Type. I haven’t been able to add columns like Date, Time, Owner, or Last Modified.
Is it possible to extend TShellListView to show additional file metadata without too much trouble?
It is assumed at various places in the code that there are exactly these three columns. Since the affected methods are not virtual it appears quite difficult to me how more columns could be added by the application developer. On the other hand, I think it should not be too difficult to generalize the column handling in the class such that additional columns can allowed. Please file a bug report (feature request), maybe somebody wants to extend the TShellListView in this direction.

Aruna

  • Hero Member
  • *****
  • Posts: 813
Re: TShellListView
« Reply #2 on: November 24, 2025, 06:01:37 pm »
The TShellListView shows only three columns by default: Name, Size, and Type. I haven’t been able to add columns like Date, Time, Owner, or Last Modified.
Is it possible to extend TShellListView to show additional file metadata without too much trouble?
It is assumed at various places in the code that there are exactly these three columns. Since the affected methods are not virtual it appears quite difficult to me how more columns could be added by the application developer. On the other hand, I think it should not be too difficult to generalize the column handling in the class such that additional columns can allowed. Please file a bug report (feature request), maybe somebody wants to extend the TShellListView in this direction.
Hi @wp, I submitted a feature request here: Feature Request for TShellListView.

wp

  • Hero Member
  • *****
  • Posts: 13622
Re: TShellListView
« Reply #3 on: November 27, 2025, 10:14:55 pm »
In the new version of TShellListview in Laz/main you have access to the Columns property and can add/delete columns. Using an column ID property you can display the elemental TSearchRec elements to a column, using the CustomID property (when ID = cidCustom) you can display any information via a handler to the OnGetCellText event.

Aruna

  • Hero Member
  • *****
  • Posts: 813
Re: TShellListView
« Reply #4 on: November 28, 2025, 01:42:54 pm »
In the new version of TShellListview in Laz/main you have access to the Columns property and can add/delete columns. Using an column ID property you can display the elemental TSearchRec elements to a column, using the CustomID property (when ID = cidCustom) you can display any information via a handler to the OnGetCellText event.
Hi @wp, I am very grateful and thankful for the work you’ve put into adding and fine-tuning the feature that allows adding custom columns to the TShellListView.

I honestly didn’t realize that all the *.po translation files would also need to be updated, which I now understand is a significant amount of work. I’m extremely happy that the feature I requested is being implemented, but I’m also very sorry for causing you so much additional effort. Thank you again for your patience and dedication. I was frankly quite surprised to see my feature request being implemented so fast. Thank you all for everything you guys do!

Aruna

  • Hero Member
  • *****
  • Posts: 813
Re: TShellListView
« Reply #5 on: November 28, 2025, 03:07:49 pm »
In the new version of TShellListview in Laz/main you have access to the Columns property and can add/delete columns. Using an column ID property you can display the elemental TSearchRec elements to a column, using the CustomID property (when ID = cidCustom) you can display any information via a handler to the OnGetCellText event.
A very small token of our appreciation for what you all do. Sketch is attached!

Ed78z

  • Jr. Member
  • **
  • Posts: 56
Re: TShellListView
« Reply #6 on: November 29, 2025, 06:07:38 am »
...................
2. Adding columns to TShellListView
The TShellListView shows only three columns by default: Name, Size, and Type. I haven’t been able to add columns like Date, Time, Owner, or Last Modified.
Is it possible to extend TShellListView to show additional file metadata without too much trouble?
...................

Aruna, I saw that your program is not Windows... However, if you switch to Windows, I can share my own TQFileListView custom component, it supports add/remove columns easily....

download demo:
https://drive.google.com/drive/folders/11Q1DPsEUJ8wMdlwjZt_o3qAHpZS4EFjj

Code: Pascal  [Select][+][-]
  1. unit MainForm;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Windows, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   ExtCtrls, Buttons, ComCtrls, ShellApi,
  10.   QFileListView;
  11.  
  12. type
  13.  
  14.   { TFormMain }
  15.   TFormMain = class(TForm)
  16.       BtnBrowse: TButton;
  17.       BtnRefresh: TButton;
  18.       BtnParent: TButton;
  19.       CheckShowHidden: TCheckBox;
  20.       EditPath: TEdit;
  21.       LabelPath: TLabel;
  22.       LabelViewMode: TLabel;
  23.       PanelTop: TPanel;
  24.       PanelControls: TPanel;
  25.       PanelViewMode: TPanel;
  26.       ComboBox1: TComboBox;
  27.       procedure BtnBrowseClick(Sender: TObject);
  28.       procedure BtnParentClick(Sender: TObject);
  29.       procedure BtnRefreshClick(Sender: TObject);
  30.       procedure CheckShowHiddenClick(Sender: TObject);
  31.       procedure EditPathKeyPress(Sender: TObject; var Key: char);
  32.       procedure FormCreate(Sender: TObject);
  33.       procedure ComboBox1Change(Sender: TObject);
  34.     private
  35.     FFileListView: TQFileListView;
  36.     FUpdatingView: Boolean;
  37.     procedure FileListViewDblClick(Sender: TObject);
  38.     procedure FileListViewViewModeChanged(Sender: TObject);
  39.   public
  40.  
  41.   end;
  42.  
  43. var
  44.   FormMain: TFormMain;
  45.  
  46. implementation
  47.  
  48. {$R *.lfm}
  49.  
  50. { TFormMain }
  51.  
  52. procedure TFormMain.FormCreate(Sender: TObject);
  53. begin
  54.   Caption := 'TQFileListView Demo';
  55.   Width := 900;
  56.   Height := 600;
  57.   Position := poScreenCenter;
  58.   FUpdatingView := False;
  59.  
  60.   // Create the TQFileListView component
  61.   FFileListView := TQFileListView.Create(Self);
  62.   FFileListView.Parent := Self;
  63.   FFileListView.Align := alClient;
  64.   FFileListView.Directory := GetCurrentDir;
  65.   FFileListView.ShowHidden := CheckShowHidden.Checked;
  66.   FFileListView.AllowColumnReorder := True;
  67.   FFileListView.MultiSelect:=True;
  68.   FFileListView.OnDblClick := @FileListViewDblClick;
  69.   FFileListView.OnViewModeChanged := @FileListViewViewModeChanged;
  70.   EditPath.Text := GetCurrentDir;
  71.  
  72.   ComboBox1.DropDownCount:=20;
  73.   with ComboBox1.Items do
  74.   begin
  75.     AddObject('Medium Icons (32)', TObject(PtrInt(qflVIEW_ICON)));
  76.     AddObject('Small Icons  (16)', TObject(PtrInt(qflVIEW_SMALL_ICON)));
  77.     AddObject('List'             , TObject(PtrInt(qflVIEW_LIST)));
  78.     AddObject('Details'          , TObject(PtrInt(qflVIEW_REPORT)));
  79.     AddObject(''                 , TObject(PtrInt(99)));
  80.     AddObject('Large Icons  (48)', TObject(PtrInt(qflVIEW_48 )));
  81.     AddObject('Large Icons  (64)', TObject(PtrInt(qflVIEW_64 )));
  82.     AddObject('Large Icons  (80)', TObject(PtrInt(qflVIEW_80 )));
  83.     AddObject('Large Icons  (96)', TObject(PtrInt(qflVIEW_96 )));
  84.     AddObject('Large Icons (112)', TObject(PtrInt(qflVIEW_112)));
  85.     AddObject('Large Icons (128)', TObject(PtrInt(qflVIEW_128)));
  86.     AddObject('Large Icons (144)', TObject(PtrInt(qflVIEW_144)));
  87.     AddObject('Large Icons (160)', TObject(PtrInt(qflVIEW_160)));
  88.     AddObject('Large Icons (176)', TObject(PtrInt(qflVIEW_176)));
  89.     AddObject('Large Icons (192)', TObject(PtrInt(qflVIEW_192)));
  90.     AddObject('Large Icons (256)', TObject(PtrInt(qflVIEW_256)));
  91.   end;
  92.  
  93.   FUpdatingView := True;
  94.   try
  95.     ComboBox1.ItemIndex := 3;
  96.     ComboBox1Change(ComboBox1);
  97.   finally
  98.     FUpdatingView := False;
  99.   end;
  100. end;
  101.  
  102. procedure TFormMain.ComboBox1Change(Sender: TObject);
  103. var
  104.   ViewValue: Integer;
  105. begin
  106.   if FUpdatingView then Exit;
  107.   if ComboBox1.ItemIndex >= 0 then
  108.   begin
  109.     FUpdatingView := True;
  110.     try
  111.       ViewValue := PtrInt(ComboBox1.Items.Objects[ComboBox1.ItemIndex]);
  112.       FFileListView.ActualViewIndex := ViewValue;
  113.     finally
  114.       FUpdatingView := False;
  115.     end;
  116.   end;
  117. end;
  118.  
  119.  
  120. procedure TFormMain.BtnBrowseClick(Sender: TObject);
  121. var
  122.   Directory: string;
  123. begin
  124.   if Assigned(FFileListView) then
  125.     Directory := FFileListView.Directory
  126.   else
  127.     Directory := GetCurrentDir;
  128.  
  129.   if SelectDirectory('Select Directory', '', Directory) then
  130.   begin
  131.     EditPath.Text := Directory;
  132.     if Assigned(FFileListView) then
  133.       FFileListView.Directory := Directory;
  134.   end;
  135. end;
  136.  
  137. procedure TFormMain.BtnRefreshClick(Sender: TObject);
  138. begin
  139.   FFileListView.Refresh;
  140. end;
  141.  
  142. procedure TFormMain.BtnParentClick(Sender: TObject);
  143. var
  144.   ParentDir: string;
  145. begin
  146.   ParentDir := ExtractFileDir(ExcludeTrailingPathDelimiter(FFileListView.Directory));
  147.   if (ParentDir <> '') and DirectoryExists(ParentDir) then
  148.   begin
  149.     FFileListView.Directory := ParentDir;
  150.     EditPath.Text := ParentDir;
  151.   end;
  152. end;
  153.  
  154. procedure TFormMain.CheckShowHiddenClick(Sender: TObject);
  155. begin
  156.   FFileListView.ShowHidden := CheckShowHidden.Checked;
  157. end;
  158.  
  159. procedure TFormMain.EditPathKeyPress(Sender: TObject; var Key: char);
  160. begin
  161.   if Key = #13 then // Enter key
  162.   begin
  163.     Key := #0; // Consume the key
  164.     if DirectoryExists(EditPath.Text) then
  165.     begin
  166.       FFileListView.Directory := EditPath.Text;
  167.     end
  168.     else
  169.     begin
  170.       ShowMessage('Directory does not exist: ' + EditPath.Text);
  171.       EditPath.Text := FFileListView.Directory;
  172.     end;
  173.   end;
  174. end;
  175.  
  176.  
  177. procedure TFormMain.FileListViewDblClick(Sender: TObject);
  178. var
  179.   FullPath: string;
  180. begin
  181.   if FFileListView.Selected <> nil then
  182.   begin
  183.     FullPath := IncludeTrailingPathDelimiter(FFileListView.Directory) +
  184.                 FFileListView.GetSelectedFileName;
  185.  
  186.     if {%H-}PtrInt(FFileListView.Selected.Data) = -1 then
  187.     begin
  188.       if DirectoryExists(FullPath) then
  189.       begin
  190.         FFileListView.Directory := FullPath;
  191.         EditPath.Text := FullPath;
  192.       end;
  193.     end
  194.     else
  195.     begin
  196.       ShellExecute(Handle, 'open', PChar(FullPath), nil, nil, SW_SHOWNORMAL);
  197.     end;
  198.   end;
  199. end;
  200.  
  201. procedure TFormMain.FileListViewViewModeChanged(Sender: TObject);
  202. var
  203.   i: Integer;
  204.   CurrentMode: Integer;
  205. begin
  206.   if FUpdatingView then Exit;
  207.   CurrentMode := FFileListView.ActualViewIndex;
  208.   FUpdatingView := True;
  209.   try
  210.     for i := 0 to ComboBox1.Items.Count - 1 do
  211.     begin
  212.       if PtrInt(ComboBox1.Items.Objects[i]) = CurrentMode then
  213.       begin
  214.         ComboBox1.ItemIndex := i;
  215.         Break;
  216.       end;
  217.     end;
  218.   finally
  219.     FUpdatingView := False;
  220.   end;
  221. end;
  222.  
  223.  
  224. end.
« Last Edit: December 10, 2025, 03:52:58 am by Ed78z »

BrunoK

  • Hero Member
  • *****
  • Posts: 766
  • Retired programmer
Re: TShellListView
« Reply #7 on: November 29, 2025, 04:44:48 pm »

Aruna, I saw that your program is not Windows... However, if you switch to Windows, I can share my own TQFileListView custom component, it supports add/remove columns easily....
Looks interesting. Is TQFileListView class downloadable or is it proprietary thus unusable ?

Ed78z

  • Jr. Member
  • **
  • Posts: 56
Re: TShellListView
« Reply #8 on: November 30, 2025, 09:07:51 pm »

Aruna, I saw that your program is not Windows... However, if you switch to Windows, I can share my own TQFileListView custom component, it supports add/remove columns easily....
Looks interesting. Is TQFileListView class downloadable or is it proprietary thus unusable ?

Brunok, I am trying to find a solution to share my entire "TQ Control" package in addition to the TDWEdit component completely free. https://forum.lazarus.freepascal.org/index.php/topic,72546.0.html
I'll share it as soon as find an easy solution to share them all free

Aruna

  • Hero Member
  • *****
  • Posts: 813
Re: TShellListView
« Reply #9 on: December 01, 2025, 03:26:38 am »
...................
2. Adding columns to TShellListView
The TShellListView shows only three columns by default: Name, Size, and Type. I haven’t been able to add columns like Date, Time, Owner, or Last Modified.
Is it possible to extend TShellListView to show additional file metadata without too much trouble?
...................

Aruna, I saw that your program is not Windows... However, if you switch to Windows, I can share my own TQFileListView custom component, it supports add/remove columns easily....

Ed78z, Thanks for the offer! 😄 I can always fire up a Windows machine to test, so yes please do share your TQFileListView component. I’d love to take a look and give it a spin!

Ed78z

  • Jr. Member
  • **
  • Posts: 56
Re: TShellListView
« Reply #10 on: June 10, 2026, 07:59:41 pm »
So, I’ve been super busy the last couple of months. This component is already 95% done. If you’d like to use it, give it a try.
« Last Edit: June 11, 2026, 08:05:57 pm by Ed78z »

 

TinyPortal © 2005-2018