2010-08-09 10 views
0

ok je peux dessiner ellipse le problème est celui-ci, im essayant de dessiner une ellipse mais changer sa valeur x à différent. comme cela je dessine une ellipse et la valeur x est 1 après dix secondes je veux la valeur x être 10, mais il semble que im créer une nouvelle ellipse avec x valeur 10. voici mon codeC++ gdi dessin ellipse problème

while(sd==1)//sd equal 1 
{ 
    sf++;//sf equals 1 
    onPaint(hdc); 
    InvalidateRect(hWnd,0,true); 
} 
//on paint function 
VOID onPaint(HDC hdc) 
{ 
    Graphics graphics(hdc); 
    Pen  pen(Color(255, 0, 0, 255)); 
    graphics.DrawEllipse(&pen,sf , 0, 50, 50); 
} 

bien i pensé que invalider rect effacera tout a été peint et repeindre mais il n'a pas fonctionné

Répondre

0

Si vous voulez faire une animation, mieux vaut régler une minuterie. L'utilisation de InvalidateRect comme moyen de générer des WM_PAINT semble excessive, cela fera beaucoup plus que cela. Au lieu de cela, vous pouvez dessiner directement dans l'appel OnTimer, car il est en dehors d'un WM_PAINT, vous aurez besoin d'obtenir un contexte de périphérique avec GetDC. Par exemple si vous pouvez avoir la fonction DrawFrame (HDC hDC).

Par exemple, si vous pouvez avoir la fonction DrawFrame (HDC hDC). OnTimer mettra à jour la position actuelle et appellera DrawFrame, OnPaint appellera DrawFrame mais ne mettra pas à jour la position (de cette façon, si vous voulez arrêter l'animation, la dernière image sera dessinée). DrawFrame effacera l'arrière-plan (probablement avec un FillRect), et dessine le cercle dans la nouvelle position

Si vous avez une grande surface, cela va scintiller, pour l'éviter, comme Tom l'a suggéré, vous pouvez utiliser un DC mémoire et un HBITMAP pour le double buffer.

+0

ok merci pour les détails mais pouvez-vous me donner un exemple comment utiliser le getDC et quelle fonction devrais-je utiliser pour mettre à jour – Ramilol

+0

c'est vraiment facile 'HDC hdc = GetDC (hWnd) 'vérifiez http://msdn.microsoft.com/en-us/library/dd144871(VS.85).aspx. Vous devriez mettre à jour quand OnTimer est lancé de cette façon, vous aurez une animation fluide. – Ismael

0

Vous ne devriez pas essayer de dessiner plusieurs images d'une animation en un seul coup.

Enregistrer votre variable sf quelque part, et OnPaint(), incrémenter sf, dessiner une seule ellipse, et appelez Invalidate()

Le Invalidate déclenchera OnPaint() à nouveau appelé.

Cela devrait fonctionner, mais sera très flickery :) Vous pouvez corriger le scintillement en double-buffering.

+0

bien il dessine plus d'un et sf est golabe varabile – Ramilol

-1

InvalidateRect indique que la fenêtre est "invalide", mais cela ne provoque pas d'effacement et de repeint. L'effacement et la peinture se produisent uniquement lorsque votre pompe de message est en cours d'exécution (par exemple, la boucle avec GetMessage et DispatchMessage). Lorsque la file d'attente de messages est vide, GetMessage synthétisera les messages WM_ERASEBKGND et WM_PAINT pour les fenêtres non valides. Lorsque ces messages sont envoyés à la procédure de fenêtre, la fenêtre a une chance de dessiner.

Votre fonction onPaint dessine uniquement, elle n'efface pas. Et puisque votre boucle ne se termine jamais, la pompe de message ne peut jamais fonctionner.

Pour les animations simples, la solution est SetTimer. Dans votre gestionnaire pour les messages WM_TIMER, mettez à jour vos variables pour une seule image, appelez le InvalidateRect et renvoyez (ce qui permet à la pompe de message de continuer à fonctionner). Le message d'effacement et de peinture arrivera, puis la minuterie se déclenchera à nouveau, et vous obtiendrez l'image suivante.

+0

Quelqu'un peut-il expliquer pourquoi ce post a été downvoted?Il explique pourquoi InvalidateRect ne fonctionne pas comme le demandeur l'attendait. –