Datum in ShellListView
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Datum in ShellListView
Ist es möglich, in der ShellListView das Edit- oder Erstellungsdatum mit anzeigen zu lassen?
Wenn ja, wie - ansonsten: Was gibt es für eine Alternative?
In der IDE unter Datei-öffnen ist ja das Datum vorhanden, aber ich komme mit den IDE-Sourcen nicht klar.
Wenn ja, wie - ansonsten: Was gibt es für eine Alternative?
In der IDE unter Datei-öffnen ist ja das Datum vorhanden, aber ich komme mit den IDE-Sourcen nicht klar.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
Re: Datum in ShellListView
Nicht direkt. Da müsstest du schon an TCustomShellListView schrauben.
"IDE unter Datei-öffnen" ist ein TOpenDialog. Den kannst du auch benutzen.
Der wird im Ggs. zu TCustomShellListView vom System zur Verfügung gestellt, sieht dafür aber auf verschiedenen Systemen anders aus.
"IDE unter Datei-öffnen" ist ein TOpenDialog. Den kannst du auch benutzen.
Der wird im Ggs. zu TCustomShellListView vom System zur Verfügung gestellt, sieht dafür aber auf verschiedenen Systemen anders aus.
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Re: Datum in ShellListView
Danke, ich habe es befürchtet. Da ich die Liste im Programm benötige, nutzt mir der Open-Dialog leider nicht viel.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
Re: Datum in ShellListView
Ich denke, das ist gar nicht so wild... Das folgende ist aber nicht getestet, aber schau dir einfach den Quellcode von TShellListView an.
- Leite von TCustomShellListView eine neue Klasse ab, z.B. TExtShellListView
- Überschreibe Create und füge weitere Spalten hinzu
Code: Alles auswählen
constructor TExtShellListView.Create(Sender: TObject);
begin
inherited;
Columns.Add('Datum');
OnFileAdded := @FileAdded;
end; - Die Liste wird in PopulateWithRoot gefüllt. Nach dem Hinzufügen eines jeden Items wird ein Event OnFileAdded generiert, dem der betreffende ListItem mitgegeben ist. Du musst nur noch das Dateidatum bestimmen. z.B. FileAge(dateiname) und an die SubItems des Listitem anhängen.
Code: Alles auswählen
procedure TExtShellListView.FileAdded(Sender: TObject; NewItem: TListItem);
var
dt: TDateTime;
begin
FileAge(IncludeTrailingPathDelimiter(FRoot) + NewItem.Caption, dt);
NewItem.SubItems.Add(FormatDateTime(dt));
end; - Veröffentliche die Properties von TShellListview, die du brauchst. Falls du wieder ein OnFileAdded-Ereignis zur Verfügung stellem willst, musst du es neu deklarieren und in FileAdded aufrufen.
Re: Datum in ShellListView
Ich hab's jetzt durchgespielt und bin noch auf ein paar Stolpersteine gestoßen, vor allem weil der Autor die "glorreiche" Idee hatte, eine automatische Anpassung der Breite der drei Spalten an die Control-Breite einzubauen, die man nicht abschalten kann - bei 4 Spalten wird's dann eng... (Das wäre wieder einen Bug-Report wert).
In der Anlage findest du eine kleines Quick-and-dirty Beispiel, es hat einige Seiteneffekte, nämlich dass die Ereignisse OnFileAdded und OnResize zwar noch zur Verfügung stehen, aber nicht mehr funktioneren (OnResize) bzw. die Funktion der neuen Spalte behindern (OnFileAdded). Das zu beheben wäre wesentlich mehr Aufwand gewesen. Oder weiß jemand, wie man bei einer virtuallen Methode die von den Großeltern geerbte Methode aufruft, also quasi ein "inherited inherited"? Das würde wahrscheinlich das OnResize einfach fixen lassen.
In der Anlage findest du eine kleines Quick-and-dirty Beispiel, es hat einige Seiteneffekte, nämlich dass die Ereignisse OnFileAdded und OnResize zwar noch zur Verfügung stehen, aber nicht mehr funktioneren (OnResize) bzw. die Funktion der neuen Spalte behindern (OnFileAdded). Das zu beheben wäre wesentlich mehr Aufwand gewesen. Oder weiß jemand, wie man bei einer virtuallen Methode die von den Großeltern geerbte Methode aufruft, also quasi ein "inherited inherited"? Das würde wahrscheinlich das OnResize einfach fixen lassen.
- Dateianhänge
-
- ShellListView_new_column.zip
- (2.31 KiB) 123-mal heruntergeladen
Zuletzt geändert von wp_xyz am Sa 26. Aug 2017, 00:14, insgesamt 1-mal geändert.
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Re: Datum in ShellListView
Das sieht ja richtig gut aus !
Herzlichen Dank für Deine Bemühungen !
Ich probiere das morgen mal in meine Anwendung zu implementieren.
Was ich nicht verstehe ist, dass es das im (Standard) FileListView nicht bereits gibt.
Herzlichen Dank für Deine Bemühungen !
Ich probiere das morgen mal in meine Anwendung zu implementieren.
Was ich nicht verstehe ist, dass es das im (Standard) FileListView nicht bereits gibt.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
Re: Datum in ShellListView
Statt einer Ableitung für den Hausgebrauch würde man für solche Dinge besser einen Patch auf TCustomShellListView machen.
Hatte ich auch gemacht für "OnFileAdded". https://bugs.freepascal.org/view.php?id=27422
Deshalb können das jetzt alle benutzen.
Hatte ich auch gemacht für "OnFileAdded". https://bugs.freepascal.org/view.php?id=27422
Deshalb können das jetzt alle benutzen.
-
- Beiträge: 369
- Registriert: Do 8. Jun 2017, 18:21
- OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
- CPU-Target: 64Bit
- Wohnort: Wien
Re: Datum in ShellListView
wp_xyz hat geschrieben:Oder weiß jemand, wie man bei einer virtuallen Methode die von den Großeltern geerbte Methode aufruft, also quasi ein "inherited inherited"? Das würde wahrscheinlich das OnResize einfach fixen lassen.
Vorvorvorfahr(self).create sollte im Create des Typs funktionieren, oder nicht? Create ist ja im Gegensatz zu destroy statisch, wenn ich mich nicht irre.
Re: Datum in ShellListView
theo hat geschrieben:Statt einer Ableitung für den Hausgebrauch würde man für solche Dinge besser einen Patch auf TCustomShellListView machen.
Das ist schon klar, aber so einen halbseidenen Patch würde ich nicht akzeptieren. Ein richtiger Patch müsste das Problem grundsätzlicher angehen und dem Benutzer eine Schnittstelle zur Verfügung stellen, beliebige Spalten hinzuzufügen; auch die nicht abschaltbare Spaltenbreitenautomatik muss weg. Mein Versuch war eigentlich eher als Motivation gedacht, dass die Leute einmal in den Quellcode schauen sollten, um Ideen für die Lösung ihrer Probleme zu bekommen - auch wenn das nicht so ausgedrückt war.
Re: Datum in ShellListView
wp_xyz hat geschrieben:theo hat geschrieben:Statt einer Ableitung für den Hausgebrauch würde man für solche Dinge besser einen Patch auf TCustomShellListView machen.
Das ist schon klar, aber so einen halbseidenen Patch würde ich nicht akzeptieren. Ein richtiger Patch müsste das Problem grundsätzlicher angehen und dem Benutzer eine Schnittstelle zur Verfügung stellen, beliebige Spalten hinzuzufügen; auch die nicht abschaltbare Spaltenbreitenautomatik muss weg. Mein Versuch war eigentlich eher als Motivation gedacht, dass die Leute einmal in den Quellcode schauen sollten, um Ideen für die Lösung ihrer Probleme zu bekommen - auch wenn das nicht so ausgedrückt war.
Mein Einwand sollte ja keine Kritik sein, sondern eine Motivation, genau das zu machen was du beschreibst.
Als Bonus braucht man sich dann nicht mehr mit der begrenzten Eingriffsmöglichkeit einer Ableitung herumzuschlagen.
Re: Datum in ShellListView
braunbär hat geschrieben:wp_xyz hat geschrieben:Oder weiß jemand, wie man bei einer virtuallen Methode die von den Großeltern geerbte Methode aufruft, also quasi ein "inherited inherited"? Das würde wahrscheinlich das OnResize einfach fixen lassen.
Vorvorvorfahr(self).create sollte im Create des Typs funktionieren, oder nicht? Create ist ja im Gegensatz zu destroy statisch, wenn ich mich nicht irre.
Ich meine die Methode Resize. Die von TCustomShellListView geerbte Methode ruft zuerst die nun von TControl geerbte Methode auf und führt dann die automatische Spaltenbreitenanpassung für 3 Spalten durch. Ich müsste die Spaltenbreitenanpassung auf 4 Spalten erweitern. Dazu müsste ich das von TControl, nicht von TCustomShellListview geerbte Resize aufrufen und dann meinen speziellen Code anfügen. (das von TCustomShellListView geerbte Resize führt zu heftigem Flackern und Hängen des Programms). Nur: wie geht das? "Inherited Inherited" wird nicht akzeptiert, genausowenig wie "TControl(Self).Resize"
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Re: Datum in ShellListView
Ich have mal begonnen, das in Shellcontrols.pas zu implementieren (funktioniert, aber noch nicht fertig)
Änderungen sind mit //CTR markiert:
Änderungen sind mit //CTR markiert:
Code: Alles auswählen
constructor TCustomShellListView.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// Initial property values
ViewStyle := vsReport;
ObjectTypes := [otNonFolders];
Self.Columns.Add;
Self.Columns.Add;
Self.Columns.Add;
Self.Columns.Add; //CTR
Self.Column[0].Caption := sShellCtrlsName;
Self.Column[1].Caption := sShellCtrlsSize;
Self.Column[2].Caption := sShellCtrlsType;
Self.Column[3].Caption := 'Date'; //CTR - has to be declared elsewhere
// Initial sizes, necessary under Windows CE
Resize;
end;
destructor TCustomShellListView.Destroy;
begin
ShellTreeView := nil;
inherited Destroy;
end;
procedure TCustomShellListView.PopulateWithRoot();
var
i: Integer;
Files: TStringList;
NewItem: TListItem;
CurFileName, CurFilePath: string;
CurFileSize: Int64;
CurFileDate: TDateTime; //CTR
begin
// avoids crashes in the IDE by not populating during design
if (csDesigning in ComponentState) then Exit;
// Check inputs
if Trim(FRoot) = '' then Exit;
Files := TStringList.Create;
try
Files.OwnsObjects := True;
TCustomShellTreeView.GetFilesInDir(FRoot, FMask, FObjectTypes, Files);
for i := 0 to Files.Count - 1 do
begin
NewItem := Items.Add;
CurFileName := Files.Strings[i];
CurFilePath := IncludeTrailingPathDelimiter(FRoot) + CurFileName;
// First column - Name
NewItem.Caption := CurFileName;
// Second column - Size
// The raw size in bytes is stored in the data part of the item
CurFileSize := FileSize(CurFilePath); // in Bytes
NewItem.Data := Pointer(PtrInt(CurFileSize));
if CurFileSize < 1024 then
NewItem.SubItems.Add(Format(sShellCtrlsBytes, [IntToStr(CurFileSize)]))
else if CurFileSize < 1024 * 1024 then
NewItem.SubItems.Add(Format(sShellCtrlsKB, [IntToStr(CurFileSize div 1024)]))
else
NewItem.SubItems.Add(Format(sShellCtrlsMB, [IntToStr(CurFileSize div (1024 * 1024))]));
// Third column - Type
NewItem.SubItems.Add(ExtractFileExt(CurFileName));
// CTR Fourth column - Date - inserted next two lines
FileAge(CurFilePath, CurFileDate);
NewItem.SubItems.Add(FormatDateTime('DD.MM.YYYY hh:mm', CurFileDate));
if Assigned(FOnFileAdded) then FOnFileAdded(Self,NewItem);
end;
Sort;
finally
Files.Free;
end;
end;
procedure TCustomShellListView.Resize;
begin
inherited Resize;
{$ifdef DEBUG_SHELLCTRLS}
debugln(':>TCustomShellListView.HandleResize');
{$endif}
// The correct check is with count,
// if Column[0] <> nil then
// will raise an exception
if Self.Columns.Count < 4 then Exit; //CTR 3 durch 4 ersetzt
// If the space available is small,
// alloc a larger percentage to the secondary
// fields
if Width < 400 then
begin
Column[0].Width := (30 * Width) div 100; //CTR
Column[1].Width := (25 * Width) div 100;
Column[2].Width := (25 * Width) div 100;
Column[3].Width := (30 * Width) div 100; //CTR
end
else
begin
Column[0].Width := (40 * Width) div 100; //CTR
Column[1].Width := (15 * Width) div 100;
Column[2].Width := (15 * Width) div 100;
Column[3].Width := (25 * Width) div 100; //CTR
end;
{$ifdef DEBUG_SHELLCTRLS}
debugln([':<TCustomShellListView.HandleResize C0.Width=',
Column[0].Width, ' C1.Width=', Column[1].Width,
' C2.Width=', Column[2].Width]);
{$endif}
end;
function TCustomShellListView.GetPathFromItem(ANode: TListItem): string;
begin
Result := IncludeTrailingPathDelimiter(FRoot) + ANode.Caption;
end;
procedure Register;
begin
RegisterComponents('Misc',[TShellTreeView, TShellListView]);
end;
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
Re: Datum in ShellListView
Genau, so ähnlich hatte ich mir das auch gedacht.
Ein paar Ideen noch:
Wenn du dir den Quellcode von TCustomShellTreeView.GetFilesInDir ansiehst, wirst du bemerken, dass der per FindFirst/FindNext gefundene SearchRec in the Objects der Stringliste Files gepackt ist. Im SearchRec steht aber schon alles mögliche an Informationen, z.B. die Dateigröße und das Dateidatum. Das heißt, man muss FileSize() und FileAge() nicht separat aufrufen (das ging in meiner Lösung nicht, weil die Routine PopulateWithRoot von außen nicht zugänglich ist), denn diese machen nichts anderes als ein zusätzliches, unnötiges FindFirst().
Dann würde ich mir einen Typ TShellListViewColumnOptions = set of (coSize, coType, coDate) definieren, mit dem man festlegen kann, welche Spalten neben dem immer sichtbaren Dateinamen angezeigt werden. Denn wenn die geänderte Komponente in Lazarus aufgenommen werden soll, muss sie sich in der Regel so verhalten wie die alte. Und ich könnte mir vorstellen, dass es Benutzer gibt, deren Formularlayout geändert werden muss, wenn plötzlich 4 statt 3 Spalten in der Listview sind. Daher sollte die Option coDate standardmäßig abgewählt sein.
Ins Feld Data des Parameters NewItem, der dem Ereignis OnFileAdded mitgegeben wird, sollte man eigentlich einen Zeiger auf den SearchRecord einhängen, nicht nur die Dateigröße. Aber das bricht den Code von Benutzern, die das schon so wie's jetzt ist verwenden. Wahrscheinlich wäre es sinnvoller, ein neues Event zu deklarieren, z.B. OnAddFile, und das alte als "deprecated" zu kennzeichnen.
Die automatische Berechnung der Spaltenbreite müsste man mit sowas wie "AutoColWidths" abschaltbar machen. Nur, wie kann der Benutzer dann die Spaltenbreite eingeben? Man könnte die Eigenschaft Columns wieder als published deklarieren, dann hätte der Benutzer volle Kontrolle. Insbesondere könnte er über das Dateidatum hinaus noch weitere Spalten einfügen. Die Zelldaten würden dann im OnAddFile (oderOnFileAdded)-Event zugewiesen. Allerdings würde das auch bedeuten, dass man prüfen muss, ob er nicht die eingebauten Spalten gelöscht hat oder an einen anderen Index verschoben hat -- das könnte etwas aufwendig werden, das naheliegende Feld Tag darf man hier nicht verwenden - es ist für den Benutzer reserviert.
Ein paar Ideen noch:
Wenn du dir den Quellcode von TCustomShellTreeView.GetFilesInDir ansiehst, wirst du bemerken, dass der per FindFirst/FindNext gefundene SearchRec in the Objects der Stringliste Files gepackt ist. Im SearchRec steht aber schon alles mögliche an Informationen, z.B. die Dateigröße und das Dateidatum. Das heißt, man muss FileSize() und FileAge() nicht separat aufrufen (das ging in meiner Lösung nicht, weil die Routine PopulateWithRoot von außen nicht zugänglich ist), denn diese machen nichts anderes als ein zusätzliches, unnötiges FindFirst().
Dann würde ich mir einen Typ TShellListViewColumnOptions = set of (coSize, coType, coDate) definieren, mit dem man festlegen kann, welche Spalten neben dem immer sichtbaren Dateinamen angezeigt werden. Denn wenn die geänderte Komponente in Lazarus aufgenommen werden soll, muss sie sich in der Regel so verhalten wie die alte. Und ich könnte mir vorstellen, dass es Benutzer gibt, deren Formularlayout geändert werden muss, wenn plötzlich 4 statt 3 Spalten in der Listview sind. Daher sollte die Option coDate standardmäßig abgewählt sein.
Ins Feld Data des Parameters NewItem, der dem Ereignis OnFileAdded mitgegeben wird, sollte man eigentlich einen Zeiger auf den SearchRecord einhängen, nicht nur die Dateigröße. Aber das bricht den Code von Benutzern, die das schon so wie's jetzt ist verwenden. Wahrscheinlich wäre es sinnvoller, ein neues Event zu deklarieren, z.B. OnAddFile, und das alte als "deprecated" zu kennzeichnen.
Die automatische Berechnung der Spaltenbreite müsste man mit sowas wie "AutoColWidths" abschaltbar machen. Nur, wie kann der Benutzer dann die Spaltenbreite eingeben? Man könnte die Eigenschaft Columns wieder als published deklarieren, dann hätte der Benutzer volle Kontrolle. Insbesondere könnte er über das Dateidatum hinaus noch weitere Spalten einfügen. Die Zelldaten würden dann im OnAddFile (oderOnFileAdded)-Event zugewiesen. Allerdings würde das auch bedeuten, dass man prüfen muss, ob er nicht die eingebauten Spalten gelöscht hat oder an einen anderen Index verschoben hat -- das könnte etwas aufwendig werden, das naheliegende Feld Tag darf man hier nicht verwenden - es ist für den Benutzer reserviert.
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Re: Datum in ShellListView
Da ich im Moment zeitlich wahrscheinlich nicht dazu komme vermerke ich hier für später, was ansonsten auch noch berücksichtigt werden sollte:
(Zuzüglich der Sachen im vorherigen Post von wp_xyz und den Kommentaren im Quellcodeteil)
Betroffene Dateien: lcl/ShellCtrls, lcl/LCLStrConsts
1. Property für Datumsformat
2. Properties ShowSize, ShowType, ShowDate
3. Erweiterung des Sort-Properties um Date
4. Properties für Width von File, Size, Type, Date
Ideen und/oder Anregungen gerne hier posten!
Anmerkung: Ich habe bisher noch nie mit Komponentenentwicklung zu tun gehabt und muss mich da wohl erst etwas einarbeiten.
Da ich einen Abgabetermin für meine Software einzuhalten habe, fehlt mir in den kommenden Wochen hierzu vermutlich die notwendige Zeit.
Sollte also jemand Lust verspüren, sich der Aufgabe annehmen zu wollen bzw. mich hierbei zu unterstützen - nur zu
(Zuzüglich der Sachen im vorherigen Post von wp_xyz und den Kommentaren im Quellcodeteil)
Betroffene Dateien: lcl/ShellCtrls, lcl/LCLStrConsts
1. Property für Datumsformat
2. Properties ShowSize, ShowType, ShowDate
3. Erweiterung des Sort-Properties um Date
4. Properties für Width von File, Size, Type, Date
Ideen und/oder Anregungen gerne hier posten!
Anmerkung: Ich habe bisher noch nie mit Komponentenentwicklung zu tun gehabt und muss mich da wohl erst etwas einarbeiten.
Da ich einen Abgabetermin für meine Software einzuhalten habe, fehlt mir in den kommenden Wochen hierzu vermutlich die notwendige Zeit.
Sollte also jemand Lust verspüren, sich der Aufgabe annehmen zu wollen bzw. mich hierbei zu unterstützen - nur zu
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.