Bitmap qui disparait

Bitmap qui disparait - C++ - Programmation

Marsh Posté le 15-07-2005 à 16:17:39    

Bonjour à tous :hello:
 
j ai un petit probleme avec l affichage d une bitmap......
en fait elle s affiche très bien, et se réaffiche très bien après avoir perdu le focus, MAIS quand je deplace une autre fenetre (j ai découvert ca avec la calculette de windows :D) de l exterieur de la bitmap a l interieur.....la bitmap ne se reaffiche pas et est remplacée par le fond...... :pt1cable:
 
voici le code qui l'affiche :
 

Code :
  1. BITMAP bmpInfo;
  2. hbitmap=(HBITMAP) LoadImage(NULL,"Goban.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
  3. hdcMemory=CreateCompatibleDC(NULL);
  4. SelectObject(hdcMemory,hbitmap);
  5. GetObject(hbitmap, sizeof(bmpInfo), &bmpInfo);
  6. StretchBlt(hdc,0,0,zoneclient.bottom,zoneclient.bottom,hdcMemory,0,0,bmpInfo.bmHeight,bmpInfo.bmWidth,SRCCOPY);


 
je ne sais pas si ca vien de la ou si c est un bug de je sais pas quoi :D
 
Donc voila si quelqu un a une idee pour regler ce petit probleme (fort peu genant mais bon :) )....
Merci :jap:

Reply

Marsh Posté le 15-07-2005 à 16:17:39   

Reply

Marsh Posté le 15-07-2005 à 18:02:20    

Invalidate() et InvalidateRect() permette de forcer un refresh d'une fenetre ou d'un widget. A toi de voir ou les utiliser.


Message édité par Joel F le 15-07-2005 à 18:02:44
Reply

Marsh Posté le 15-07-2005 à 18:18:14    

heu.... donc si j en met un au début du WM_PAINT, logiquement ca devrait marcher si je comprend bien ce que tu me dis?
J'essairai ca tout a l heure :)
 
merci bien :jap:

Reply

Marsh Posté le 15-07-2005 à 18:50:02    

Le mettre la d'office risque de faire clignoter l'appli. Je crosi qu'il y a un event précis pour ça.

Reply

Marsh Posté le 15-07-2005 à 21:23:08    

en effet ca fait tout clignoter...c est pas top :D
d autant plus que ca ne resoud meme pas le probleme :/
sauf que maintenant au lieu d effacer juste une partie de l image ca efface tout d un coup :D
 
je ne vois pas de quel event tu parles...tu peux preciser un peu stp :) (je sui "un peu" noob :o :D)
jvai voir un peu ce que je peux trouver comme event qui pourrai correspondre.... :)
 
merci encore :)

Reply

Marsh Posté le 15-07-2005 à 22:27:06    

StretchBlt(hdc, 0, 0, zoneclient.bottom, zoneclient.bottom, hdcMemory, 0, 0, bmpInfo.bmHeight, bmpInfo.bmWidth, SRCCOPY);
 :ouch:

Reply

Marsh Posté le 15-07-2005 à 22:39:08    

ben quoi?
spabien? :D
c estjuste pour redimensionner l image a la taille de la zone client...je vois pas ce qui te choque?

Reply

Marsh Posté le 15-07-2005 à 23:05:00    

est ce que ca peut venir de cette ligne :
 
hdcMemory=CreateCompatibleDC(NULL);
 
?
Parce que j ai pas encore bien compris les hdc et cette ligne est un authentique copier-coller :D

Reply

Marsh Posté le 16-07-2005 à 12:19:57    

je te recommande cette petite lecture :)
 
http://msdn.microsoft.com/library/ [...] s_9cok.asp
 
Tu verras que tes parametres sont pas tres cohérents.


Message édité par retrox le 16-07-2005 à 12:20:12
Reply

Marsh Posté le 16-07-2005 à 13:32:00    

ben en fait j ai fait comme ca parce que mon image est carrée donc pour ne pas la déformer je l ai adaptée a la hauteur de l ecran (parce que en general les ecrans sont plus larges que haut :) ) donc c est pour ca que j ai mis zoneclient.bottom pour la largeur et ca marche plutot bien :)
mais s il y a un autre moyen je suis tout ouï :D
 
