[MFC] recherche de nom de fonction pour éviter le clipping

recherche de nom de fonction pour éviter le clipping [MFC] - C++ - Programmation

Marsh Posté le 04-04-2005 à 23:25:18    

Bonjour j'aimerai savoir le nom de la fonction (si elle existe) qui me permette de redessiner ma fenetre (une CFramWnd). Mais je veux savoir quelle parte de la fenetre je dois redessiner. Pour l'instant j'utilise la fonction BOOL OnEraseBkgnd(CDC*). Mais je redessine toute la fantre lorsque'une fenetre s'affiche devant mon appli et que je fais bouger celle-ci.
 
 
En gros je voudrai aves BOOL OnEraseBkgnd(CRect,CDC*) avec l'objet CRect qui me dise la zone à redessiner.
 
merci :hello:


Message édité par LordHarryPotter le 05-04-2005 à 09:30:53
Reply

Marsh Posté le 04-04-2005 à 23:25:18   

Reply

Marsh Posté le 04-04-2005 à 23:34:15    

Je suppose que c'est à toi de maintenir cette liste ?

Reply

Marsh Posté le 05-04-2005 à 09:33:15    

IrmatDen a écrit :

Je suppose que c'est à toi de maintenir cette liste ?


Quelle liste ?
Je ne vois pas comment récupérer les coordonées de la zone image à redessiner ? :pt1cable:

Reply

Marsh Posté le 05-04-2005 à 12:34:51    

Pourquoi veux-tu redessiner ta fenêtre ?

Reply

Marsh Posté le 05-04-2005 à 15:16:08    

