SHGETFILEINFO - Problème

Programmation d'applications complexes
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

SHGETFILEINFO - Problème

Message par Le Soldat Inconnu »

Je cherche à réduire l'esppace mémoire de mes programmes à moi qui sont toujours en mémoire (des barres de boutons)

Et j'ai trouvé une fonctions qui me bouffe 2.5 Mo de mémoire à elle toute seule 8O
il s'agit de SHGETFILEINFO

voir cet exemple, j'ai affiché en commentaires l'espace mémoire occupée après chaque fonction en ko

Code : Tout sélectionner

Procedure.l ExtractLargeIconFile2(IconPath.s) ; Extraire l'icône 32*32 d'un fichier
  ; Cette procedure permet d'extraire l'ID de l'icône 32*32 associé au type de fichier ou au dossier dont l'adresse est IconPath
  hImageList = SHGetFileInfo_(IconPath, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_SYSICONINDEX | #SHGFI_ICON | #SHGFI_LARGEICON)
; hImageList est le handle de l'ImageList
  
  ProcedureReturn InfosFile\hIcon
EndProcedure


OpenWindow(0, 0, 0, 100, 100, #PB_Window_ScreenCentered | #PB_Window_SystemMenu, "Test") ; 1364

CreateGadgetList(WindowID()) ; 1376

Icone = ExtractLargeIconFile2("c:\") ; 3944 (+2568 Arg)
ImageGadget(0, 0, 0, 32, 32, Icone) ; 3984

Repeat
  Event = WaitWindowEvent()

Until Event = #PB_Event_CloseWindow
Je pense que ces 2.5 mo correspondent à l'ImageList des icônes mais comment la supprimer une fois qu'on n'en a plus besoin ?

Je n'y arrive pas.
J'ai essayé avec ImageList_Destroy mais je n'obtients aucun résultat :cry:

Si quelqu'un peut m'aider.

Car 2.5mo, c'est pas négligeable et *2 programmes, ça fait 5mo de gagner.

Merci d'avance
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

ImageList_Destroy (hImageList)

Mais je pense que tu as le handle de la listimage systeme et si tu la détruit, l'exploreur n'aura plus d'icônes.

Fait un essai
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

j'ai dit que ImageList_Destroy ne marche pas :roll:
pourtant, la fonction marche (elle renvoie 1)

Code : Tout sélectionner

ProcedureDLL.l ExtractLargeIconFile2(IconPath.s) ; Extraire l'icône 32*32 d'un fichier
  ; Cette procedure permet d'extraire l'ID de l'icône 32*32 associé au type de fichier ou au dossier dont l'adresse est IconPath
  hImageList = SHGetFileInfo_(IconPath, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_SYSICONINDEX | #SHGFI_ICON | #SHGFI_LARGEICON)
  Debug hImageList
  Debug ImageList_Destroy_(hImageList)
  ProcedureReturn InfosFile\hIcon
EndProcedure


OpenWindow(0, 0, 0, 100, 100, #PB_Window_ScreenCentered | #PB_Window_SystemMenu, "Test") ; 1364

CreateGadgetList(WindowID()) ; 1376

Icone = ExtractLargeIconFile2("c:\") ; 3944 (+2568 Arg)
ImageGadget(0, 0, 0, 32, 32, Icone) ; 3984

Repeat
  Event = WaitWindowEvent()

Until Event = #PB_Event_CloseWindow
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Le Soldat Inconnu a écrit :j'ai dit que ImageList_Destroy ne marche pas :roll:
pourtant, la fonction marche (elle renvoie 1)
J'avais pas tout lu :oops:


Tu récupères d'après la doc MS le handle de la liste image système.
Il me semble avoir fait des essais il y a quelque temps et si je détruisais la liste, l'exploreur de fichier n'affichait plus d'icônes, mais il me semble que c'était sous WIN98.

De toute façon, il ne faut pas détruire la listimage système.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Si ça ajoute 2.5 mo à mon programme, c'est que l'imagelist n'est pas système mais spécifique au programme, non ?
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Je ne sais pas

La doc MS dit
Note Once you have a handle to a system image list, you can use the Image List API to manipulate it like any other image list. Because system image lists are created on a per-process basis, you should treat them as read-only objects. Writing to a system image list may overwrite or delete one of the system images, making it unavailable or incorrect for the remainder of the process.
ce qui n'explique pas pourquoi ImageList_Destroy ne supprime pas la liste alors que les API modifient cette liste.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

tu comprends quoi toi de ce charabia
are created on a per-process basis, you should treat them as read-only objects
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Je ne sait pas si ça a un sens ma traduction

Que la list image système est créé comme étant un élément de base d'un process et on ne devrait intervenir sur cette image list que pour des opérations de lecture sinon ça pourrait modifier le process qui a créé cette liste d'image.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Bon, une remarque vraiment bizarre

voilà, plutot que de récupérer le handle de l'icône, j'ai décomposé

donc j'ai fait un exe qui récupère l'emplacement du fichier qui contient l'icône qui met nécessaire et qui l'écrit dans un fichier .ini
puis je lance ce programme au début du programme principal, j'attend qu'il se termine

bon, la récupération de l'icône marche qu'avec les exe et ico, bon dommage mais ce qui est étrange, c'est cela :

toujours 4 mo en mémoire

je lance le programme qui récupère l'emplacement de l'icone au début du programme principal donne 4mo
je le programme principal sans lancer le programme qui récupère l'emplacement de l'icone (juste en gardant le fichier .ini qui contient l'adresse des icônes), j'obtiens 2mo

c'est bizarre comme fonctionnement ?
Windows alloue direct l'imagelist au prog principal alors que c'est pas lui qui l'utilise ?

Vous y comprenez quelque chose ?
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
DominiqueB
Messages : 47
Inscription : sam. 01/mai/2004 14:41

Salut !

Message par DominiqueB »

J'ai ce petit bout de code que j'utilise dans un prog en PowerBasic,
je penses qu'il va t'aider:

Code : Tout sélectionner

;Ce petit bout de procédure permet de diminuer beaucoup la taille de la mémoire utilisée. 
hProcess.l = OpenProcess_(#PROCESS_ALL_ACCESS, 0, GetCurrentProcessId_()) 
SetProcessWorkingSetSize_(hProcess, -1, -1) 
CloseHandle_(hProcess) 

Met le juste après l'appel à la fonction ImageGadget().
J'espère que ca va t'aider !

Ton bout de code n'occupe plus que 1256 au lieu de 4352 en mémoire !

Tu sais que si tu réduit puis agrandit une fenêtre la taille de ton prog
ne tient plus que 800 en mémoire ?

J'ai posté aussi ce texte sur le site anglais.

Dominique
Dominique
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

c'est génial ce truc, je teste de suite, merci :D
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

La valeur de la constante #PROCESS_ALL_ACCESS est $1F0FFF

chez moi, il reste 540 ko en mémoire :D
yepee, extra super génial. Allez je t'embrase. smack smack :roll: :lol:

je vais coller ça partout dans mes programmes, ça va pas tarder :wink:
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
DominiqueB
Messages : 47
Inscription : sam. 01/mai/2004 14:41

cool !

Message par DominiqueB »

ya pas de quoi,
avec tous les progs gratuits que tu fais, je suis heureux de pouvoir
renvoyer l'ascenseur de temps en temps !

A+

Dominique
Dominique
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Je peux le mettre sur 2DEV ?
Je m'occupe de faire un exemple pour illustrer :wink:
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
DominiqueB
Messages : 47
Inscription : sam. 01/mai/2004 14:41

oui

Message par DominiqueB »

Bien sur, tu peux !

A+

Dominique
Dominique
Répondre