et pour la disparition de l image tu n as pas d idée?
j ai pas trouvé l event dont parlait Joel F :(

Reply

Marsh Posté le 16-07-2005 à 13:32:00   

Reply

Marsh Posté le 16-07-2005 à 14:15:24    

Le code que tu as fourni, c'est bien le code de WM_PAINT?
 
Au fait il faut mémoriser l'ancien bitmap retourné par SelectObject(HDC, HGDIOBJECT) puis le restaurer quand tu as fini.
 
Pour finir, tu ne devrais pas libérer le HBITMAP retourné par LoadImage par hasard?
Et le

hdc

dans ton code il sort d'où?
 
Il faudrait au mieux que tu déclares le HBITMAP comme attribut de la classe, que tu l'initialises dans le WM_CREATE et que tu le libères dans WM_DESTROY.


Message édité par slash33 le 16-07-2005 à 14:27:05
Reply

Marsh Posté le 16-07-2005 à 14:29:05    

Sinon jette un coup d'oeil sur les boîtes "A propos..." personnalisées. C'est une technique employée fréquemment et la MSDN la traite.

Reply

Marsh Posté le 16-07-2005 à 18:44:51    

slash33 a écrit :

Le code que tu as fourni, c'est bien le code de WM_PAINT?
 
Au fait il faut mémoriser l'ancien bitmap retourné par SelectObject(HDC, HGDIOBJECT) puis le restaurer quand tu as fini.
 
Pour finir, tu ne devrais pas libérer le HBITMAP retourné par LoadImage par hasard?
Et le

hdc

dans ton code il sort d'où?
 
Il faudrait au mieux que tu déclares le HBITMAP comme attribut de la classe, que tu l'initialises dans le WM_CREATE et que tu le libères dans WM_DESTROY.


 
pfiou!
j ai lu ton post plusieurs fois et ben....j ai rien compris! [:alvas]
 
Alors :
-oui c est bien le code de WM_PAINT :)
-je comprend pas ton histoire de memoriser l ancien bitmap.... y en a pas avant celui là si :??:
-ca se libere comment un HBITMAP? :D (ca je dois pouvoir trouver facilement sur google je pense :jap: )
-de quelle classe parles-tu pour le HBITMAP?
 
Bon je vais poursuivre mes investigations en attendant ta reponse :D
 
EDIT : J ai oublié de repondre pour le hdc :D
il vien de là :

Code :
  1. case WM_PAINT:
  2.     PAINTSTRUCT ps;
  3.    HDC hdc;HDC hdcMemory;


Message édité par T'CHATTE le 16-07-2005 à 18:47:43
Reply

Marsh Posté le 16-07-2005 à 20:34:22    

Je ne vois pas ce qu'il y a de drôle ce sont pourtant les termes consacrés.
 

Code :
  1. LRESULT APIENTRY WndProc(HWMD hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  2. {
  3.   PAINTSTRUCT ps;
  4.   HDC hDC;
  5.   switch(message)
  6.   {
  7.   case WM_PAINT:
  8.     hDC = BeginPaint(hWnd, &ps);
  9.     if (hDC == NULL)
  10.     {
  11.       // erreur à traiter
  12.     }
  13.     HBITMAP hBitmap = LoadImage(
  14.        NULL,
  15.        "Goban.bmp",
  16.        IMAGE_BITMAP,
  17.        0,0,
  18.        LR_LOADFROMFILE);
  19.     if (hBitmap == NULL)
  20.     {
  21.       // erreur à traiter
  22.     }
  23.     HDC hMemDC = CreateCompatibleDC(NULL);
  24.     if (hMemDC == NULL)
  25.     {
  26.       // erreur à traiter
  27.     }
  28.     // sélectionne le bitmap
  29.     HBITMAP hPrevBitmap = SelectObject(
  30.        hMemDC, hBitmap);
  31.     // on peut dessiner maintenant
  32.     BITMAPINFO bmpInfo;
  33.     GetObject(hBitmap, sizeof(bmpInfo), &bmpInfo);
  34.    
  35.     RECT rcClient;
  36.     GetClientRect(&rcClient);
  37.     StretchBlt(hDC,
  38.        0,0,
  39.        rcClient.right,rcClient.bottom,
  40.        hMemDC,
  41.        0,0,
  42.        bmpInfo.bmWidth,bmpInfo.bmHeight,
  43.        SRCCOPY);
  44.     // sélectionne le bitmap précédent
  45.     SelectObject(hMemDC, hPrevBitmap);
  46.     // libére le bitmap sinon tu grilles des  
  47.     // handles limités sous Win 98
  48.     DeleteObject(hBitmap);
  49.     // libère le DC temporaire
  50.     DeleteDC(hMemDC);
  51.     EndPaint(hWnd, &ps);
  52.     break;
  53.     // Process other messages (comme dit la MSDN)
  54.   }
  55. } // fin de WndProc


 
Voilà c'est fait en live et je connais plus les MFC que la WIN32 classique alors il y a peut-être des erreurs, il y aura bien quelqu'un pour les corriger.
 
Tu es peut-être obligé de déclarer toutes les variables avant l'instruction switch. Enfin voilà je n'ai pas testé car je n'ai pas Visual sous les yeux.
 
Je te conseille de lire et de comprendre ce que dit la MSDN.


Message édité par slash33 le 16-07-2005 à 21:29:06
Reply

Marsh Posté le 16-07-2005 à 20:56:43    

:love:
jvai manger et je me penche la dessu :)
merci beaucoup a toi :jap:
 
