GDI, MFC, Double Buffering

WhiteSpi Messages postés 17 Date d'inscription mercredi 22 octobre 2003 Statut Membre Dernière intervention 22 avril 2004 - 21 févr. 2004 à 21:19
shorzy Messages postés 94 Date d'inscription jeudi 23 novembre 2000 Statut Membre Dernière intervention 1 juin 2013 - 28 déc. 2008 à 12:14
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

ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
23 févr. 2004 à 01:58
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();
0
WhiteSpi Messages postés 17 Date d'inscription mercredi 22 octobre 2003 Statut Membre Dernière intervention 22 avril 2004
25 févr. 2004 à 02:32
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
0
cs_oussaman Messages postés 2 Date d'inscription samedi 11 novembre 2006 Statut Membre Dernière intervention 12 avril 2007
6 mars 2007 à 17:46
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
0
shorzy Messages postés 94 Date d'inscription jeudi 23 novembre 2000 Statut Membre Dernière intervention 1 juin 2013
28 déc. 2008 à 12:14
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
0
Rejoignez-nous