Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Beim Programmstart geht es, im Thread nicht? (https://www.delphipraxis.net/157926-beim-programmstart-geht-es-im-thread-nicht.html)

Mattze 30. Jan 2011 10:34

Beim Programmstart geht es, im Thread nicht?
 
Hallo,

ganz komisches Problem bei dem ich keine Idee habe. Vielleicht könnt Ihr mir helfen:
Ich habe mir eine Laufwerksleiste gebastelt, die eigentlich ganz ausgezeichnet funktioniert.
Die nötigen zusätzlichen Daten (z. Bsp. die Laufwerksiconen) wurden zuerst direkt (seriell im Programmabschnitt) ermittelt. Das ging sowohl beim Programmstart als auch bei Devicechange (Devicearrival) problemlos.
Nun habe ich aber von Microsoft die Empfehlung gelesen, dass man das möglichst per Thread machen sollt, um das Devicechange nicht zu überfrachten.
Also habe ich einen Thread gebastelt.
Der wird auch beim Programmstart für jedes Laufwerk ordentlich aufgerufen und baut alles, auch die richtigen Iconen richtig zusammen.
Aber nicht bei Devicearrival.
Er arbeitet mit (ImageIndex und hint sind vom erweiterten TButton)

ImageListHandle:=SHGetFileInfo(pchar(pidl),0,Finfo ,
sizeof(TSHFILEINFO),
SHGFI_PIDL or SHGFI_SysIconIndex or SHGFI_Icon or SHGFI_Smallicon or
SHGFI_displayname);

ImageIndex:=FInfo.iicon;
hint:=FInfo.szDisplayName;


szDisplayname, Typename funktionieren alle dufte. Nur das Icon kriegt er einfach nicht und wählt da ein Standardicon.

Frage(n):
Warum geht das zwar beim Programmstart richtig, aber nicht in Devicearrival?
Warum geht das beim Programmstart, aber nicht im Thread aus dem Programm?
Warum geht das nur für das Icon nicht, alles andere wird mit der gleichen Funktion im Thread aber ordentlich gesetzt?

Was kann man da tun?

Gruß
Matthias

himitsu 30. Jan 2011 10:44

AW: Beim Programmstart geht es, im Thread nicht?
 
Du greifst von einem Thread direkt auf die VCL zu?
Sowas macht man nicht, denn die VCL ist nicht threadsave! :warn:

Delphi-Referenz durchsuchenSynchronize

Mattze 30. Jan 2011 12:33

AW: Beim Programmstart geht es, im Thread nicht?
 
Richtig!
Ich habe es auch mit Synchronize probiert. Keine Änderung!
Und da alle anderen Werte (szDisplayname usw.) ordentlich "in der VCL" ordentlich gesetzt wurden, habe ich es wieder rausgenommen.
Er findet einzig und allein den Iconindex in der Systemimagelist nicht, obwohl vorhanden! Er setzt dann etwas anderes ein. (Genau: Nr. 7, während der richtige 271 hat!)
Beim Programmstart findet er ihn.
Das ist VOR der VCL. Das SHGetFileInfo hat sicher noch nicht allzu viel mit der VCL zu tun.
Warum der Unterschied?

Gruß
Mattze

himitsu 30. Jan 2011 12:48

AW: Beim Programmstart geht es, im Thread nicht?
 
Hmm, nee mit der VCL nicht, aber vor der VCL läuft auch alles noch im Hauptthread ab.

Was passiert, wenn du diese Funktion einfach mal direkt über einen Button aufrufst?

alfold 30. Jan 2011 12:53

AW: Beim Programmstart geht es, im Thread nicht?
 
Vielleicht ist es nur hier ein Schreibfehler?
ImageIndex:=FInfo.iicon;
Obwohl ja eigentlich Delphi bei Schreibfehler meckert :?

Ansonsten kann ich @himitsu nur zustimmen. Mal mit nen Button starten und debuggen und die Werte mal auslesen wo der Index geholt wird!

Gruss alfold

Mattze 30. Jan 2011 14:12

AW: Beim Programmstart geht es, im Thread nicht?
 
Hallo,

es ist kein Schreibfehler. In meiner Frage steht Finfo.iicon!

Nochmals: Der Witz und das Komische ist, dass das Icon mit dieser Methode völlig richtig bestimmt wird - nur nicht in Devicearrival.

1. Es war mal direkt (also ohne Thread) im Devicearrival kodiert. Kein Problem! Alles OK!
Dann habe ich das in einen Thread gepackt.

2. Beim Programmstart wird genau das gleiche mittels des Threads aufgerufen. Kein Problem! Alles OK! Das FInfo.iicon ist korrekt bestimmt.

3. Der gleiche Thread wird genau auf die gleiche Art wie beim Programmstart beim Devicearrival in Devicechange aufgerufen. Das Icon wird nicht gefunden. Stattdessen wir ein Standardicon zurückgeliefert. Für mich ist merkwürdig, dass aber FInfo.szDisplayname immer richtig gefunden wird.

Alle Klarheiten beseitigt? Es ist ziemlich schwierig zu beschreiben,
weil da zweimal genau das gleiche zu halb-unterschiedlichen Ergebnissen kommt.

Gruß
Mattze

PS: D7 pro, Windows 7 HP
Ich konnte die Iconnummern angeben, weil ich sie mir mal habe anzeigen lassen.

himitsu 30. Jan 2011 14:44

AW: Beim Programmstart geht es, im Thread nicht?
 
Es kann sein, daß Windows für jeden Thread eine eigene ImageList erstellt, somit wäre es möglich, daß die Liste im Thread eine andere ist, als die im Hauptthread.

Jedes Programm hat ja auch seine eigene SystemImageList, wobei ich auf diese bisher immer nur im Hauptthread zugriff, also vielleicht doch nicht nur je Programminstanz, sondern direkt für jeden Thread (damit Windows da nichts gegen Threads absichern mußte).

Wenn dem so ist, dann bleiben nur zwei/drei Möglichkeiten:
- das Auslesen in den Hauptthread verlagen
- die Icons im Thread auslesen und in je ein TIcon kopieren
- oder die Icons im Thread auslesen und an eine programmeigene TImageList kopieren

Mattze 30. Jan 2011 14:52

AW: Beim Programmstart geht es, im Thread nicht?
 
Hallo,

kleine Ergänzung und Einschränkung:
Ich habe es eben unter XP probiert und nun scheint sich zu zeigen, dass es wirklich nur bei USB-Sticks daneben geht.
Bei neuer DVD in das DVD-LW oder der externen (schon beim Start angeschlossenen) USB-HD kommt auch das richtige Icon.
Beim USB-Stick, wenn er vor dem Programmstart schon angeschlossen ist, auch.
Das richtige Icon wird eben "nur" nicht gefunden, wenn der USB-Stick erst während des Programmlaufs angesteckt wird. Und das unabhängig davon, ob das Icon schon in der Systemimagelist steht oder nicht. (Beim Windows-Explorer funktioniert es aber richtig!)

Nur der Vollständigkeit halber:
Das Icon steht in der Wurzel auf dem Stick und ist dort in die Autorun.inf eingetragen. Ob das ein Geschwindigkeitsproblem ist?
Wie gesagt, wenn ich das nicht über Thread mache, sondern das, was in execute steht, direkt ausführen lasse, funktioniert es!?

Mattze 30. Jan 2011 14:58

AW: Beim Programmstart geht es, im Thread nicht?
 
Hallo,

danke!
Das werde ich mal probieren.
Es wäre aus Sicherheitsgründen des Systems sogar verständlich, dass jeder Thread auch eine eigene "Systemimagelist" hat.
Ich werde das nachher mal probieren.

Aber wie macht das dann der Explorer? Ich dachte eigentlich, dass der sowas auch über einen Thread macht...

Ich melde mich...

Gruß
Mattze

Mattze 30. Jan 2011 15:41

AW: Beim Programmstart geht es, im Thread nicht?
 
Hm...
Mir fällt gerade auf, dass es mit der eigenen Imagelist pro Thread wahrscheinlich nicht sein kann.
Wie gesagt:
Ist der USB-Stick beim Programmstart dran, ist auch das richtige Icon da, obwohl das genau über diesen Thread eingebaut wird!
Wenn der USB-Stick mal dran war, steht dessen Icon auch schon in der Systemimagelist. Angezeigt wird es aber nicht, wenn der Stick dann nach Programmstart nochmal eingesteckt wird. Also auch das Kopieren der Systemimagelist in eine Threadimagelist kann es nicht sein.

Also, ich sehe da nicht durch! Irgendwas fehlt mir da. Der Explorer kann es doch auch und der macht es sicherlich auch per Thread...

Gruß
Mattze


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:27 Uhr.
Seite 1 von 2  1 2      

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