PS : par contre juste un ptit truc que je vois vite fait : moi LRESULT c est CALLBACK WndProc au lieu de APIENTRY WndProc... ca change quelque chose :??:

Reply

Marsh Posté le 16-07-2005 à 20:59:51    

Dans la MSDN ils utilisent APIENTRY mais dans les faits ça change rien.


Message édité par slash33 le 16-07-2005 à 21:00:28
Reply

Marsh Posté le 16-07-2005 à 22:15:44    

ca marche! :love: :roi:
 
donc si j ai bien compris, c est
 
HBITMAP hPrevBitmap = SelectObject(hMemDC, hBitmap);
.
.
.
SelectObject(hMemDC, hPrevBitmap);  
 
qui fait que ca ne clignote plus et ne disparait plus, c est ca?
Ou est-ce le fait de libérer le hMemDC et le hBitmap?
(ou les 2? :D)
 
Et aussi j aimerai savoir a quoi sert le hMemDC? c est une sorte de cache?
 
En tout cas merci beaucoup a toi :jap:

Reply

Marsh Posté le 17-07-2005 à 10:12:30    

En fait je ne peux pas te répondre clairement.
Comme je ne sais pas comment tu initialisais le hdc, je ne peux pas dire ce qui faisait échouer ton code. Si tu n'utilisais pas le HDC retourné par BeginPaint celà pourrait expliquer ton problème. Car pour traiter WM_PAINT tu dois impérativement employer BeginPaint()/EndPaint()
 
A quoi sert le hDCMem? C'est simple: copier un bitmap revient à copier des pixels d'un DC dans un autre DC (en appliquant diverses modifications...). Or le bitmap que tu récupères, c'est un bitmap justement c'est à dire quelque chose que tu ne peux pas utiliser tel quel puisqu'il te faut un DC. Donc il faut 'insérer' le bitmap dans un DC (mais pas celui de l'écran sinon tu vas avoir des problèmes). C'est pour celà qu'on utilise effectivement un DC tampon identique à celui de l'écran.
 
En tout cas ce qu'il faut retenir avec les DC, c'est qu'il faut impérativement savoir ce que l'on fait avec et restaurer tous les objets GDIs avant de les libérer. Mais certains DC, à l'image de celui retourné par BeginPaint, ne doivent pas être libéré par tes soins. Tu vois c'est un peu compliqué, c'est bien pour ça que je lui préfère les MFC en tout cas pour la partie GDI (interface graphique de Windows)
 
Pour le fun sache que la chose se complique quand tu dois en plus traiter des exceptions... c'est là que MFC fait toute la différence du fait de son mécanisme de libération des objets GDIs dans le destructeur de l'objet (MFC est un framework objet; j'avais oublié de le préciser)


Message édité par slash33 le 17-07-2005 à 10:29:03
Reply

Marsh Posté le 17-07-2005 à 12:02:52    

En fait j ai peut etre trouvé ce qui clochait dans mon code..... j avais oublié le EndPaint ..... :whistle:  :D
Mais bon il manquait d autres trucs de toute facon.
 
En tout cas je te remercie grandement pour tous ces eclaircissements :jap:
Et je vais peut etre jeter un coup d'oeil aux MFC car ca a l air pas mal d après ce que tu dis :)

Reply

Marsh Posté le 17-07-2005 à 16:20:05    

Les MFC c'est quand même compliqué et beaucoup ici n'aime pas.

Reply

Marsh Posté le 17-07-2005 à 17:53:12    

ok merci pour l avertisement :jap:
j y jetterai un ptit coup d oeil quand meme au cas ou mais apparament il faut mieux j en apprenne un peu plus avant de me lancer la dedans.... :)
 
EDIT : tu t y connais en jeu de go? :D
parce que je bloque un peu sur algorythme  :sweat:  (mais je vais y reflechir serieusement....)


Message édité par T'CHATTE le 17-07-2005 à 17:55:39
Reply

Marsh Posté le 18-07-2005 à 08:56:46    

Ha non le jeu de go ça ne me dit rien  :sweat:

Reply

Marsh Posté le 18-07-2005 à 16:44:00    

tant pi :)
mais pfiou... j ai du mal avec ce truc :D
mais je trouverai!!!! :D
 
merci quand meme :jap:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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