GDI, MFC, Double Buffering

Signaler
Messages postés
17
Date d'inscription
mercredi 22 octobre 2003
Statut
Membre
Dernière intervention
22 avril 2004
-
Messages postés
94
Date d'inscription
jeudi 23 novembre 2000
Statut
Membre
Dernière intervention
1 juin 2013
-
Bonjour a tous.
Voila j'ai un petit probleme...
J'utilise les MFC de visual C++, ainsi que GDI et j'aurais aimé afficher un echiquier a l'ecran. Malheureusement, cet echiquier est redessiné a chaque fois que je bouge une piece, et je me retrouve avec un probleme de flickering. Pour essayer de remedier au probleme j'ai essayé de mettre en place un double buffer... malheureusement.. plus rien ne s'affiche et je ne trouve pas mon erreur. Si qqun a la solution.. merci d'avance.

Voici le code de ma fonction OnPaint:

void CWinChessFighterView::OnPaint()
{
CPaintDC SuperDC(this);
CDC dc; // device context for painting
CDC MemDC;
CBitmap Bmp;
CRect cRect;
MemDC.CreateCompatibleDC(&dc);
dc.CreateCompatibleDC(&SuperDC);

int cpt=1,alter=0;
for (int j=0; j<400; j+=50){
for (int i=0; i<400; i+=50){
cRect.left=i;
cRect.right=i+50;
cRect.top=j;
cRect.bottom=j+50;if (cpt %2 0 && alter %2 0)
dc.FillRect(cRect,&CBrush(m_hWhiteSquares));
else if (cpt %2 0 && alter %2 1)
dc.FillRect(cRect,&CBrush(m_hBlackSquares));
else if (cpt %2 1 && alter %2 0)
dc.FillRect(cRect,&CBrush(m_hBlackSquares));
else if (cpt %2 1 && alter %2 1)
dc.FillRect(cRect,&CBrush(m_hWhiteSquares));
cpt++;
}
alter++;
}

//PIECE INITIALISATION
Piece *p;
for (cpt=1;cpt<65;cpt++){
p = board.GetPiece(cpt);
if (p->GetType() !Empty && ! (m_bCaptured && PieceMoving->GetPosition() cpt)){
switch (p->GetType())
{
case Pawn:
Bmp.LoadBitmap(IDB_PAWN);
break;
case Rook:
Bmp.LoadBitmap(IDB_ROOK);
break;
case Knight:
Bmp.LoadBitmap(IDB_KNIGHT);
break;
case Bishop:
Bmp.LoadBitmap(IDB_BISHOP);
break;
case Queen:
Bmp.LoadBitmap(IDB_QUEEN);
break;
case King:
Bmp.LoadBitmap(IDB_KING);
break;
}
//BITMAP DISPLAY

MemDC.SelectObject(&Bmp);
if (p->GetColour()==Black){
dc.BitBlt(p->GetXPosition(), p->GetYPosition(), 200, 200, &MemDC, 0, 0, SRCAND);
}
else // White Colour
dc.BitBlt(p->GetXPosition(), p->GetYPosition(), 200, 200, &MemDC, 0, 0, SRCAND|MERGEPAINT);
Bmp.DeleteObject();
}
}
if (m_bCaptured == TRUE){
p = PieceMoving;
if (p->GetType() != Empty){
switch (p->GetType())
{
case Pawn:
Bmp.LoadBitmap(IDB_PAWN);
break;
case Rook:
Bmp.LoadBitmap(IDB_ROOK);
break;
case Knight:
Bmp.LoadBitmap(IDB_KNIGHT);
break;
case Bishop:
Bmp.LoadBitmap(IDB_BISHOP);
break;
case Queen:
Bmp.LoadBitmap(IDB_QUEEN);
break;
case King:
Bmp.LoadBitmap(IDB_KING);
break;
}
//BITMAP DISPLAY

MemDC.SelectObject(&Bmp);
if (p->GetColour()==Black){
dc.BitBlt(p->GetXPosition(), p->GetYPosition(), 200, 200, &MemDC, 0, 0, SRCAND);
}
else // White Colour
dc.BitBlt(p->GetXPosition(), p->GetYPosition(), 200, 200, &MemDC, 0, 0, SRCAND|MERGEPAINT);
Bmp.DeleteObject();
}
}
/////////////////////////////////
/////////MESSAGE DISPLAY/////////
/////////////////////////////////

if (m_Message._Mysize == 0){
dc.FillRect(MsgZone,&CBrush(RGB(255,255,255)));
}
else {
char * MsgTmp = (char*) m_Message.c_str();
dc.DrawText(MsgTmp,MsgZone,DT_CENTER);
}
SuperDC.BitBlt(0,0,600,500,&dc,0,0,SRCCOPY);
DeleteObject(Bmp);
DeleteObject(MemDC);
DeleteObject(dc);
DeleteObject(SuperDC);

}

WhiteSpi

4 réponses

Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
il faut créer un bitamp ert le sélectionner dans le DC en mémoire pour povoir dessiner dedans :

un exemple de base :
void OnDraw(CDC* pDC)
{
// taille zone cliente
CRect rcClient;
GetClientRect(rcClient);

CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap memBmp;
memBmp.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());
CBitmap* pOldBmp = memDC.SelectObject(&memBmp);

// effacement du fond
CBrush backBrush;
backBrush.CreateSolidBrush(RGB(255, 255, 255));
memDC.FillRect(rcClient, &backBrush);
backBrush.DeleteObject();

//ici tu dessine dans memDC comme tu l'aurai fait dans pDC

// recopie du contexte en mémoire
pDC->BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY);

