Double buffering (mfc)

Description

Application qui Gère le Double-Buffering...

L'Effet (très Génant) de Scintillement lors des Opérations de Dessin
peut être Résolu simplement par l'Ajout d'un Double-Buffer !

Cette Technique de Double-Buffering est Inserée dans la Fonction OnDraw()

Voyez Plutôt...
1) Lancer le .exe
2) Faites Cliquer-Glisser pour Déplacer la Vue (avec le Clique Gauche)
L'Image Scintille. (Il n'y a pas de Double-Buffering)
3) Activez le Double-Buffering (Touche F5)
4) Faites Cliquer-Glisser pour Déplacer la Vue (avec le Clique Gauche)
L'Image NE Scintille PAS. (VIVE le Double-Buffering)

Source / Exemple :


/////////////////////////////////////////////////////////////////////////////
// CDFView drawing
//
// Fonction de Dessin
// Le Double-Buffering agit ici !!!
//////////////////////////////////////
void CDFView::OnDraw(CDC* pDC)
{
	// Ajouter par AppWizard...
	//CDFDoc* pDoc = GetDocument();
	//ASSERT_VALID(pDoc);

	//mise en place du double-buffering ...
	CDC DC2;						// Création d'un DC qui servira de Tampon pour nos Opération de Dessin
	DC2.CreateCompatibleDC(pDC);	// Création du Context de Périférique Compatible avec notre Ecran
	CDC* pDC2=&DC2;					// On affecte à un Pointeur l'Adresse du  Tampon ( au cas où le Double-Buffering serait Activé !!

	

	// Récupération de la Taille Zone Client...
	CRect rcClient;
	GetClientRect(rcClient);
	// Convertir en Zone Logique Conrespondante...
	CRect LogicRect;
	LogicRect = CRect(rcClient);
	pDC->DPtoLP(&LogicRect);
	
	// Déclaration de BitMap... (Utile pour le Double-Buffering)
	CBitmap memBmp;
	CBitmap* OldBmp;

	// Affichage des Adresses de DC...
	CString szAdrsDC;

	if(!mDoubleBuffering)
	{
		// Si le Double-Buffering n'est pas Actif...
		pDC2=pDC;	// Le Context de Périférique sur lequel on Dessine
					// est Celui que l'on Affiche Directement (Pas de Tampon !!!)
	}
	else
	{
		//Sinon...(Ici pDC2 garde sa Valeur, Affecter dès le Départ!!!)
		memBmp.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height()); // On Créer un BitMap de la Largeur de la Zone Client (du DC en Cour)
		OldBmp = pDC2->SelectObject(&memBmp);								// On selectionne ce BitMap
		pDC2->SetWindowOrg(LogicRect.TopLeft().x,LogicRect.TopLeft().y);	// Correction d'un Bug (Car l'Affichage du BitMap ne Travaille pas en Dehors de l'Ecran)
	}
	
	// Création d'un Chaine contenant les Adresses de DC...
	szAdrsDC.Format(" pDC :%X   -   &DC2 :%X   -   pDC2 :%X",pDC,&DC2,pDC2);

// Effacement du Fond...
	LogicRect.InflateRect(1,1); // Tracer un Rectangle (BLANC=FOND) de la Taille de la Zone Client (un peu Plus)

