AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
Thema durchsuchen
Ansicht
Themen-Optionen

Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

Ein Thema von KodeZwerg · begonnen am 13. Nov 2018 · letzter Beitrag vom 14. Nov 2018
Antwort Antwort
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

  Alt 13. Nov 2018, 14:03
Ich hoffe *bet* das ichs jetzt gerafft habe:
Delphi-Quellcode:
procedure TfrmMain.StartIcons();
begin
  TThread.CreateAnonymousThread(procedure ()
    var
      LIcon: TIcon;
      dummy: Word;
    begin
      dummy := 0;
      LIcon := TIcon.Create;
      LIcon.Transparent := True;
      try
        TThread.Synchronize (TThread.CurrentThread, procedure ()
          var
            I: Integer;
          begin
            lvFiles.Update;
            FileIcons.BeginUpdate;
            for i := 0 to lvFiles.Items.Count -1 do
              begin
                LIcon.Handle := ExtractAssociatedIcon( hInstance, PWideChar( lvFiles.Items.Item[ i ].Caption ), dummy );
                LIcon.Transparent := True;
                lvFiles.Items.Item[ i ].ImageIndex := FileIcons.AddIcon( LIcon );
                DestroyIcon( LIcon.Handle );
              end;
          end);
      finally
        FileIcons.EndUpdate;
        LIcon.Free;
      end;
    end).Start;
end;
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#2

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

  Alt 13. Nov 2018, 14:11
