Problème ontexte mémoire et classe

Signaler
Messages postés
22
Date d'inscription
jeudi 14 octobre 2004
Statut
Membre
Dernière intervention
3 janvier 2005
-
Messages postés
22
Date d'inscription
jeudi 14 octobre 2004
Statut
Membre
Dernière intervention
3 janvier 2005
-
Bonjour
Je travaille sous visual C++ et j'ai un petit problème de classe et de contexte mémoire. Je crée une classe ligne que j'appelle ds ma fonction afficherMenu mais à la compilation, il trouve une erreur dans la fonction dessiner :
error C2664: 'Dessiner' : cannot convert parameter 1 from 'class CDC' to 'class CDC'
No copy constructor available for class 'CDC'

Je pense aussi qu'il y eu erreur dans mon code au niveau de la déclaration du CpaintDC. J'ai du mal avec les contextes de périphériques.
Sinon sans l'appel à ma classe le programme marche parfaitement.

Je vous remercie pour votre aide car ça fait un moment que je bloque sur ce problème.

++
Joyeuses Fetes

CDC dcMem;

void CProjecttestDlg::AfficherMenu ()
{
CPaintDC dc(this);
GetClientRect(rect);

dcMem.CreateCompatibleDC(&dc);

bitmap.CreateCompatibleBitmap(&dc,240,320);
CBitmap* pOldBitmap = dcMem.SelectObject(&bitmap);

CBrush backBrush (RGB(010,106,010));
dcMem.FillRect(rect, &backBrush);

CString s0="TEXTE";
dcMem.SetTextAlign(TA_BASELINE | TA_LEFT);
dcMem.SetTextColor(RGB(255,255,255));
dcMem.SetBkMode(TRANSPARENT);
dcMem.TextOut(38,18,s0,11);

int ct[3];
ct[0]=255;
ct[1]=128;
ct[2]=000;

ligne line1(0,25,240,25,1);
line1.Dessiner(dcMem,pinceau);
ligne line2(160,0,160,320,1);
line2.Dessiner(dcMem,pinceau);

}

void CProjecttestDlg::OnPaint()
{
CPaintDC dc(this);
GetClientRect(rect);

dc.BitBlt(0,0,240,320,&dcMem,0,0,SRCCOPY);

dc.SelectObject(pOldBitmap);//pr l'instant supprimer
bitmap.DeleteObject();
dcMem.DeleteDC();
}

//Ligne.h

class ligne
{
private:
int x1;
int x2;
int y1;
int y2;
int couleurBord;

public:
ligne();
ligne(int,int,int,int,int);
void Dessiner(CDC,CPen*[7]);
};

//ligne.cpp

ligne::ligne()
{
}

ligne::ligne(int xx1,int yy1, int xx2, int yy2,int CB)
{
x1=xx1;
x2=xx2;
y1=yy1;
y2=yy2;

couleurBord=CB;

}

void ligne::Dessiner(CDC dcMem, CPen* ppinceau[7])
{
CPen* pOldPen;
pOldPen=dcMem.SelectObject(ppinceau[couleurBord]);
dcMem.MoveTo(x1,y1);
dcMem.LineTo(x2,y2);

dcMem.SelectObject(pOldPen);
}

10 réponses

Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
J'ai du mal a comprendre ton programme. Mais si simplement tu crées le constructeur de copie de la class CDC, ca fait quoi ?
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
Il n'y a aucun constructeur par recopie pour les objets MFC encapsulant des handles (et il ne faut pas les rajouter sous peine de fuites mémoires). Il faut passer ces objets par référrence ou par pointeur :

void ligne::Dessiner(CDC& dcMem, CPen* ppinceau[7])

void ligne::Dessiner(CDC* pdcMem, CPen* ppinceau[7])
Messages postés
22
Date d'inscription
jeudi 14 octobre 2004
Statut
Membre
Dernière intervention
3 janvier 2005

Je te remercie pour ton aide, ça fonctionne.
Cependant j'ai un autre problème. Je crée une classe rectangle qui permet d'afficher du texte dans un rectangle, mais lorsque je l'appelle , elle dessine le rectangle mais pas le texte.
Voici le code :

ma classe rectangle

rectangle::rectangle()
{
}

rectangle::rectangle(int xx1, int yy1,int xx2,int yy2,int CB,int CF,CString text,int CT[3])
{
x1=xx1;
x2=xx2;
y1=yy1;
y2=yy2;
couleurBord=CB;
couleurFond=CF;
couleurText[0]=CT[0];
couleurText[1]=CT[1];
couleurText[2]=CT[2];
texte=text;
}

void rectangle::SetRectangle(int xx1, int yy1,int xx2,int yy2,int CB,int CF,CString text,int CT[3])
{
x1=xx1;
x2=xx2;
y1=yy1;
y2=yy2;
couleurBord=CB;
couleurFond=CF;
couleurText[0]=CT[0];
couleurText[1]=CT[1];
couleurText[2]=CT[2];
texte=text;
}

void rectangle::ModifCouleurFond(int i)
{
couleurFond=i;
}

void rectangle::Dessiner(CDC& dcMem, CPen* ppinceau[7],CBrush* pbrosse[6])
{
CBrush* pOldBrush;
CPen* pOldPen;
CRect rect(x1,y1+3,x2,y2+3);
pOldBrush=dcMem.SelectObject(pbrosse[couleurFond]);

pOldPen=dcMem.SelectObject(ppinceau[couleurBord]);
dcMem.Rectangle(x1,y1,x2,y2);

LOGBRUSH logbrush;
pbrosse[couleurFond]->GetLogBrush( &logbrush );
dcMem.SetBkColor(logbrush.lbColor);
dcMem.SetTextColor(RGB(couleurText[0],couleurText[1],couleurText[2]));

dcMem.DrawText(texte,texte.GetLength(),&rect,DT_CENTER);

dcMem.SelectObject(pOldBrush);
dcMem.SelectObject(pOldPen);
}

