2010-08-10 4 views
2

J'ai créé une animation qui fonctionne bien, mais elle se tourne. J'ai besoin d'aide pour le double tampon, car je n'en sais rien.Aide à la double-mise en mémoire tampon

Voici le code dans mon OnPaint():

VOID onPaint(HDC hdc) 
{ 
    Graphics graphics(hdc); 
    Pen  pen(Color(255, 0, 0, 255)); 
    graphics.DrawEllipse(&pen, sf , 0, 10, 10); 
} 

Il fonctionne très bien, mais avec le scintillement. J'ai essayé ce code mais cela n'a pas fonctionné:

VOID onPaint(HDC hdc,HWND hWnd) 
{ 
    HDC hDC=GetDC(hWnd);; 
    HDC memDC = CreateCompatibleDC(hDC); 
    HBITMAP hMemBmp = CreateCompatibleBitmap(hDC,10,10); 
    HBITMAP hOldBmp = (HBITMAP)SelectObject(memDC,hMemBmp); 
    BitBlt(hDC, 0, 0, 10, 10, memDC, 0, 0, SRCCOPY); 
    Graphics graphics(memDC); 
    Pen  pen(Color(255, 0, 0, 255)); 
    graphics.DrawEllipse(&pen, sf , 0, 10, 10); 

    // Always select the old bitmap back into the device context 
    SelectObject(memDC, hOldBmp); 
    DeleteObject(hMemBmp); 
    DeleteDC(memDC); 
} 
+1

Vous pouvez formater votre code en l'indentant de quatre espaces. –

+0

merci pour le conseil mais aucune idée pour mon problème – Ramilol

+1

dans votre exemple de code, on dirait que vous êtes en train de mixer la nouvelle mémoire DC, et * ensuite * de dessiner dessus, ce qui est un peu contraire à la façon habituelle de le faire . – JustJeff

Répondre

9

Il semble que vous copiez prématurément le DC hors-écran sur l'affichage. Essayez de déplacer l'appel à quatre lignes BitBlt vers le bas, pour en faire la dernière ligne avant de commencer le nettoyage, comme ceci:

VOID onPaint(HDC hdc,HWND hWnd) 
{ 
    // this line looks a little odd : 
    HDC hDC = GetDC(hWnd); 
    // .. usually the hdc parameter passed to onPaint would already refer to 
    // the on-screen DC that windows wants updated. Also worth noting is that 
    // when you use GetDC(), you should have a matching ReleaseDC() 
    // As a quick test, you might just replace the above line with 
    //  HDC hDC = hdc; 

    HDC memDC = CreateCompatibleDC(hDC); 
    HBITMAP hMemBmp = CreateCompatibleBitmap(hDC,10,10); 
    HBITMAP hOldBmp = (HBITMAP)SelectObject(memDC,hMemBmp); 

    // draw to the off-screen map .. 
    Graphics graphics(memDC); 
    Pen  pen(Color(255, 0, 0, 255)); 
    graphics.DrawEllipse(&pen, sf , 0, 10, 10); 

    // now that you've drawn on the offscreen map, go ahead 
    // and put it on screen. 
    BitBlt(hDC, 0, 0, 10, 10, memDC, 0, 0, SRCCOPY); 

    // Always select the old bitmap back into the device context 
    SelectObject(memDC, hOldBmp); 
    DeleteObject(hMemBmp); 
    DeleteDC(memDC); 
} 

Une autre chose à propos de ce code, vous avez passé la constante « 10 » comme la largeur et la hauteur de votre bitmap hors écran, ainsi que son utilisation pour les paramètres width et height du BitBlt() qui effectue la copie. Les chances sont que la zone cliente de la fenêtre en cours de mise à jour soit beaucoup plus grande que cela. Le 'carré noir' est une conséquence de la fusion de la carte hors écran 10x10 sur la zone client de la fenêtre. Au lieu de coder en dur 10, vous pouvez essayer d'utiliser une autre fonction GDI pour obtenir les dimensions du bitmap à l'écran, ou tout au moins # définir les valeurs de largeur et de hauteur et les utiliser dans les paramètres. L'autre chose qui vous tue est probablement le 'sf' dans la ligne "graphics.DrawEllipse (& pen, sf, 0, 10, 10)" - puisque vous avez créé une carte incroyablement minuscule 10x10, si le La valeur de 'sf' est quelque chose en dehors de 0..10, l'appel DrawEllipse() placera l'ellipse entièrement en dehors des pixels disponibles dans votre carte hors écran. Donc, en bout de ligne, vous voulez probablement faire en sorte que la carte hors écran ait la même taille que la zone client de la fenêtre, et assurez-vous de déplacer l'appel BitBlt() pour qu'il se produise après toutes les opérations de dessin carte d'écran.

+0

j'ai le même résultat un carré noir – Ramilol

+0

j'ai eu une erreur ne peut pas convertir HWND en HDC – Ramilol

+0

Si cette fonction onPaint est appelée en réponse à WM_PAINT, alors vous devriez utiliser BeginPaint pour obtenir le DC, et EndPaint. Vous devez également obtenir les tailles correctes pour le bitmap de la mémoire et le blit, probablement GetClientRect. Il semble que vous n'initialisiez pas le bitmap de la mémoire, donc vous aurez des données aléatoires, sauf où l'ellipse peint. –

Questions connexes