TThread.Synchronize (TThread.CurrentThread,

Bist sicher? Nicht Nil!
Nur mal als sample

Delphi-Quellcode:
function TSessionThread.OnSessionCreated(NewSession: IAudioSessionControl): HResult;
begin

  Result := S_FALSE;

  if (MainThreadID <> GetCurrentThreadId) then
  begin
    TThread.Queue(nil,
      procedure
      var
        bDuplicate: BOOL;
        i: Integer;
      begin
        if Assigned(FOnAudioSessionCreate) then
        begin
          ASessionInfo := GetSessionInfo(NewSession);
          if ASessionInfo.FileName <> 'then
          begin
            // Check to prevent duplicate registeration of audio session
            bDuplicate := false;
            for i := 0 to (FSessionCount - 1) do
           if SessionInfo[i].PID = ASessionInfo.PID then
           begin
             // for the case of reuse of same PID (but different programs)
             if SessionInfo[i].State <> AudioSessionStateExpired then
             begin
               bDuplicate := true;
               Break;
             end;
          end;

          if not bDuplicate then
          begin
            inc(FSessionCount);
            SetLength(SessionInfo, FSessionCount);
            SessionInfo[FSessionCount - 1] := ASessionInfo;
            FOnAudioSessionCreate(NewSession, ASessionInfo, FSessionCount);
          end;
        end;
      end;
    end);
    Result := S_OK;
  end;
end;
Zitat:
Warum so kompliziert und nicht einfach die Icons in eine ImageList stecken.
Und du kennst alle Icons von Programmen die er auslesen will auch unbekannte die noch niemals auf seiner Platte waren also im Moment unbekannt sind?
Super na ja dann addiere die unbekannten mal zur Imagelist.
Ist doch einfach oder?

gruss

Geändert von EWeiss (13. Nov 2018 um 14:17 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

  Alt 13. Nov 2018, 14:36
Mein nächster Versuch, bis jetzt mehr als gescheitert, bin noch auf Fehlersuche.

Hab mal im Soure kommentiert so wie ich es dachte das es funktioniert:
Delphi-Quellcode:
//dieses mal mit eingabe
procedure TfrmMain.StartIcons( ListView: TListView; ImageList: TImageList );
begin
  // hier soll ein Thread abseits des Mainthreads starten um diesen zu entlasten
  TThread.CreateAnonymousThread(procedure ()
    var // <- locale variablen für den Thread
      LIcon: TIcon;
      dummy: Word;
      I: Integer;
      LImageList: TImageList;
      LListView: TListView;
    begin
      dummy := 0;
      LListView := TListView.Create( nil );
      LImageList := TImageList.Create( nil );
      LIcon := TIcon.Create();
      LIcon.Transparent := True;
      LImageList.BeginUpdate;
      LImageList.Assign( ImageList ); // <-- lokale kopie der aktuellen liste
      LListView.Items.BeginUpdate;
      LListView.Assign( ListView ); // <-- lokale kopie der aktuellen liste
      try // <-- beginne mit der arbeit an den lokalen kopien
        for i := 0 to LListView.Items.Count -1 do
          begin
            LIcon.Handle := ExtractAssociatedIcon( hInstance, PWideChar( LListView.Items.Item[ i ].Caption ), dummy );
            LIcon.Transparent := True;
            LListView.Items.Item[ i ].ImageIndex := LImageList.AddIcon( LIcon );
            DestroyIcon( LIcon.Handle );
          end;
        LImageList.EndUpdate;
        LListView.Items.EndUpdate;
        TThread.Synchronize (nil, procedure () // übergebe lokale kopien zurück an vcl
          begin
            FileIcons.BeginUpdate;
            FileIcons.Assign( LImageList );
            FileIcons.EndUpdate;
            lvFiles.Items.BeginUpdate;
            lvFiles.Assign( LListView );
            lvFiles.Items.EndUpdate;
          end);
      finally
        LIcon.Free;
        LImageList.Free;
        LListView.Free;
      end;
    end).Start;
end;
das ist momentan die schnellste variante, da sie nicht funktioniert :-]
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#4

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

  Alt 13. Nov 2018, 15:53
TThread.Synchronize (TThread.CurrentThread, Bist sicher? Nicht Nil!
Du kannst da übergeben was du möchtest - der Wert wird im Prinzip nicht wirklich verwendet.

Die Thread-Instanz wird in einen Record geschrieben:
Delphi-Quellcode:
class procedure TThread.Synchronize(const AThread: TThread; AMethod: TThreadMethod);
var
  FSynchronize: TSynchronizeRecord;
begin
  FSynchronize.FThread := AThread; // da
  FSynchronize.FSynchronizeException := nil;
  FSynchronize.FMethod := AMethod;
  FSynchronize.FProcedure := nil;
  Synchronize(@FSynchronize);
end;

class procedure TThread.Synchronize(const AThread: TThread; AThreadProc: TThreadProcedure);
var
  FSynchronize: TSynchronizeRecord;
begin
  FSynchronize.FThread := AThread; // oder da
  FSynchronize.FSynchronizeException := nil;
  FSynchronize.FMethod := nil;
  FSynchronize.FProcedure := AThreadProc;
  TThread.Synchronize(@FSynchronize);
end;
und dann wird ein TNotifyEvent damit aufgerufen:
Delphi-Quellcode:
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False; ForceQueue: Boolean = False);
var
  SyncProc: TSyncProc;
  SyncProcPtr: PSyncProc;
begin
  [...]
        if Assigned(WakeMainThread) then
          WakeMainThread(SyncProcPtr.SyncRec.FThread);
  [...]
end;
der bei einer VCL-Anwendung mit dieser Methode verbunden ist:
Delphi-Quellcode:
procedure TApplication.WakeMainThread(Sender: TObject);
begin
  PostMessage(Handle, WM_NULL, 0, 0);
end;
Wie man sieht, mit der schönen Instanz die mit Sender übergeben wird, wird schon mal gar nichts gemacht.
(BTW: Bei FMX sieht es auch nicht besser aus)

Fazit
Es ist völlig egal ob man dort eine Instanz des aktuellen Threads, oder irgendeine Instanz oder eine ungültige oder eben einfach gar keine mit nil übergibt. Somit besteht kein Grund zur Sorge, wenn jemand dort eine Instanz übergibt.

Darum sollte man hier auch ganz beherzt ein nil übergeben, denn das ist kürzer und gaukelt auch keine sonstige Funktionalität vor.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.630 Beiträge
 
Delphi 12 Athens
 
#5

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

  Alt 13. Nov 2018, 17:19
Du kannst da übergeben was du möchtest - der Wert wird im Prinzip nicht wirklich verwendet.
Für Synchronize stimmt das, aber bei Queue spielt es schon eine Rolle.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#6

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

  Alt 13. Nov 2018, 17:33
Du kannst da übergeben was du möchtest - der Wert wird im Prinzip nicht wirklich verwendet.
Für Synchronize stimmt das, aber bei Queue spielt es schon eine Rolle.
Könntest du erklären wie oder welche Rolle? Ich sehe aktuell nicht, wo diese Information (Instanz von TThread ) auch beim TThread.Queue sinnvoll verwendet wird.

Auch TThread.Queue ruft intern class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False; ForceQueue: Boolean = False) auf und das habe ich oben erläutert.

Aber bestimmt übersehe ich da etwas ...
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.630 Beiträge
 
Delphi 12 Athens
 
#7

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

  Alt 13. Nov 2018, 18:28
Könntest du erklären wie oder welche Rolle? Ich sehe aktuell nicht, wo diese Information (Instanz von TThread ) auch beim TThread.Queue sinnvoll verwendet wird.

Auch TThread.Queue ruft intern class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False; ForceQueue: Boolean = False) auf und das habe ich oben erläutert.
TThread.Destroy ruft TThread.RemoveQueuedEvents auf und dort werden alle noch nicht erledigten Queue-Events für diesen Thread gelöscht und somit nicht mehr ausgeführt. Übergibt man beim Queue ein nil, kommen die Events auch noch an wenn der auslösende Thread schon weg ist.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#8

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

  Alt 13. Nov 2018, 18:48
TThread.Destroy ruft TThread.RemoveQueuedEvents auf
jetzt wo du es sagst ... stimmt, da war noch was
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:26 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz