Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi TListView - OnDataHint (https://www.delphipraxis.net/198213-tlistview-ondatahint.html)

ManfredG 13. Okt 2018 18:24

TListView - OnDataHint
 
Ich arbeite gerade an einem virtuellen ListView.
Kann mir jemand einen Hinweis geben, wie man das Ereignis OnDataHint bedient?
Ich finde kaum Informationen in der DP, aber auch nichts brauchbares in anderen Quellen.
Mein erster Ansatz war folgender:

LvFiles ist ein TListView, OwnerData ist TRUE, OwnerDraw ist FALSE
FileObjLst ist ein TList, in dem sich die Daten der virteuellen Items befinden (FileObj)

Delphi-Quellcode:
Procedure THF.LvFilesDataHint (Sender: TObject; StartIndex, EndIndex: Integer);
Var
  Idx : Integer;
  Item: TListItem;
  FileObj: TFileObj;
  FilePathName: string;
Begin
  CodeSite.Send ('LvFilesDataHint for Lines ' + IntToStr(StartIndex)+' to '+ IntToStr(EndIndex));
  For Idx := StartIndex To EndIndex Do
  Begin
    Item   := LvFiles.Items.Item[Idx];
    FileObj := FileObjLst[Item.Index];
    CodeSite.Send ('LvFilesData for: ' + FileObj.FileName, FileObj);
    Item.Data      := FileObj;
    Item.Caption   := FileObj.FileName; // NUR Dateiname (wird angezeigt)
    FilePathName   := FileObj.NodeFldrObj.AbsPathEx + '\' + FileObj.FileName; // Pfad + Dateiname für weitere Verwendung
    Item.ImageIndex := IconList.FindIcon (FilePathName); // Bildindex in Windows Hauptliste small images
    Item.SubItems.Add (FileObj.FileLenS);               // SubItem 0 - Dateigröße
    Item.SubItems.Add (FileObj.FileType);               // SubItem 1 - Dateitype
    Item.SubItems.Add (formatdatetime('yyy-mm-dd hh:nn:ss', FileObj.FileDate)); // Subitem 2 - Änderungsdatum
    Item.SubItems.Add (FileObj.FileAttr); // SubItem 3 - Dateattribute
  End;
End;
Ich kann keine Auswirkungen dieser Procedure erkennen, was habe ich nicht richtig verstanden?
Manfred

Bbommel 15. Okt 2018 08:10

AW: TListView - OnDataHint
 
Du musst nicht nur OnDataHint setzen, sondern auch OnData. Möglicherweise liegt es daran. Die Einstellung OwnerData=true und OwnerDraw=false sollte jedenfalls passen.

Edit: ...ach ja, und du musst irgendwo auch das Count des ListView auf die Anzahl der Elemente setzen, die du anzeigen willst, also im Zweifel auf FileObjList.Count. Das geh aus deinem Codeschnippsel so nicht hervor, ob du das gemacht hast.

ManfredG 16. Okt 2018 07:05

AW: TListView - OnDataHint
 
Sorry, habe ich nicht erwähnt, aber alles andere ist geschehen, also:

Delphi-Quellcode:
Procedure THF.LvFilesData (Sender: TObject; Item: TListItem);
Var
  FileObj: TFileObj;
Begin
  FileObj        := FileObjLst[Item.Index];
  Item.Data      := FileObj;
  Item.Caption   := FileObj.FileName; // NUR Dateiname (wird angezeigt)
  Item.ImageIndex := FileObj.FileIcon; // Bildindex in Windows Hauptliste small images
  Item.SubItems.Add (FileObj.FileLenS); // SubItem 0 - Dateigröße
  Item.SubItems.Add (FileObj.FileType); // SubItem 1 - Dateitype
  Item.SubItems.Add (FileObj.FileDatS); // Subitem 2 - Änderungsdatum
  Item.SubItems.Add (FileObj.FileAttr); // SubItem 3 - Dateattribute
End;
und

Delphi-Quellcode:
Procedure THF.ReadFiles (Node: TTreeNode);
Var
  FldrPath : String;
  FileName : String;
  FldrObj : TFldrObj;
  FileArray: TStringDynArray;
  ArrayIdx : Integer;
  ArraySize: Integer;
  FileCount: Integer;
  FileObj : TFileObj;
  FIdCnt  : Integer;
  sFileAttr: String;
  lFileAttr: TFileAttributes;
  // FileInfo : TSHFileInfo;
Begin
  LogEnterMethod ('THF.ReadFiles');
  // Vorbereitung ==============================
  FileCount := 0;                             // Zählt die wirklich angezeigten Dateien
  FldrObj  := Node.Data;                     // Ordnerobjekt aus dem aktuellen Baumknoten extrahieren
  FldrPath := FldrObj.AbsPathEx;             // Absoluten Pfad des aktuellen Ordners bereitstellen (ohne \)
  FileArray := TDirectory.GetFiles (FldrPath); // Unterordner ermitteln und in Array bereitstellen
  ArraySize := Length (FileArray);            // Anzahl der Unterordner
  // alte Dateiliste durchlaufen und die enthaltnen Folder-Objekte vernichten
  LvFiles.Items.BeginUpdate;
  For FIdCnt := 0 To FileObjLst.Count - 1 Do    // Dateiobjektliste durchgehen
  Begin                                         // alle Elemente
    TFileObj (FileObjLst.Items[FIdCnt]).Destroy; // einzeln vernichten (jetzt Destroy, füher Free 2018-10-11)
  End;                                          // bis Ende
  // Listelemente löschen
  FileObjLst.Clear; // alle auf einmal
  // Alle Dateien im Array durchgehen ...
  For ArrayIdx := 0 To ArraySize - 1 Do              // alle Dateien durchgehen
  Begin                                              // (die Arrayelemente enthalten den vollstämdigen Dateinamen = Pfad+Dateiname
    FileName := FileArray[ArrayIdx];                 // ein Dateiname
    If Opt.ShowThisFile (FileName) Then              // wenn nichts gegen die Anzeige spricht (z.B. datei.bak) sh. OdbOpt
    Begin                                            // Objekt für die Dateiliste aufbauen:
      inc (FileCount);                               // Dateizähler erhöhen
      FileObj         := TFileObj.Create;           // Dateiobjekt erstellen (sh. ObjObj->TFileObj)
      FileObj.FileName := ExtractFilename (FileName); // Dateinamen (ohne Pfad) ablegen
      LogLog ('Collecting Data for: »' + FileObj.FileName + '«');
      FileObj.FileLn64    := GetFileSize (FileName); // Dateigröße in Bytes   ablegen
      FileObj.NodeFldrObj := FldrObj;               // Datenobjekt des Ordners referenzieren
      //
      lFileAttr := TFile.GetAttributes (FileName); // Attribute zusammenstellen (bisher nur unbedeutend)
      sFileAttr := '';                            // leer
      ...
      FileObj.FileAttr := sFileAttr;                  // Attribute ablegen
      //
      FileObj.FileIcon := IconList.FindIcon (FileName);
      FileObj.FileType := IconList.FindType (FileName);
      FileObj.FileDatE := TFile.GetCreationTime (FileName); // Datei-Estellungszeit ablegen
      FileObj.FileDesk := DeskriptFile (FldrObj, FileObj);
      FileObjLst.Add (FileObj); // Objekt in Datei-Liste aufnehmen (wird für OwnerData benötigt)
    End Else Begin
      LogLog ('Hiding File: ' + FileName, clLtBlue);
    End;
  End;
  LvFiles.Items.Count := FileCount; // Count muß bei OwnerData manuell gesetzt werden <-----------------
  LogLog (IntToStr(FileCount) + ' out of ' + IntToStr(ArraySize) + ' Files collected');
  LvFiles.Items.EndUpdate;          // Update der Dateiliste beenden
  SetLength (FileArray, 0);         // Dateinamen-Array löschen
  Finalize (FileArray);             // und endgülig entfernen
  AcOrdDsk.Enabled := FileCount > 0; // Action/Menüpunkt Ordner verschlagworten erlauben
  LvFiles.Refresh;
  LogExitMethod ('THF.ReadFiles');
End;
Da Ganze hatte schon ohne OnDataHint funktioniert.
In der Zwischenzeit habe ich OnDataHint aufgebaut. Dort wird StartIndex und EndIndex übergeben, für die Zeilen, die sich ändern.
Offensichtlich kann man das zum Aufbau eines Caches nutzen, in dem die Zeilen bereitgestellt werden, die dann von OnData aufgerufen werden.
Ich glaube, das war alles dazu.
Danke, Manfred.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz