Libération des HBRUSH créé via CreateSolidBrush [API Win32]

Résolu
stagiairecpp Messages postés 37 Date d'inscription jeudi 22 octobre 2009 Statut Membre Dernière intervention 10 décembre 2011 - 1 nov. 2009 à 15:01
stagiairecpp Messages postés 37 Date d'inscription jeudi 22 octobre 2009 Statut Membre Dernière intervention 10 décembre 2011 - 1 nov. 2009 à 17:30
Bonjour,

J'aurais une question, si vous voulez bien m'aider, qui porte sur les objets gdi créés via l'api windows CreateSolidBrush.
Pour info préliminaire (si ça change quelquechose mais je ne pense pas) j'ai choisi de réaliser ce projet en C (/TC).

Donc,
dans le très instructif exemple de racpp (merci :) sur la transparence et les couleurs des contrôles, racpp déclare et instancie ses HBRUSH dans le CALLBACK de sa fenêtre principale de la sorte :
BOOL CALLBACK DialogProc(  HWND hDlg, UINT message, WPARAM wParam,LPARAM lParam  )
{
static HBRUSH hbDialog = CreateSolidBrush(RGB(200,175,100));
...

C'est très pratique, je connaissais l'utilisation du préfixe 'static' pour les méthodes en cpp mais pas pour les variables.
Après 2 ou 3 tests je pense avoir compris que ça permet de ne l'initialiser que lors du premier appel.
Bon, comme mon projet est en C je ne fais pas comme ça, je déclare les HBRUSH en global et je les initialise lorsque la fonction CALLBACK de ma fenêtre principale reçoit le message WM_INITDIALOG (elle ne reçoit pas le message WM_CREATE comme je passe par DialogBoxParam pour la créer).
Ca fonctionne très bien.

Mais,
voilà, je voudrais créer mes HBRUSH en fonction de certains paramètres dynamiques. Je fais ça via CreateSolidBrush :
HBRUSH hBrush;
//...et plus loin...
hBrush= CreateSolidBrush(RGB(r,g,b));

Seulement lorsque le HBRUSH vient à changer et que j'en recrée un autre, je n'arrive pas à libérer le précédent.
- DeleteObject((HGDIOBJ)hBrush) -> renvoie systématiquement NULL
- DeleteObject(SelectObject(???,hBrush)) -> je ne sais pas quoi mettre à la place des '???' vu qu'il s'agit d'un controle en ressource, et avec sont handle ça ne fontionne pas non plus

Je me retrouve donc avec une dramatique fuite d'objets gdi qui fait rapidement péter la limite des 9999 et qui fait donc bugguer l'application.

L'un d'entre vous saurait'il comment faire svp ?
J'imagine que c'est du déjà vu mais je n'ai pas trouvé.

Merci d'avance.

@+

5 réponses

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
1 nov. 2009 à 15:41
Tombe bien, le code de racpp est aussi en C...
Il n'y a généralement pas un iota de C++ dans ses codes, c'est idéal pour les débutants (et les autres) car rien n'est caché derrière qlq bibli que ce soit.

static HBRUSH hbEdit = ...
dans une fonction est une fantaisie du langage C, rien de plus. On déclarerait hbEdit en global en haut du module sans le mot 'static' que ça ne changerait absolument rien au binaire final, c'est d'ailleurs ce que le compilo fera quand il génèrera l'ASM final.
La différence, seulement pendant la phase de dev, ces params sont inaccessibles en dehors de la fonction qui les déclare.

Jette un oeil ici:
CHOIX COULEURS (WIN32, NON MFC)
http://www.cppfrance.com/code.aspx?id=10501
Tout ce qui t'intéresse est dans RgbTest.cpp

ciao...
BruNews, MVP VC++
3
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
1 nov. 2009 à 17:05
Il est vrai que racpp compile en mode C++ sinon ça ne passerait pas. Hormis cela tout est pru C.

Les profs récitent les tabous à la mode, il convient de ne pas les contrarier tant que tes notes dépendent d'eux, plus tard tu pourras en rire.

ciao...
BruNews, MVP VC++
3
stagiairecpp Messages postés 37 Date d'inscription jeudi 22 octobre 2009 Statut Membre Dernière intervention 10 décembre 2011 15
1 nov. 2009 à 15:09
Re,

J'ai oublié de préciser que j'ai également essayé via :
- DeleteObject(GetStockObject(hBrush)) -> Ne fonctionne pas non plus

@+
0
stagiairecpp Messages postés 37 Date d'inscription jeudi 22 octobre 2009 Statut Membre Dernière intervention 10 décembre 2011 15
1 nov. 2009 à 16:33
Re,

Pour le 'static', effectivement c'est ce que je fais, je déclare en haut du module et ça a l'avantage de rendre les brushs utilisables depuis n'importe quelle autre fonction du module.
Par contre je pense que la syntaxe est vraiment propre au cpp parce qu'en compilant en C (/TC) ça ne passe pas -> erreur: l'initialisateur n'est pas une constante...'. En changeant les options de compilations pour spécifier du code cpp (/TP) ça le tolère, plus de soucis à la compilation.

J'en profite pour te demander si ça ne cause pas de soucis de déclarer des variables en haut de module à l'extérieur de toutes fonctions, parce qu'un prof nous avait dit que c'était à proscrire sans d'avantages d'explications ?

En tous cas merci beaucoup, je m'en vais de ce pas regarder ta source. :)
Je reprendrai ce sujet si je rencontre une difficulté de compréhension (je dois t'avouer que desfois tes codes sont un peu obscurs pour moi...).

Merci.

@+
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
stagiairecpp Messages postés 37 Date d'inscription jeudi 22 octobre 2009 Statut Membre Dernière intervention 10 décembre 2011 15
1 nov. 2009 à 17:30
Re,

Merci pour la précision sur les déclarations globales. C'est tellement pratique dans certains cas (le handle de la fenêtre principale est un exemple parmi tant d'autres) que ça aurait été dommage de s'en priver.

Pour le reste j'ai bien regardé ton code source et...
Ben tu utilises simplement et efficacement un DeleteObject sur le HBRUSH (ma première idée) !
Donc j'ai décommenté mes lignes et ça fonctionne parfaitement . Je ne comprends pas, je devais avoir un petit pet quelque part ou une crotte dans les yeux tout à l'heure parce que j'avais éliminée cette solution.

Merci, sans toi j'aurais essayé un paquet d'autres choses avant de revenir à cette solution qui s'avère être la bonne.

@+
0
Rejoignez-nous