/*	// 1er Méthode ...
	CBrush backBrush;
	backBrush.CreateSolidBrush(RGB(255, 255, 255));
	pDC2->FillRect(LogicRect, &backBrush);
	backBrush.DeleteObject();

  • /
// 2em Méthode pDC2->SelectStockObject(WHITE_BRUSH); pDC2->Rectangle(LogicRect); // Opérations de Dessin dans le Context de Périférique Selectionné... //Brouillage pDC2->MoveTo(-5,210); pDC2->LineTo(0,290); pDC2->LineTo(5,210); pDC2->LineTo(10,290); pDC2->LineTo(15,210); pDC2->LineTo(20,290); pDC2->LineTo(25,210); pDC2->LineTo(30,290); pDC2->LineTo(35,210); pDC2->LineTo(40,290); pDC2->LineTo(45,210); pDC2->LineTo(50,290); pDC2->LineTo(55,210); pDC2->LineTo(60,290); pDC2->LineTo(65,210); pDC2->LineTo(70,290); pDC2->LineTo(75,210); pDC2->LineTo(80,290); pDC2->LineTo(85,210); pDC2->LineTo(90,290); pDC2->LineTo(95,210); pDC2->LineTo(100,290); pDC2->LineTo(105,210); pDC2->LineTo(110,290); pDC2->LineTo(115,210); pDC2->LineTo(120,290); pDC2->LineTo(125,210); pDC2->LineTo(130,290); pDC2->LineTo(135,210); pDC2->LineTo(140,290); pDC2->LineTo(145,210); pDC2->LineTo(150,290); pDC2->LineTo(155,210); pDC2->LineTo(160,290); pDC2->LineTo(165,210); // pDC2->Rectangle(-10,200,700,300); // pDC2->Rectangle(-10,150,300,300); CBrush* pOldBrush=static_cast<CBrush*>(pDC2->SelectStockObject(LTGRAY_BRUSH)); pDC2->Ellipse(30,30,60,60); pDC2->MoveTo(0,80); pDC2->LineTo(20,60); pDC2->LineTo(70,60); pDC2->LineTo(90,80); pDC2->MoveTo(30,150); pDC2->LineTo(45,100); pDC2->LineTo(60,150); pDC2->MoveTo(20,60); pDC2->LineTo(45,100); pDC2->LineTo(70,60); // Aileron 1 pDC2->MoveTo(360,300); pDC2->LineTo(360,150); pDC2->LineTo(400,130); // Corps de la Fusé pDC2->Rectangle(400,180,480,30); // Aileron 2 pDC2->MoveTo(440,130); pDC2->LineTo(440,300); // Aileron 3 pDC2->MoveTo(520,300); pDC2->LineTo(520,150); pDC2->LineTo(480,130); //Tête de Fusé pDC2->MoveTo(400,30); pDC2->LineTo(440,-30); pDC2->LineTo(480,30); pDC2->MoveTo(440,-30); pDC2->LineTo(440,-70 ); pDC2->Rectangle(-10,200,700,300); pDC2->Rectangle(-10,150,300,300); pDC2->SelectObject(pOldBrush); //pDC2->SelectStockObject(HOLLOW_BRUSH); //pDC2->SelectStockObject(WHITE_BRUSH); pDC2->SetBkMode(TRANSPARENT); pDC2->TextOut(LogicRect.TopLeft().x,LogicRect.TopLeft().y,szAdrsDC); // Affichage des Adresses pDC2->SetTextAlign(TA_RIGHT); pDC2->SetTextColor(RGB(255,0,0) ); if(mDoubleBuffering) pDC2->TextOut(LogicRect.BottomRight().x,LogicRect.TopLeft().y,"DOUBLE-BUFFERING "); // Affichage du "Double-Buffering" // Fin des Opérations de Dessin... if(mDoubleBuffering) { // Si le Double-Buffering était activé, On rends les Objets utilisé... pDC->BitBlt(LogicRect.TopLeft().x, LogicRect.TopLeft().y, LogicRect.Width(), LogicRect.Height(), pDC2, LogicRect.TopLeft().x, LogicRect.TopLeft().y,SRCCOPY); // Recopie le BMP à L'Ecran (au Bon Endroit) pDC2->SelectObject(OldBmp); pDC2->DeleteDC(); memBmp.DeleteObject(); ReleaseDC(pDC); } }

Conclusion :


L'Affichage montre (En Direct) l'Activation du D.F.
Vous pouvez Observez ceci :
Quand le D.F. est Actif pDC2=&DC2 qui Signifie que le Dessin à Lieu dans le Tampon !!!
Quand le D.F. est InActif pDC2=pDC qui Signifie que le Dessin à Lieu Directement à l'Ecran !!!
-------------------------------------------------
J'ai commenté au mieux la Source.
Il faut bien sur intégrer la Fonction OnDraw() dans l'un de vos Programme MFC

J'ai cependant besoin d'éclaircissement :
Ceci à été réalisé "à Taton"

1)Notament : SetWindowOrg()
Sans cela l'Affichage n'est pas Correct.
Mais je ne peux pas apporter plus d'explication que ce que j'ai mis en Commentaire...

2)La Libération des Ressources...
Je ne connais pas exactement le Mécanisme, mais sans, ca ne marche pas !

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.