// destruction contexte d'affichage
memDC.SelectObject(pOldBmp);
memDC.DeleteDC();
memBmp.DeleteObject();
Messages postés
17
Date d'inscription
mercredi 22 octobre 2003
Statut
Membre
Dernière intervention
22 avril 2004

COOL!!
Merci beaucoup, ca marche a present.. j'ai pas eu le temps de m'en occuper avant... mais la c cool :)
Merci pour tes conseils... mais c'est vrai que pour moi qui debut en programmation windows c pas evident ;)

Bon pour ceux que eventullement ca peut interesser, je copie le nouveau code obtenu qui fonctionne.

void CWinChessFighterView::OnPaint()
{
CRect cRect;

CPaintDC dc(this);
CDC MemDC;
CDC MemDCTemp;
CBitmap Bmp;
CBitmap MemBmp;
MemDCTemp.CreateCompatibleDC(&dc);
MemDC.CreateCompatibleDC(&dc);

MemBmp.CreateCompatibleBitmap(&dc,400,600);
CBitmap* pOldBmp = MemDC.SelectObject(&MemBmp);

int cpt=1,alter=0;
for (int j=0; j<400; j+=50){
for (int i=0; i<400; i+=50){
cRect.left=i;
cRect.right=i+50;
cRect.top=j;
cRect.bottom=j+50;if (cpt %2 0 && alter %2 0)
MemDC.FillRect(cRect,&CBrush(m_hWhiteSquares));
else if (cpt %2 0 && alter %2 1)
MemDC.FillRect(cRect,&CBrush(m_hBlackSquares));
else if (cpt %2 1 && alter %2 0)
MemDC.FillRect(cRect,&CBrush(m_hBlackSquares));
else if (cpt %2 1 && alter %2 1)
MemDC.FillRect(cRect,&CBrush(m_hWhiteSquares));
cpt++;
}
alter++;
}

//PIECE INITIALISATION
Piece *p;
for (cpt=1;cpt<65;cpt++){
p = board.GetPiece(cpt);
if (p->GetType() !Empty && ! (m_bCaptured && PieceMoving->GetPosition() cpt)){
switch (p->GetType())
{
case Pawn:
Bmp.LoadBitmap(IDB_PAWN);
break;
case Rook:
Bmp.LoadBitmap(IDB_ROOK);
break;
case Knight:
Bmp.LoadBitmap(IDB_KNIGHT);
break;
case Bishop:
Bmp.LoadBitmap(IDB_BISHOP);
break;
case Queen:
Bmp.LoadBitmap(IDB_QUEEN);
break;
case King:
Bmp.LoadBitmap(IDB_KING);
break;
}
//BITMAP DISPLAY

MemDCTemp.SelectObject(&Bmp);
if (p->GetColour()==Black){
MemDC.BitBlt(p->GetXPosition(), p->GetYPosition(), 200, 200, &MemDCTemp, 0, 0, SRCAND);
}
else // White Colour
MemDC.BitBlt(p->GetXPosition(), p->GetYPosition(), 200, 200, &MemDCTemp, 0, 0, SRCAND|MERGEPAINT);
Bmp.DeleteObject();
}
}
if (m_bCaptured == TRUE){
p = PieceMoving;
if (p->GetType() != Empty){
switch (p->GetType())
{
case Pawn:
Bmp.LoadBitmap(IDB_PAWN);
break;
case Rook:
Bmp.LoadBitmap(IDB_ROOK);
break;
case Knight:
Bmp.LoadBitmap(IDB_KNIGHT);
break;
case Bishop:
Bmp.LoadBitmap(IDB_BISHOP);
break;
case Queen:
Bmp.LoadBitmap(IDB_QUEEN);
break;
case King:
Bmp.LoadBitmap(IDB_KING);
break;
}
//BITMAP DISPLAY

MemDCTemp.SelectObject(&Bmp);
if (p->GetColour()==Black){
MemDC.BitBlt(p->GetXPosition(), p->GetYPosition(), 200, 200, &MemDCTemp, 0, 0, SRCAND);
}
else // White Colour
MemDC.BitBlt(p->GetXPosition(), p->GetYPosition(), 200, 200, &MemDCTemp, 0, 0, SRCAND|MERGEPAINT);
Bmp.DeleteObject();
}
}
/////////////////////////////////
/////////MESSAGE DISPLAY/////////
/////////////////////////////////

if (m_Message._Mysize == 0){
MemDC.FillRect(MsgZone,&CBrush(RGB(255,255,255)));
}
else {
char * MsgTmp = (char*) m_Message.c_str();
MemDC.DrawText(MsgTmp,MsgZone,DT_CENTER);
}
dc.BitBlt(0,0,600,500,&MemDC,0,0,SRCCOPY);

MemDC.SelectObject(pOldBmp);
DeleteObject(Bmp);
DeleteObject(MemDC);
DeleteObject(dc);

}

WhiteSpi
Messages postés
2
Date d'inscription
samedi 11 novembre 2006
Statut
Membre
Dernière intervention
12 avril 2007

salut white, chwi tout new en mfc, je les maitrise pas bien , j ai pas arriver a dessiner un echiqier et d y mettre les diffirentes pieces, help me please !!!!! svp qq1 connait un bon tutorial car il en manque vraiment sur le net

CIAO
Messages postés
94
Date d'inscription
jeudi 23 novembre 2000
Statut
Membre
Dernière intervention
1 juin 2013

Lol ça Fait un peu Tard, j'espère qu'il y a encore Qqun ici...


Voila, j'ai peur que la solution ne marche pas (Dans cet état !!) pour un mode de Tracer
ISOTROPIC ou ANISOTROPIC

Qu'en Pensez vous ??

Yeeh Baby