ici j'appelle ma classe, elle dessine bien le rectangle mais pas le texte.

rectangle rect3(50,80,190,240,1,1,"TEXTE",ct);
rect3.Dessiner(dcMem,pinceau,brosse);

Alors je sais pas si ça vient du fait que mon buffer mémoire est tjs le meme pour les deux classes ou d'autre chose.
Je vais chercher de mon coté, c'est peut etre un problème de brosse non déséléctionné. Je débute là dedans et j'ai un peu de mal.

En tout cas, merci pour ton aide.

++
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
essaye en mettant des couleurs brutes dans le code (genre rouge pour le texte et blanc pour le fond pour vérifier que c'est pas un problème de couleur
Messages postés
22
Date d'inscription
jeudi 14 octobre 2004
Statut
Membre
Dernière intervention
3 janvier 2005

alors j'ai essayé avec des couleurs primaires mais rien à faire il m'affiche tjs mon rectangle ds lequel on peut changer les couleurs ou la bordure, en revanche je n'arrive tjs pas à afficher le texte.
Je ne vois pas trop de quoi ça peut venir.

Si t'as une autre idée je cherche de mon coté.

Merci

++
Messages postés
22
Date d'inscription
jeudi 14 octobre 2004
Statut
Membre
Dernière intervention
3 janvier 2005

je sais pas pourquoi mais la fonction SetTextAlign empeche le texte de s'afficher dans le rectangle qd je l'enlève ça marche nickel. Merci pour ton aide.
Sinon une question vu que tu m'as l'air assez doué ds le GDI, j'aimerai éviter de redessiner le fond de ma page à chaque fois, comment puis je faire ? Ou faut il que je le dessine ? Et il faut utiliser la fonction InvalidateRect(rect, FALSE) mais tout ce que j'ai essayé ne marche pas.

Merci
Bonne soirée

++
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
POur que le systeme ne redessine pas le fond automatiquement :
- mettre NULL pour le HBRUSH du fond dans le WNDCLASS lors de l'enregistrement de la classe de fenêtre (sous MFC c'est plus dur, il faut enregistrer une nouvelle classe de fenêtre dans PreCreateWindow.
- l'autre solution est de surcharger la fonction OnEraseBkGnd et de retourner TRUE sans appeler la fonction de la classe de base, ainsi, le fond de la fenêtre ne sera pas dessiner automatiquement.

Maintenant, dans OnPaint (ou OnDraw pour les vues), il faudra dessiner le fond toi-même. Le mieux, c'est de créer un DC en mémoire de la taille de la zone cliente, de remplir avec la couleur de fond souhaitée, puis de dessiner dedans au lieu du DC fourni. A la fin, il suffira de faire un BitBlt sur le Dc fournit pour recopier en une seule fois à l'écran (pas de clignotement dans ce cas). C'est la technique du double-buffering (pas mal de sources et de questions du forum s'y rapporte, tu pourra y trouver des exemples.
Messages postés
22
Date d'inscription
jeudi 14 octobre 2004
Statut
Membre
Dernière intervention
3 janvier 2005

je débute sous visual et je comprends pas trop ce que tu veux dire par surcharger la fonction OnEraseBkGnd sans appeler la fonction de la classe de base. En fait il faut forcer cette donction à retourner TRUE.
Faut que j'essaye mais si je crée un buffer mémoire dcMem dans le onPaint est ce que je pourrai réutiliser le meme ds mes fonctions afficher ou faut il en créer un autre et blitter son contenu à l'écran par dessus le buffer mémoire de ma fonction OnPaint.

en tout cas merci pour tes explications. C sympa.

++
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
Dans le class wizard, tu recherche WM_ERASEBKGND, et tu ajoute la fct
tu lui fait retourner TRUE sans faire CWnd::OnEraseBkGnd ou autre mis automatiquement.

Je pense qu'il faudra en créer un autre, dessiner le fonf et copier ton dc mémoire dednans puis blitter à l'écran
Messages postés
22
Date d'inscription
jeudi 14 octobre 2004
Statut
Membre
Dernière intervention
3 janvier 2005

salut

j'ai essayé ce que tu as dit mais j'arrive pas à intercepter WM_ERASEBKGND ds le class wizard ni OnDraw mais j'ai tapé la fonction
BOOL CProjecttestDlg::OnEraseBkgnd(CDC& dcMem1)
{
return FALSE;
}

et je dessine ds ce nouveau CDC dcMem1 ds le OnPaint.
je crée un dc compatible et je le bitblt.
je bitblt tjs dcMem mais ça ne marche pas. Il m'affiche le fond au démarrage puis rien d'autre.

void CProjecttestDlg::OnPaint()
{
CPaintDC dc(this);
GetClientRect(rect);

dcMem1.CreateCompatibleDC(&dc);
je dessine le fond ds dcMem1 avec fillrect

dc.BitBlt(0,0,240,320,&dcMem1,0,0,SRCCOPY);
dc.BitBlt(0,0,240,320,&dcMem,0,0,SRCCOPY);

dc.SelectObject(pOldBitmap);//pr l'instant supprimer
bitmap.DeleteObject();
dcMem.DeleteDC();
dcMem1.DeleteDC();
}

J'ai une erreur aussi que je ne comprends pas
dc.SelectObject(pOldBitmap);
c ds mon DC mémoire dcMem que je dois sélectionner ma bitmap mais si je met dcMem à la place de dc, ça ne fonctionne pas.
Bref c pas clair ce que je dis mais j'ai vraiment du mal.
Si t'as une idée ou des info, encore merci.

++