Je veux la redessiner car sinon j'ai plus rien d'afficher à l'écran. Pour celà j'ai bien recoder la fonction OnEraseBkgnd mais celle ci doit être appeler pour redessinener toute la fenetre, or moi je voudrai éviter de redessiner toute la fenetre mais seulement la partie éffacé (autre fenetre qui passe devant l'application, ...)

Reply

Marsh Posté le 05-04-2005 à 16:47:07    

ok j'ai mal posé la question... Où est le mal de redessiner ta fenêtre en entier ?

Reply

Marsh Posté le 05-04-2005 à 21:39:00    

Ben plus t'as de chose à redessiner plus t'as un effet de clognottement :o
Le truc c'est que si je savais quel endroit redessiner j'optimiserai l'affichage et donc le phénomène de clipping serais aténuer

Reply

Marsh Posté le 05-04-2005 à 21:45:10    

Reply

Marsh Posté le 08-04-2005 à 09:58:02    

En faite j'avais déjçà vu e site, mais je n'arrive pas à metre en application les CMemDC, le problème est que mon programme ne se rend jamais dans le fonction OnDraw(), et même sir je rajoute ou non le message On_WN_PAINT() dans la table des mesages :(

Reply

Marsh Posté le 08-04-2005 à 18:43:45    

Salut,
Je suis pas sûr de bien comprendre ton message mais dans la message map, c'est ça qu'il faut mettre :

Code :
  1. MESSAGE_HANDLER(WM_PAINT, OnPaint)


avec le lien qui en dit plus : http://msdn.microsoft.com/library/ [...] sg_map.asp

Reply

Marsh Posté le 08-04-2005 à 18:43:45   

Reply

Marsh Posté le 08-04-2005 à 22:55:41    

LordHarryPotter a écrit :

En faite j'avais déjçà vu e site, mais je n'arrive pas à metre en application les CMemDC, le problème est que mon programme ne se rend jamais dans le fonction OnDraw(), et même sir je rajoute ou non le message On_WN_PAINT() dans la table des mesages :(


dans quelle méthode fais tu ton affichage alors ?

Reply

Marsh Posté le 08-04-2005 à 23:31:02    

SquiZZ a écrit :

dans quelle méthode fais tu ton affichage alors ?


C'est ptete bourrin mais je crois l'avoir déjà dit : OnEraseBkgnd()

Reply

Marsh Posté le 08-04-2005 à 23:49:38    

bon ben tu utilises CMemDC dans ton OnEraseBkgnd()
 

Code :
  1. CMemDC dc(pDC);
  2. dc.FillSolidRect(0,0,5,5,0);
  3. // ....


 
et ca devrait marcher.

Reply

Marsh Posté le 08-04-2005 à 23:53:44    

IrmatDen a écrit :

Salut,
Je suis pas sûr de bien comprendre ton message mais dans la message map, c'est ça qu'il faut mettre :

Code :
  1. MESSAGE_HANDLER(WM_PAINT, OnPaint)


avec le lien qui en dit plus : http://msdn.microsoft.com/library/ [...] sg_map.asp


 
J'ai essayé mais c'est pour la librairie ATL et moi j'utilise MFC et çà ne reconnait pas le truc (le compilo),
 
bref voici ma table de message :

Code :
  1. BEGIN_MESSAGE_MAP(GraphiqueMainWin, CFrameWnd)
  2. ON_COMMAND(ID_QUICOMMENCE_JOUEUR1, OnQuicommenceNoir)
  3. ON_COMMAND(ID_QUICOMMENCE_JOUEUR2, OnQuicommenceBlanc)
  4. ON_COMMAND(ID_QUICOMMENCE_ALTERN40013, OnQuicommenceAltern40013)
  5. ON_COMMAND(ID_AIDE_APROPOS, OnAideApropos)
  6. ON_COMMAND(ID_AIDE_MANUEL, OnAideManuel)
  7. ON_COMMAND(ID_OPTION_AFFICHAGE, OnOptionAffichage)
  8. ON_COMMAND(ID_PARTIE_NOUVELLE, OnPartieNouvelle)
  9. ON_COMMAND(ID_PARTIE_ENREGISTRER, OnPartieEnregistrer)
  10. ON_COMMAND(ID_PARTIE_OUVRIR, OnPartieOuvrir)
  11. ON_COMMAND(ID_PARTIE_ENREGISTRER_SOUS, OnPartieEnregistrerSous)
  12. ON_MESSAGE(WM_PAINT,OnDraw) //<- compilo dit pas bon
  13. ON_WM_ERASEBKGND()
  14.         ON_WM_LBUTTONUP()
  15. ON_COMMAND(ID_AIDE_RULES, OnAideRules)
  16. END_MESSAGE_MAP()


 
Voici le message du compilo :
error C2440: 'static_cast' : cannot convert from 'void (__thiscall GraphiqueMainWin::* )(CDC *,const CRect &,const CRect & )' to 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'
        None of the functions with this name in scope match the target type
 
Bon alors mon skelette de OnDraw est bien : (CDC *,const CRect &,const CRect & ) -> void
 
Somebody save me  :hello:

Reply

Marsh Posté le 08-04-2005 à 23:56:28    

ben le compilo te dit gentillement qu'il attend une fonction du style LRESULT toto(WPARAM,LPARAM) et que tu insistes méchamment pour lui refiler une fonction du style void toto(CDC *,const CRect &,const CRect & )
 
et le compilo a toujours raison.

Reply

Marsh Posté le 09-04-2005 à 08:11:11    

vi, il faut que tu respectes la déclaration du callback, que tu le déclares static, et dans sa définition tu appeles ta vrai fonction en utilisant par exemple LPARAM pour lui passer this afin de récupérer les éléments nécessaires à lui passer.

Reply

Marsh Posté le 09-04-2005 à 12:49:59    

cricri_ a écrit :

vi, il faut que tu respectes la déclaration du callback, que tu le déclares static, et dans sa définition tu appeles ta vrai fonction en utilisant par exemple LPARAM pour lui passer this afin de récupérer les éléments nécessaires à lui passer.


 [:shinji_kun64] on parle d'une MESSAGE_MAP MFC ici, pas callback, pas besoin de static ici.
quand a WPARAM, LPARAM il suffit de regarder dans la doc a quoi ca corrspond pour chaque message.

Reply

Marsh Posté le 10-04-2005 à 00:10:58    

non mais moi mon problème c'est que je veux que le prog aille dans la fonctionOnDraw qui est prédéfini (virtuel), donc qu'il veuilles le LRESULT toto(WPARAM,LPARAM), je m'en fiche moi mon but c'est qu'il entre dans OnDraw() quand il le faut. Le problème c'est que ej sais pas comment faire :o

Reply

Marsh Posté le 10-04-2005 à 00:35:31    

LordHarryPotter a écrit :

non mais moi mon problème c'est que je veux que le prog aille dans la fonctionOnDraw qui est prédéfini (virtuel)


 
ben tu surdéfinis OnDraw()
=> même nom, même liste de paramètres et ca devrait marcher.

Reply

Marsh Posté le 10-04-2005 à 00:38:07    

SquiZZ a écrit :

ben tu surdéfinis OnDraw()
=> même nom, même liste de paramètres et ca devrait marcher.


Pas compris, OnDraw doi avec un squelette : (CDC *,const CRect &,const CRect & ) -> void
 
Donc voilà çà veut dire quoi ton meme nom meme kliste de paramètre

Reply

Marsh Posté le 10-04-2005 à 00:52:14    

bon faudrait voir a essayer de parler en francais de temps en temps.
 
Je viens de regarder la doc de CFrameWnd dans la MSDN et il je n'ai pas vu de OnDraw ni dans la classe CFrameWnd ni dans la classe parente CWnd.
Tu peux me dire ou t'as trouvé ton squelette de OnDraw ?


Message édité par SquiZZ le 10-04-2005 à 00:52:37
Reply

Marsh Posté le 10-04-2005 à 15:00:09    

SquiZZ a écrit :

bon faudrait voir a essayer de parler en francais de temps en temps.
 
Je viens de regarder la doc de CFrameWnd dans la MSDN et il je n'ai pas vu de OnDraw ni dans la classe CFrameWnd ni dans la classe parente CWnd.
Tu peux me dire ou t'as trouvé ton squelette de OnDraw ?


SquiZZ : Autant pour moi j'étais bourré quand j'ai vu cette fonction (membre seulement d'une CDialog apparement), sinonpour les CMemDC que je doit utiliser comme des CDC, j'ai un problème :
 

Code :
  1. // pFW est un CFrameWnd * qui pointe sur ma frame courante
  2. pDC = CMemDC(pFW->GetDC()) ;
  3. // plateau_brush est un CBrush*
  4. DWORD mygreen = RGB( 50,200, 80) ;
  5. plateau_brush = new CBrush(mygreen) ;
  6. pDC->SelectObject(&*plateau_brush); // !! pb à cette ligne là


 
En faite ce code passe si pDC est un CDC* mais plante si c'est un CMemDC*
Il plante à l'exécution en me passant une fenetre windows Assert machin chose :
 

Code :
  1. CBrush* CDC::SelectObject(CBrush* pBrush)
  2. {
  3. ASSERT(m_hDC != NULL); // là il plante
  4.         //...
  5. }


 
Mon problème c'est que si j'ai bien compris, la classe CMemDC remplace complètement la classe CDC. Donc il ne devriait pas y avoir de problème là car si j'ai un CDC çà roule :s
 
Je sais pas si je suis assez clair. En gros j'ai lut que la class CMemDC était une classe qui était transparente niveau programmation : si çà marche avec les CDC çà marchera avec les CMemeDC sans toucher au code (à pars pour les déclarations CDC).

Reply

Marsh Posté le 10-04-2005 à 16:05:23    

bordel, tu sais pas déclarer une variable ?

Code :
  1. CMemDC memDC(pFW->GetDC());
  2. memDC.SelectObject(...


 
et c'est quoi ce touillage avec &* dans SelectObject ?
[edit : nom de variable]


Message édité par SquiZZ le 10-04-2005 à 16:06:38
Reply

Marsh Posté le 10-04-2005 à 16:43:44    

SquiZZ a écrit :

bordel, tu sais pas déclarer une variable ?

Code :
  1. CMemDC memDC(pFW->GetDC());
  2. memDC.SelectObject(...


 
et c'est quoi ce touillage avec &* dans SelectObject ?
[edit : nom de variable]


Parce que j'ai éditer mon  et que comme çà marchait pas j'ai tenté çà :o
Donc en remplaçant par pDC->SelectObject(plateau_brush) j'ai toujours la meme fenetre windows qui s'affiche et toujours au meme endroit.
Voilà :(

Reply

Marsh Posté le 10-04-2005 à 19:21:06    

est ce que tu a lu la première partie de mon message précédent ?

Reply

Marsh Posté le 10-04-2005 à 21:04:52    

SquiZZ a écrit :

bordel, tu sais pas déclarer une variable ?

Code :
  1. CMemDC memDC(pFW->GetDC());
  2. memDC.SelectObject(...


 
et c'est quoi ce touillage avec &* dans SelectObject ?
[edit : nom de variable]


Si je sais déclarer une variable, seulement pDC est un des champs de mon objet.
 
J'ai un objet Dessin qui a comme champs pDC de type CMemDC* (ou avant CDC*) d'où l'initialisation comme çà :

Code :
  1. pDC = CMemDC(pFW->GetDC()) ;

Reply

Marsh Posté le 10-04-2005 à 21:26:43    

CMemDC s'utilise comme je l'ai mis dans mon exemple.
Tu passes au constructeur le CDC que tu veux gérer en double buffering.
Tu dessines dans le CMemDC et à la destruction de l'instance de CMemDC, il va blitter tout seul le résultat dans le CDC que tu as donné au constructeur.
 

Reply

Marsh Posté le 11-04-2005 à 00:33:32    

SquiZZ a écrit :

CMemDC s'utilise comme je l'ai mis dans mon exemple.
Tu passes au constructeur le CDC que tu veux gérer en double buffering.
Tu dessines dans le CMemDC et à la destruction de l'instance de CMemDC, il va blitter tout seul le résultat dans le CDC que tu as donné au constructeur.


Okay, j'initialise bien de CMemDC (enfin je pense) :
 

Code :
  1. Dessin::Dessin(CFrameWnd *pGMW, Echiquier& jeu ):
  2. pDC(pGMW->GetDC()) //pDC est un CMemDC (pas un pointeur)
  3. {
  4. //...
  5. }


 
Il ne plante pas (y a déjà un progres), mais il ne m'affiche que dalle :(
 

Code :
  1. CBrush brush_essai(RGB(255,0,0));
  2.   pDC.SelectObject(brush_essai);
  3.   pDC.Rectangle(100,100,150,150);
  4.   //...


 
Je mets un breakpoint juste après le pDC.Rectangle mais il affiche rien :(
 
 
Désolé mais pourune classe qui s'utilise comme les CDC je m'attendais à pas tant de changements :(

Reply

Marsh Posté le 11-04-2005 à 00:47:20    

SquiZZ a écrit :

à la destruction de l'instance de CMemDC, il va blitter tout seul le résultat dans le CDC que tu as donné au constructeur.


 
ton instance de CMemDC ne doit pas être une variable membre vu que c'est lors de la destruction que la recopie se fait dans le DC qu'on lui a passé en paramètre.
 
Admettons que ta méthode ou se fait l'affichage s'apelle toto  

Code :
  1. void pouet::toto()
  2. {
  3.     // récupération d'un DC
  4.     CDC *pDC = plif->GetDC();
  5.     pDC->Rectangle(0,0,5,5);
  6. }


 
tu remplaces par :

Code :
  1. void pouet::toto()
  2. {
  3.     // récupération d'un DC
  4.     CDC *pDC = plif->GetDC();
  5.     // instanciation de CMemDC;
  6.     CMemDC memDC(pDC);
  7.     memDC.Rectangle(0,0,5,5);
  8. }


 
et ca marche.
c'est pas compliqué, non ? si ?

Reply

Marsh Posté le 11-04-2005 à 09:03:18    

oki c'est bon j'ai compris, j'avais pas compris que c'était à la destruction que l'objet faisait qqch :o
 
J'connaissais pas cette technique (de faire un objet qui "agit seulement" à sa destruction :D
 
Mici pour ta persévérance Squizz

Reply

Marsh Posté le 11-04-2005 à 09:26:29    

SquiZZ a écrit :

[:shinji_kun64] on parle d'une MESSAGE_MAP MFC ici, pas callback, pas besoin de static ici.
quand a WPARAM, LPARAM il suffit de regarder dans la doc a quoi ca corrspond pour chaque message.


Oups ... dsl j'ai lu un peu trop en travers ...  :whistle:  

Reply

Marsh Posté le 11-04-2005 à 17:07:54    

Squizz, j veux pasfaire mon boulet mais si :D
 
En faite mainteant tout est nickel chrome sauf un détail, dans ma fenetre j'ai inclus une CToolBar et une CStatusBar. Et ces dernières disparaissent lorsque ma CMemDC redessine le bazar :(
Ne me dis pas qu'il faut reloader la CToolBar et la CStatusBar ?

Reply

Marsh Posté le 11-04-2005 à 20:01:51    

t'es sûr de passer le bon DC a la construction de CMemDC ?

Reply

Marsh Posté le 12-04-2005 à 08:41:28    

SquiZZ a écrit :

t'es sûr de passer le bon DC a la construction de CMemDC ?


A priori oui, en gros je fais
 

Code :
  1. // pDC est de type CMemDC* et est initialisé à NULL
  2. if (pDC)
  3.  delete pDC ;
  4. pDC = new CMemDC(pFW->GetDC()) ;
  5. PlotPlateau() ; // plot le plateau de jeu
  6. PlotPions()   ; // plot les pions
  7. PlotScore()   ; // plot le scores
  8. delete pDC ;  // delete pDC pour pouvoir afficher la nouvelle image
  9. pDC = NULL ;


 
En sachant que PlotXXXX() modifie le CDC (enfin le CMemDC) pDC  
(mon programme est un jeu d'othello)

Reply

Marsh Posté le 12-04-2005 à 23:43:22    

up

Reply

Marsh Posté le 14-04-2005 à 22:56:18    

down
 
pourquoi s'embeter avec un pointeur ?
tu peux utiliser une variable automatique et passer ton DC en paramètre bêtement a tes méthodes ?
 
je pense que ta variable pDC est une variable membre, non ?
au niveau conception ca n'a aucun interret de la mettre en var membre (a mon avis).
 
 
tu peux donner la définition de ton pFW ?

Reply

Marsh Posté le 15-04-2005 à 00:44:26    

le pFW est un pointeur sur mon type dérivé de CFrameWnd.
Sinon je vais essayé de mettre le CMemDC& en paramètre de fonction (et donc ne plus m'en servir comme membre)

Reply

Marsh Posté le 15-04-2005 à 09:15:53    

Je viens d'essayer de passer CMemDC& comme argument de mes fonctions qui modifie l'affichage et celà ne change rien :(
Deplus j'ai vraiment l'impession que l'affichage de la barre d'état et de la barre d'outils de ma fenetre est indépendant du CMemDC :(

Reply

Marsh Posté le 15-04-2005 à 23:12:35    

tu peux poster un peu le code de ta classe dérivée de CFrameWnd ?
tu peux virer les méthodes Plot*() pour alléger, le problème ne doit pas venir de ces méthodes.

Reply

Marsh Posté le 16-04-2005 à 11:54:34    

SquiZZ a écrit :

tu peux poster un peu le code de ta classe dérivée de CFrameWnd ?
tu peux virer les méthodes Plot*() pour alléger, le problème ne doit pas venir de ces méthodes.


oki si tu veux, voilà le .h
 

Code :
  1. #ifndef _MYMAINWINDOW_OTHELLO_H_DS_
  2. #define _MYMAINWINDOW_OTHELLO_H_DS_
  3. #include <afxwin.h>
  4. #include <afxext.h>
  5. #include "dessin.h"
  6. #include "../othello.h"
  7. const unsigned short int status_length = 3 ;
  8. class GraphiqueMainWin : public CFrameWnd
  9. {
  10. CMenu  menu_principal  ;
  11. CString  filesave;
  12. CString  fileopen;
  13. CStatusBar  status_principal ;
  14. CToolBar tool_principal  ;
  15. UINT  status_text[status_length]  ;
  16. UINT  status_width ;
  17. UINT  status_height ;
  18. UINT  width  ;
  19. UINT  height  ;
  20. Echiquier le_jeu ;
  21. Dessin*  le_visuel ;
  22. void SetStatusTextPoisition(UINT ,UINT ) ;
  23. void DrawChess(void) ;
  24. bool OuvrirFichier(void) ;
  25. bool EnregistrerFichier(void) ;
  26. public:
  27. GraphiqueMainWin();
  28. ~GraphiqueMainWin();
  29. DECLARE_MESSAGE_MAP()
  30. afx_msg void OnQuicommenceNoir();
  31. afx_msg void OnQuicommenceBlanc();
  32. afx_msg void OnQuicommenceAltern40013();
  33. afx_msg void OnAideApropos();
  34. afx_msg void OnAideManuel();
  35. afx_msg void OnOptionAffichage();
  36. afx_msg void OnPartieNouvelle();
  37. afx_msg void OnPartieEnregistrer();
  38. afx_msg void OnPartieOuvrir();
  39. afx_msg void OnPartieEnregistrerSous();
  40. afx_msg BOOL OnEraseBkgnd(CDC* ) ;
  41. afx_msg void OnLButtonUp(UINT nFlags, CPoint point) ;
  42. friend class Dessin;
  43. afx_msg void OnAideRules();
  44. };
  45. #endif /* _MYMAINWINDOW_OTHELLO_H_DS_ */


 
et le .cpp (juste les 2 fonctions qui actualisent l'écran) :
 

Code :
  1. // quand le bouton de la souris est relaché
  2. void GraphiqueMainWin::OnLButtonUp(UINT nFlags, CPoint point)
  3. {
  4. CMemDC pDC(GetDC()) ;
  5. // test si la partie courante est terminée
  6. if (le_visuel->UpdatePions(point))
  7. {
  8.  unsigned int joueur_commence ;
  9.  if (GetMenuState(menu_principal,ID_QUICOMMENCE_JOUEUR1,MF_BYCOMMAND)==MF_CHECKED)
  10.  {
  11.   joueur_commence = 1 ;
  12.  }
  13.  else
  14.  {
  15.   if (GetMenuState(menu_principal,ID_QUICOMMENCE_JOUEUR2,MF_BYCOMMAND)==MF_CHECKED)
  16.   {
  17.    joueur_commence = 2 ;
  18.   }
  19.   else
  20.    if (GetMenuState(menu_principal,ID_QUICOMMENCE_ALTERN40013,MF_BYCOMMAND)==MF_CHECKED)
  21.   {
  22.    joueur_commence = 0 ;
  23.   }
  24.  }
  25.  // On réinitialise le jeu
  26.  le_jeu.PlayAnOtherOne(joueur_commence) ;
  27. }
  28. le_visuel->PlotAll(pDC) ;
  29. }
  30. BOOL GraphiqueMainWin::OnEraseBkgnd(CDC* ppDC)
  31. {
  32. CMemDC pDC(ppDC) ;
  33. CRect rect;
  34. GetClientRect(&rect) ;
  35. status_width = rect.Width() ;
  36. width = status_width ;
  37. height = rect.Height() ;
  38. for(int i=0 ; i< status_length ; ++i )
  39.  status_principal.SetPaneInfo(i,status_text[i],SBPS_NORMAL,status_width/3);
  40.         //  si le visuel n'a pas été crée alors on l'initialise
  41.         // sinon on rafraichit
  42. if (le_visuel)
  43.  le_visuel->Refresh(pDC) ;
  44. else
  45. {
  46.  le_visuel = new Dessin(this,pDC)  ;
  47. }
  48. return FALSE;
  49. }


Message édité par LordHarryPotter le 16-04-2005 à 12:04:49
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed