![]() |
VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen
Ich fülle ein VST ganz normal über Init, GetText, Free. So wie es ja sein soll. Das macht auch keine Probleme.
Im Event GetImageIndex macht diese Zeile hier Probleme, wenn ich öfter schnell rauf- und runterscrolle und danach irgendeine der Spaltenbreiten verändere. Ein paar mal verändern geht, aber sobald ich auf einen Trenner doppelklicke, sodass sich die Spalte eigentlich die Auto-Größe holt, hängt sich alles auf. Das Programm hängt sich auf und manchmal kommt die Fehlermeldung oben. Manchmal kommt auch Falscher Parameter. Manchmal kommt das auch, wenn ich das Fenster über längere Zeit offen lasse ohne irgendwas zu machen. Manchmal reicht auch schon rumscrollen.
Delphi-Quellcode:
Lasse ich die Zeile weg, habe ich gar keine Probleme. Mache ich irgendwas falsch
if SHGetFileInfo(PChar(FileName), FILE_ATTRIBUTE_NORMAL, Info, SizeOf(TSHFileInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX or SHGFI_ICON or
SHGFI_SMALLICON) = 0 then (wie ich Icons lade und anzeige, sieht man hier ![]() |
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Keiner eine Idee was hier an VirtualStringTree falsch sein kann? Wenn ich keine Icons anzeige ist das Problem nicht da.
|
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Ohne den Rest deines Programms zu kennen:
Das riecht verdächtig nach Threads. Bearbeitest du irgendwo außerhalb des VCL-Mainthreads Bitmaps? Denn da muss man höllisch aufpassen, bzw. es besser ganz sein lassen. Selbst Thread-lokale TBitmaps können dir den Rest des Programms an ganz anderer Stelle zerschießen. |
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Arbeitet VirtualStringTree intern mit Threads?
Weil ich selber nicht an dieser Stelle. Mit Bitmaps mache ich auch nichts. Wenn das VST 10000 Einträge hat, jeder Eintrag 6 Spalten und jeweils 2 Icons und man richtig wild rauf und runter fährt, kommt es auch irgendwann zu dem Fehler. Definitiv kommt es aber zu dem Fehler, wenn man auf einen Spalten-Trenner doppel-klickt, damit die Spalte die Auto-Breite bekommt. Dann kommt auch irgendwann Systemresourcen erschöpft und Canvas erlaubt kein Zeichnen. FormCreate
Delphi-Quellcode:
Und dann, egal wo, ob im GetImageIndex oder InitNode oder wo auch immer, sobald ich mit SHGetFileInfo arbeite um an die Icons zu kommen, kommen die Probleme.
SmallImages := TImageList.Create(Self);
SystemImageList := SHGetFileInfo('', 0, Info, SizeOf(TSHFileInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_ICON or SHGFI_SYSICONINDEX or SHGFI_SMALLICON); SmallImages.Handle := SystemImageList; SmallImages.ShareImages := True; VST.Images := SmallImages; Die Icons werden alle angezeigt, das ist kein Problem. Aber wild rumscrollen und sowas erzeugt dann irgendwann einfach ein einfrierendes/schwarzes Fenster. |
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Zerstörst du denn die Icons irgendwann wieder? Die Remarks zu
![]() Zitat:
Zitat:
Dalai |
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Reicht es, wenn ich die Imagelist einfach leere wenn ich das Fenster schließe?
Kannst du mir dafür ein Beispiele geben, wie ich das mit CoInitialize richtig mach? Einen Fehler hab ich vergessen. "Falscher Parameter" aus der Vcl.Graphics kommt auch gelegentlich. Wie gesagt bei wildem umherscrollen. Ich dachte immer ein VirtualStringTree hat kein Problem mit Millionen Einträgen. Bei mir sind es schon 9000 die Probleme machen (nur mit Icons, alles andere ist feinst säuberlich generisch aufgebaut). |
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Zitat:
Die Image-list verwaltet dann die Icons das Handle des Icon das du vorher addiert hast musst du dann löschen. Zitat:
wenn du sonst nirgends ein COM object verwendest. Dann rufe vor SHGetFileInfo CoInitialize auf und wenn du alle Icons addiert hast CoUnInitialize. |
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Ich rufe SHGetFileInfo in InitNode auf. Das heißt es wird nur ein Icon geladen, wenn es benötigt wird. Ich dachte eigentlich immer, dass das helfen würde.
CoInitialize und CoUnInitialize um SHGetFileInfo hat hier nichts gebracht leider. Könnte es helfen, wenn ich SHGetFileInfo ganz aus der Unit mit dem VST auslagere und schon dort aufrufe, wo ich meine Liste für das VST erestelle? Im VST GetImageIndex hole ich mir dann nur noch den ImageIndex. |
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Zitat:
Dafür ist sie da! Ich mache hier auch nichts anderes.
Delphi-Quellcode:
Ok ist für ein ListView und Win32 Api aber in der Funktionsweise das gleiche.
if hLarge = 0 then
begin hLarge := ImageList_Create(round(bw), round(bh), ILC_COLOR32, 1, 1); // 32 Bit Bitmap konvertiert zu Icon ListView_SetImageList(Handle, hLarge, LVSIL_NORMAL); end; // Icon zur Liste addieren ImageList_AddIcon(hLarge, hIconItem); SetLength(ItemsInfo, nItem + 1); ItemsInfo[nItem].Item := nItem; ItemsInfo[nItem].SubItem := nSubItem; ItemsInfo[nItem].Width := round(bw); ItemsInfo[nItem].Height := round(bh); ItemsInfo[nItem].ImgIcon := hIconItem; ItemsInfo[nItem].IdentStr := ImgIdent; // Icon freigeben // wird nicht mehr verwendet da in der ImageList enthalten DestroyIcon(hIconItem); Wenn ich jedes Icon extra laden würde oh.. oh.. das wird nix. Image list erstellen Icon addieren Handle löschen. |
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Deinen Code verstehe ich nicht. Ich mache nichts anderes. Ich lade das Icon und weise den ImageIndex zu.
Ich habe den Code jetzt ausgelagert und komplett von der VST-Unit abgekoppelt. Trotzdem kommen Fehlermeldungen. Bis vor 10.3.3 war das alles gar kein Problem bin ich der Meinung. Mein Code ist wie gesagt so.
Delphi-Quellcode:
SmallImages und SystemImageList: passiert im FormCreate. Beides lokale Variablen in FormCreate (warum, keine Ahnung).
SmallImages := TImageList.Create(Self);
SystemImageList := SHGetFileInfo('', 0, Info, SizeOf(TSHFileInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_ICON or SHGFI_SYSICONINDEX or SHGFI_SMALLICON); SmallImages.Handle := SystemImageList; SmallImages.ShareImages := True; VST.Images := SmallImages; |
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Zitat:
Das ist sehr un-konstruktiv jedesmal eine neue ImageListe zu erstellen für 1 Icon! sorry Einmalig und fertig. Das ist dein Problem. Und wie gesagt das Handle des Icon löschen.
Delphi-Quellcode:
DestroyIcon(Info.HIcon);
|
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Ungefähr so?
FormCreate
Delphi-Quellcode:
InitNode
SmallImages := TImageList.Create(Self);
SystemImageList := SHGetFileInfo('', 0, Info, SizeOf(TSHFileInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_ICON or SHGFI_SYSICONINDEX or SHGFI_SMALLICON); SmallImages.Handle := SystemImageList; SmallImages.ShareImages := True; VST.Images := SmallImages;
Delphi-Quellcode:
Ach das funktioniert doch eh nicht. Deinen Code verstehe ich nicht und auch keine Ahnung wo der hin soll, welche Variablentypen das sind, wie ich das am Ende anzeige usw.
SHGetFileInfo(PChar(FileName), FILE_ATTRIBUTE_NORMAL, Info, SizeOf(TSHFileInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX or SHGFI_ICON or SHGFI_SMALLICON);
ImageList_AddIcon(SmallImages.Handle, Info.iIcon); DestroyIcon(Info.iIcon); // Mit dieser Zeile sehe ich dann keine Icons |
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Zitat:
Das ImageList wird zerstört oder sonst was. Ist aber auch möglich das es in 10.4 einfach nicht mehr korrekt funktioniert. |
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Ich verstehe deine Aussage aber auch nicht
Zitat:
Und außerdem. Woher will das VST wissen, welchen Index es für welches Node braucht? Dafür muss ich doch zwangsweise in jedem Node 1x GetSHFileInfo aufrufen. Zitat:
Hier nochjmal zusammengefasst wie ich es immer gemacht habe und wie es auch eigentlich immer funktioniert hat FormCreate
Delphi-Quellcode:
InitNode
SmallImages := TImageList.Create(Self);
SystemImageList := SHGetFileInfo('', 0, Info, SizeOf(TSHFileInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_ICON or SHGFI_SYSICONINDEX or SHGFI_SMALLICON); SmallImages.Handle := SystemImageList; SmallImages.ShareImages := True; VST.Images := SmallImages;
Delphi-Quellcode:
VSTGetImageIndex
SHGetFileInfo(PChar(FileName), FILE_ATTRIBUTE_NORMAL, Info, SizeOf(TSHFileInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX or SHGFI_ICON or SHGFI_SMALLICON);
MeinNode-generisch.MeinIconIndex := Info.iIcon; // jetzt weiß der Datensatz unter dem Node, welcher IconIndex das Icon braucht.
Delphi-Quellcode:
ich glaube die ImageList benutze ich nicht einmal.
if Kind in [ikNormal, ikSelected] then
ImageIndex := MeinNode-generisch.MeinIconIndex; |
AW: SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichnen / VirtualStringTr
Zitat:
Zitat:
Delphi-Quellcode:
SHGetFileInfo(PChar(FileName), FILE_ATTRIBUTE_NORMAL, Info, SizeOf(TSHFileInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX or SHGFI_ICON or SHGFI_SMALLICON);
MeinNode-generisch.MeinIconIndex := Info.iIcon; // jetzt weiß der Datensatz unter dem Node, welcher IconIndex das Icon braucht. Zitat:
Und du lädst jedesmal ein neues Icon anstatt die ImageListe zu verwenden wo dann alle schon enthalten sind. da ist so einiges faul. Der richtige weg ist. Die ImageList einmalig mit allen Icons zu füllen. Und bei InitNode den entsprechenden index aus der ImageList (Hicon) der Node zuzuweisen. |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Wieso "so einiges"?
Ich würde es ja verbessern aber ich verstehe deinen Code nicht, weil da für mich der Kontext fehlt. Ich habe das eben aber mal mit der ImageList versucht. Egal ob ein Icon schon da drin ist oder nicht, es werden in InitNode immer weiter Icons in die Liste gepackt. Ich kapiere mittlerweile überhaupt nix mehr und besonders nicht, warum die ImageList angeblich so gut sein soll. Woher soll die denn beim Hinzufügen neuer Icons wissen, ob das schon da drin ist oder nicht? Und auch wenn, das ist ja nicht einmal mein Problem. ich muss für JEDEN Node GetSHFileInfo aufrufen, um überhaupt herauszubekommen, welches Icon dahintersteckt. Wie soll mir da eine ImageList helfen? Du redest hier im Prinzip mit einem Anfänger! Hast du keinen normalen Code statt den aufd Seite 1 mit SetLength, ItemsInfo und so? |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Zitat:
Nur zur Veranschaulichung es geht um die Bilder.. ![]() |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Verstehe ich alles nicht. Ich habe es im Prinzip so gemacht wie hier aus #7
![]() |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Nun ja du rufst in jeder InitNode SHGetFileInfo auf das ist ein Overhead oder?
Warum? Frage ich mich. Das meine ich mit Un-Konstruktiv. ![]() |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Dazu meine Gegenfrage
Zitat:
![]() Oder ist das alles schon wieder so ein unbekannter Delphi-Fehler? Hier ist auch ein Beispiel wo SHGetFileInfo ständig aufgerufen wird ohne irgendwas mit Destroy oder so ![]() |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Ich würde dir vorschlagen dir die Samples vom VirtualStringTree anzuschauen.
![]() Keine Ahnung ob es das gleiche ist was du verwendest. Zuletzt. ![]() ![]() den index aus der ImageList bekommt man so. VirtualStringTree1GetImageIndex ![]() EDIT: Zitat:
Delphi-Quellcode:
ImageIndex := MeinNode-generisch.MeinIconIndex;
Du lädst jedesmal ein neues Icon. Prüfe dann mal das Handle es ist unterschiedlich oder? Also wird das Icon nicht freigegeben das bedeutet der Speicher deiner Anwendung explodiert Exponential Das ist der Grund warum du dann irgendwann einfach nicht mehr zeichnen kannst. Das du das Icon nicht mehr siehst ist normal nach DestroyIcon(Info.Hicon) denn du verwendest nicht den Index der ImageList sondern dein Index ist ein HIcon. Das ist definitiv falsch! |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Zitat:
Alle deine Links kenne ich leider schon. |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Zitat:
Das einzige was noch helfen könnte prüfe ob sich das Handle des Icon zu dem vorherigen unterscheidet und lösche das alte (HIcon) bevor du ein neues lädst. |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Zitat:
Zitat:
Im InitNode rufe ich 1x SHGetFileInfo auf. Und egal, ob ich da jetzt mit einer ImageList was mache, mit Destroy oder ohne: die Fehler kommen trotzdem. |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Wenn du jedes mal vom System lädst, was soll die ImageList?
Sonst müsstest du einmal beim Befüllen des VST bei jedem Node einmalig gucken welches Image mit welchem Index das in der ImageList ist und das dann in dem Node speichern. |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Zitat:
Weil du das zuletzt geladenen Icon freigibst und nicht das vorherige das geladen wurde. Du erkennst den unterschied? Prüfe doch einfach mal was für einen Speicher deine Anwendung verwendet und vor allem ob dieser freigegeben wird. (Taskmanager) Zitat:
Das ist nun mal fakt. Die frage ist doch was geladen wird. Wenn es nur um System icons geht wie Folder ec.. dann ist eine Imagelist immer vom vorteil. Denn diese ändern sich nicht. Aber dafür gibt es ja schon eine liste "SystemImageList" Zitat:
Gebe die Icon Handles frei und alles ist gut. |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Eine Idee hätte ich noch.
Nur zum testen ob dein Problem damit behoben ist. Erstelle eine ImageList. Add 1 Icon nach dem addieren lösche das Handle. Dann übergeben jeder Node den Index 0 der ImageList. Prüfe dann ob dein Problem behoben ist. Ja jede Node hat dann das gleiche Icon. Ist auch nur zum testen gedacht ob dein Problem damit behoben ist. Falls ja dann weist du woran es liegt. |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Sorry wegen der langen Antwortzeit. Ich hatte hier Probleme die Datei hochzuladen.
Ich habe hier mal ein Minimalprojekt gebaut. Das zeigt das Problem und auch GANZ grob runtergebrochen meinen Aufbau mit meiner Liste. Ich glaube hier dran kann man am besten sehen was das Problem ist. Benötigt wird ein Verzeichnis mit sehr vielen Dateien und Verzeichnissen. Ich nehme dafür gerne das Mozilla-Verzeichnis in AppData. Die Datei ist etwas größer weil ich da noch die Exe-Datei drin habe, kompiliert mit 10.3.3 CE und VirtualStringTree 7.X (die neueste). ... Dateien hochladen funktioniert heute nicht. Deswegen hab ichs woanders hochgeladen: ![]() |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Ist das denn richtig?
Delphi-Quellcode:
Wird .IconIndexSpalte1 jemals gesetzt und wenn ja, wo?
if SHGetFileInfo(PChar(TreeDataKlassen[Node^.Index].PfadSpalte1), FILE_ATTRIBUTE_NORMAL, Info, SizeOf(TSHFileInfo), SHGFI_SYSICONINDEX or SHGFI_ICON or SHGFI_SMALLICON) = 0 then
begin ImageIndex := TreeDataKlassen[Node^.Index].IconIndexSpalte1; // Eigentlich müsste das Icon angezeigt werden, wird es aber nicht. end; Übrigens:
Delphi-Quellcode:
List sollte
procedure AddAllFilesInDir(const Dir: string; var List: TStringList);
Delphi-Quellcode:
sein, nicht
const
Delphi-Quellcode:
, denn es soll ja nicht der Zeiger zur Liste geändert werden (können) sondern nur deren Inhalt.
var
Grüße Dalai |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Der Code da ist unwichtig, ist ein Fehler beim Kopieren passiert.
Es funktioniert ja ohnehin nicht, egal was ich mache und ob da jetzt eine Zuweisung fehlt. Ich habe dieses Minimalbeispiel nur gebaut um grob zu zeigen wie alles aufgebaut ist. Und in der Hoffnung, dass ihr mir helfen könnt, SHGetFileInfo() dort richtig einzubauen. So bekomme ich was angezeigt aber es ruckelt, zuckelt und führt sicher wieder zu Fehlern. Was ich gerade bestätigen konnte: ein Doppelklick auf den Trenner nach Spalte 1 führt zum Einfrieren und OutOfResources; aus Vcl.Graphics wird aufgerufen.
Delphi-Quellcode:
procedure TForm1.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: TImageIndex);
var Info: TSHFileInfo; begin if (not(Column in [0, 1])) or (not Assigned(TreeDataKlassen)) then Exit; if Kind in [ikNormal, ikSelected] then begin if TreeDataKlassen[Node^.Index].IconIndexSpalte1 = -1 then begin SHGetFileInfo(PChar(TreeDataKlassen[Node^.Index].PfadSpalte1), FILE_ATTRIBUTE_NORMAL, Info, SizeOf(TSHFileInfo), SHGFI_SYSICONINDEX or SHGFI_ICON or SHGFI_SMALLICON) ; TreeDataKlassen[Node^.Index].IconIndexSpalte1 := Info.iIcon; end; ImageIndex := TreeDataKlassen[Node^.Index].IconIndexSpalte1; end; end; Zitat:
|
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Zitat:
Ich sagte aber schon woran es liegt das Hicon wird nicht freigegeben. Und einiges fehlt noch. Ich kann hier 10000 Einträge laden ohne das irgendein Problem beim zeichnen hier auftritt. |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Zitat:
|
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
preview.. 40566 Dateien scrolle ich ohne Probleme.
Kein Abstürze oder dergleichen. Mit einer ImageList ![]() |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Kannst du mir zeigen, wie du das umgesetzt hast?
Hat jede Datei ein festes Icon oder das was zur Datei dazugehört und dynamisch bestimmt? |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Zitat:
Delphi-Quellcode:
SHGetFileInfo('', 0, Info, SizeOf(TSHFileInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_ICON or SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
Und zwar das des Laufwerks. Das liegt dran weil du keine Datei zum auswerten vorgibst. Dann verwendest du die falsche Funktion Du muss dafür jedoch noch Vcl.ImgList in den uses hinzufügen. Nicht VSTGetImageIndex sondern VSTGetImageIndexEx
Delphi-Quellcode:
in create
procedure TForm1.VSTGetImageIndexEx(Sender: TBaseVirtualTree;
Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: TImageIndex; var ImageList: TCustomImageList); var Info: TSHFileInfo; begin if (not(Column in [0, 1])) or (not Assigned(TreeDataKlassen)) then Exit; if Kind in [ikNormal, ikSelected] then begin ImageIndex := TreeDataKlassen[Node^.Index].IconIndexSpalte1; // Den aktuellen Index der Node end; end;
Delphi-Quellcode:
Du kannst das Hicon noch freigeben nach FreeAndNil(Icon)SmallImages := TImageList.Create(Self); SmallImages.ShareImages := True; VST.Images := SmallImages; VST.Images.ColorDepth := cd32Bit; // Unbedingt wichtig damit du keinen schwarzen Hintergrund bei den Icons hast VST.Images.DrawingStyle := dsTransparent; // Transparenz einschalten // ********* TreeDataKlassen.Add(TreeData); ZeroMemory(@Info, SizeOf(TSHFileInfo)); // Speicher bereinigen SHGetFileInfo('', 0, Info, SizeOf(TSHFileInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_ICON or SHGFI_SYSICONINDEX or SHGFI_SMALLICON); //Icon Holen if Info.hIcon <> 0 then begin Icon := TIcon.Create; Icon.Handle := Info.hIcon; VST.Images.AddIcon(Icon); // VST.Images = SmallImages FreeAndNil(Icon); end;
Delphi-Quellcode:
DestroyIcon(Info.hIcon);
glaube aber nicht das dass nötig ist weil TIcon ja nach der Übergabe der Eigentümer des handle ist und es auch frei gibt bei Free. Ich hoffe du kommst klar. teste es mit deinem minimalen Sample. Dein Projekt zurück.. wenn es hilft gut wenn nicht ab in die Tonne. Siehe meine Kommentare im code Habe genug mit dem Kram rum gespielt. Canvas erlaubt das zeichnen nun wieder sogar mit Icons Meine Meinung VirtualStringTree ist einfach nur müll es ist nicht möglich an den Index der Node zu kommen. So wie du das gerne möchtest ist es nicht möglich. |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Zitat:
Ich weiß noch immer nicht, wie ich SHGetFileInfo richtig anwende, sodass ich jeweils das Icon habe, was zur Datei gehört. Kommt das einfach in VSTGetImageIndexEx? Dann hab ich ja wieder die Ruckler und Aussetzer. |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
@Dolly: Evtl. hilft dir das, wenn nicht war es ein Versuch :)
So mache ich es in Lazarus (ohne ):
Delphi-Quellcode:
So habe ich es vorher in Delphi gemacht:
LargeIco, SmallIco : hIcon;
... ExtractIconEx(PChar(Pfad\Datei.exe), 0, LargeIco, SmallIco, 1); Icon.Handle := LargeIco; Icon.Transparent := True; ToolI.Picture.Icon := Icon;
Delphi-Quellcode:
icon : TIcon;
Filter : word; ... Icon := TIcon.Create; try Icon.Handle:=ExtractAssociatedIcon(hInstance, PChar(ToolE.Text), Filter); ToolI.Picture.Icon := icon; finally icon.Free; end; |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Zitat:
![]() Ich würde in dem Fall evtl. einen IconCache anlegen und dem beim Erstellen der Dateiliste füllen. Beim Zeichnen in OnGetImageIndex musst du dann nur noch den ImageIndex angeben. Kommt ein Dateityp hinzu der noch nicht in deinem IconCache enthalten ist, dann wird der hinzugefügt. Beim Zeichnen im Tree kannst du evtl. noch ein Fallback einbauen, dass ein Standardicon angezeigt wird, wenn der Thread Aufruf von SHGetFileInfo noch nicht abgeschlossen ist. Das ist jetzt alles nur Theorie. Ich habe keinen SourceCode hierfür. Aber so sollte es funktionieren. |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Damit habe ich dasselbe Problem wie mit SHGetFileInfo. Alles ruckelt und ist langsam gefolgt von seltsamen Canvas-Fehlern.
IconCache? Klingt irgendwie kompliziert und für mich nicht umsetzbar. Obwohl es interessant klingt. Würde man da einfach alle Dateiendungen die es gibt durchgehen, SHGetFileInfo aufrufen und sich das Info.iIcon holen? Ich habe das jetzt so und es ruckelt ohne Ende.
Delphi-Quellcode:
Wie man da mit der ImageList arbeiten soll, ist für mich immer noch ein großes Geheimnis.
procedure TForm1.VSTInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
var Info: TSHFileInfo; begin Node.SetData<TTreeData>(TreeDataKlassen[Node.Index]); if TreeDataKlassen[Node^.Index].IconIndexSpalte1 = -1 then begin SHGetFileInfo(PChar(TreeDataKlassen[Node^.Index].PfadSpalte1), FILE_ATTRIBUTE_NORMAL, Info, SizeOf(TSHFileInfo), SHGFI_SYSICONINDEX or SHGFI_ICON or SHGFI_SMALLICON); TreeDataKlassen[Node^.Index].IconIndexSpalte1 := Info.iIcon; end; end; procedure TForm1.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: TImageIndex); begin if (not(Column in [0, 1])) or (not Assigned(TreeDataKlassen)) then Exit; if Kind in [ikNormal, ikSelected] then begin ImageIndex := TreeDataKlassen[Node^.Index].IconIndexSpalte1; end; end; |
AW: VirtualStringTree - SHGetFileInfo hängt Programm auf / Canvas erlaubt kein Zeichn
Delphi-Quellcode:
Es wird immer ruckeln und du wirst immer die Ressourcen Probleme haben, von wegen kann nicht auf das Canvas zeichnen.
SHGetFileInfo(PChar(TreeDataKlassen[Node^.Index].PfadSpalte1), FILE_ATTRIBUTE_NORMAL, Info, SizeOf(TSHFileInfo), SHGFI_SYSICONINDEX or SHGFI_ICON or SHGFI_SMALLICON);
TreeDataKlassen[Node^.Index].IconIndexSpalte1 := Info.iIcon; Es hat ganz einfach damit zu tun das du sehr viele Handles in den Speicher lädst und sie nicht freigibst. Sorry aber du kannst das auf diese weise niemals in den griff bekommen weil Windows das nicht zulässt. Und bedenke irgendwann ist das Limit an Handles erreicht und dann geht bei dir gar nichts mehr. Und ja es gibt eine Beschränkung wie viele Handles ein Anwendung verwenden darf. Genau wie dein vorheriges SystemImageList := SHGetFileInfo was zur folge hatte das überhaupt keine Icons geladen wurden. Wie dem auch sei.. Tut mir leid für dich aber das ist der falsche weg. Das VirtualStringTree macht es einen aber auch besonders schwer weil man nicht auf den Index jeder Node hin prüfen kann. Deshalb macht eine ImageList auch keinen sinn wenn man sie mit nichts vergleichen kann. Nun ist halt so. Zitat:
Wenn das gehen würde..
Delphi-Quellcode:
If ImageList.ImageIndex = NOde^.Index then
aber selbst das funktioniert nicht! Eine andere Lösung habe ich auch nicht gefunden. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:45 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