[Visual C++] Question (basique) sur les CPen

Question (basique) sur les CPen [Visual C++] - C++ - Programmation

Marsh Posté le 19-02-2004 à 11:15:17    

Salut,
 
dans mon programme, je déclare un CPen comme ceci :
 

Code :
  1. CPen blackPen;


 
Je n'initialise ce CPen que sous une certaine condition :
 

Code :
  1. if (drawBlack){
  2. CPen.CreatePen(PS_SOLID, 2, RGB(0,0,0));
  3. pOldPen = pDC->SelectObject(&blackPen);
  4. }


 
Ma question est de savoir si, après utilisation de mon nouveau CPen (je l'utilise bien s^ûr que si la condition drawBlack est validée, est ce que je dois appeler  

Code :
  1. CPen.DeleteObject();

dans tous les cas ou alors seulement si la condition drawBlack est validée (apres bien avoir resélectionné pOldPen dans le DC!
 
En bref, faut il utiliser pour le CPen la méthode DeleteOject dans tous les cas ou alors seulement si le CPen est initialisé, avec CreatePen par exemple?
 
Merci.

Reply

Marsh Posté le 19-02-2004 à 11:15:17   

Reply

Marsh Posté le 19-02-2004 à 13:15:16    

Les objets GDI se détruisent eux même quand ils sont hors du scope dans lequel ils ont été définis, donc tu n'as pas besoin d'appeler toi même DeleteObject(), une fois que ton objet sort du scope, cette fonction est appelée automatiquement. Tu dois donc déclarer ton CPen le plus tard possible, ou alors sur la pile (à l'intérieur d'une fonction) :
 

Code :
  1. if (drawBlack){
  2.    CPen blackPen;
  3.    CPen.CreatePen(PS_SOLID, 2, RGB(0,0,0));
  4.    pOldPen = pDC->SelectObject(&blackPen);
  5. }


Dans cet exemple, le CPen est détruit implicitement dés que tu sors de la condition if. Ceci marcherait aussi :
 

Code :
  1. void CMaClasse::MaFonction()
  2. {
  3.    CPen blackPen;
  4.    
  5.    if (drawBlack){
  6.       CPen.CreatePen(PS_SOLID, 2, RGB(0,0,0));
  7.       pOldPen = pDC->SelectObject(&blackPen);
  8.    }
  9. }


Ici, le CPen sera détruit automatiquement en sortie de fonction.


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 19-02-2004 à 13:41:37    

D'accord, merci:
 
Mais lorsque tu fais ça :
 

Code :
  1. if (drawBlack){
  2.   CPen blackPen;
  3.   blackPen.CreatePen(PS_SOLID, 2, RGB(0,0,0));
  4.   pOldPen = pDC->SelectObject(&blackPen);
  5. }


 
Ca ne pose pas de probleme que blackPen, qui est donc un objet du bloloc, soit détruit à la sortie du bloc, alors qu'il est encore attaché au DC?
 
Sinon, il reste quand même une question :
 
A quel moment est vraiment consommé la mémoire :
Lors de  
 

Code :
  1. CPen blackPen


 
ou alors lors de  
 

Code :
  1. blackPen.CreatePen(PS_SOLID, 2, RGB(0,0,0));


 
Pour ma part, si je devais répondre à la question, je drai lors de

Code :
  1. Pen blackPen


 
Et alors, je suppose que le  

Code :
  1. blackPen.CreatePen(PS_SOLID, 2, RGB(0,0,0));


 
se contente simplement d'affecter des données membres déja présentes en mémoire?
 
 
 
 
 

Reply

Marsh Posté le 19-02-2004 à 22:40:16    

Bon, c'est bon, je comprends mieux comment tout ce petit monde marche!
 
Par contre, y a un truc qui me gragrine : dans mon appli, je dois tracer un tas de formes géométriques, disons des lignes! Et je dois les tracer avec des traits identiques, si ce n'est la couleur qui change! Est ce que ca veut dire que pour chaque ligne, je suis obligé de créer un nouveau CPen, l'attacher au DC et ensuite le détrouire? Y a pas un moyen d'avoir main mise sur la structure du HPEN derrière et de juste changer sa couleur?

Reply

Marsh Posté le 20-02-2004 à 12:32:36    

Pour répondre à HArkonnen:
 
Quand tu me dis que le CPEn est détruit implictement en fin de bloc, il semble que ce ne soit pas le cas:
 
En effet, j'ai fait plein de tests depuis ce matin, et voici sans fdoute le plus probant :
 
Considère le code suivant:
 

Code :
  1. void CTestingGraphicsView::OnTest()
  2. {
  3. // TODO: Add your command handler code here
  4. const int NUM = 20480;
  5.         CPen* myPen = new CPen[NUM];
  6. for (int i = 0; i < NUM; i++){
  7.     myPen[i].CreatePen(PS_SOLID, 2, RGB(0,0,0));
  8. }
  9. delete[] myPen;
  10. }

 
 
En théorie, apres avoir lancé l'application et apres avoir exécuté la fonction membre OnTest, l'état de la mémoire (Working Set) devrait etre le meme qu'avant d'avoir exécuté la fonction, puisque les CPen, à la sortie de la boucle for, et a fortiori, à la sortie de la fonction, sont effacés!
Or en utilisant "Process Viewer", avant avoir exécuté la fonction, la taille du Working Set est de 192 ko alors qu'elle est de 268 ko apres avoir exécuté la fonction. Ce qui prouve qu'il y a un trou de 76 ko qui ont disparu (=> non effacés)
 
Maintenant, si je fais exactement le meme test, mais en mettant un myPen[i].DeleteObject() dans la boucle for, j'obtiens bien un Working Set de 192 ko avant et APRES avoir exécuté la fonction.
 
Il me semble donc qu'il est plus propre de faire un DeleeObject()  
 
Quelqu'un peut il confirmer?
 
 
 
 
 
}

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed