IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

Des classes autour de CPaint


Sujet :

MFC

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 25
    Par défaut Des classes autour de CPaint
    Bonjour,

    Le but de mon post est de connaître la taille d’un texte (longueur hauteur) dans une classe. Pour cela, il faut utiliser la fonction GetTextExtentPoint32 qui me retourne la taille d’un texte dans son contexte.

    Problème :

    J’ai une classe CTestDlg qui hérite de CDialog ou il y a les membres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class CTestDlg : public CDialog
    {
    public:
       CDrawing drawing;
     
    // Dialog Data
    	//{{AFX_DATA(CTestDlg)
    	enum { IDD = IDD_TEST_DIALOG };
    	CDrawingView	m_DrawingWindow;
    	//}}AFX_DATA}
    CDrawing est une classe qui gère un dessin (Texte, cercle, ligne...) et CDrawingView est une classe gérant la vue du dessin dans un object type "Picture" d’une fenêtre graphique.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class CDrawingView : public CStatic
    {
    public:
    	CDrawing* m_pDrawing;
    protected:
    	//{{AFX_MSG(CDrawingView)
    	afx_msg void OnPaint();
    ...
    }
    Le pointeur m_pDrawing est initialisé à la construction de la classe CtestDlg :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_DrawingWindow.m_pDrawing = &drawing;
    IDC_DRAWINGWINDOW est un contrôle (ressource) pour mon "Picture" de la fenètre graphique.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void CTestDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(CTestDlg)
    	DDX_Control(pDX, IDC_DRAWINGWINDOW, m_DrawingWindow);
    	//}}AFX_DATA_MAP
    }
    La fonction de dessin (IDC_DRAWINGWINDOW) est réalisée par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void CDrawingView::OnPaint() 
    {
    	CPaintDC dc(this); // device context for painting
    	if(m_pDrawing!=NULL)
    	{
    		m_pDrawing->Paint(dc.m_hDC);
    	}
    }
    m_pDrawing->Paint permet de dessiner les données du dessin (cercles, lignes, textes...). La valeur du handle de dc change à chaque appel de cette fonction.

    J’ai besoin d’appeler la fonction de taille de texte dans ma classe CDrawing sans passer un handle de CPaintDC en paramètre.

    Alors comment réaliser cette fonction de manière propre pour me donner un handle de CPaintDC :
    • Faire une fonction amie dans CdrawingView qui me retourne un dc ?
    • Mettre une variable membre dans CDrawing pointant dans CDrawingView afin d’accéder au CPAintDC ?
    • Ou autre ?

    J’espère avoir été clair sur mon problème.

    Merci d’avance.
    Hervé

  2. #2
    Membre expérimenté
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Par défaut
    La fonction CreateCompatibleDC(NULL) devrait répondre à ton besoin en te permettant de créer un contexte hors phase de rendu. Tu as aussi la fonction CreateIC("DISPLAY", NULL, NULL, NULL) qui pourrait faire l'affaire si tu n'as vraiment besoin que de connaître des métriques précises.

  3. #3
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    Pour en revenir à la base de ton problème, qui, si j'ai bien compris, est de déterminer le plus petit rectangle englobant un texte dans un contexte graphique donné, j'utiliserai simplement la méthode DrawText avec le flag DT_CALCRECT.

    Par exemple (dans une méthode DrawItem):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CDC * dc = CDC::FromHandle(lpDrawItemStruct->hDC);
    CString texte;
    CRect rect;
    dc->DrawText(texte, &rect, DT_CALCRECT);
    ça ne ne fera que simuler l'écriture du texte dans ce contexte et te renverra la taille du rectangle.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 25
    Par défaut
    Merci pour vos réponses.

    En effet, je pense que la fonction CreateCompatibleDC(NULL) devrait répondre à ce besoin. La base de mon problème n'est pas de dessiner un texte mais de le déplacer après l'avoir dessiner. J'ai besoin de connaître la taille de ce texte afin de le déplacer dans une zone ou il n'y a pas d'autres éléments.

    Avec vos réponses j'ai assez d'éléments pour continuer. Je vous tiendrais au courant ce WE.

    Hervé

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 25
    Par défaut
    J’ai effectué le test avec CreateCompatibleDC, mais cela ne fonctionne pas. En fait le DC compatible est celui de la fenêtre et non pas celui du dessin…

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    BOOL CDrawing::MoveNailText(Str_nail *pNail, num_layer layer, double NewX, double NewY )
    {
    ....
    	HDC hDc;
    	if (hDc = CreateCompatibleDC(0))
    	{
    		drwGetTextRect(m_hDrawing, hDc, &m_EntityHeader, DataText.strText, &RpRect);
    	}}
    Je pense que j’ai mal posé mon problème. Dans ma classe CDrawing, je n’arrive pas à accéder à l'handle mon graphique CDrawingView.

    Si je déclare une instance :
    J’ai une erreur de compilation :
    'CPaintDC::CPaintDC' : cannot convert parameter 1 from 'class CDrawing *const ' to 'class CWnd *'
    Normal puisque CDrawing n’hérite pas de CPaint. Alors comment je peux accéder au m_hDc de ma classe CdrawingView ? J’ai bien un pointeur CDrawingView -> CDrawing, mais pas l’inverse. Si je le créé, j’ai l’impression que cela risque de faire un peut « bidouille ».

    C’est ce que je ne comprend pas dans « lpDrawItemStruct->hDC » par TheGzD. Mais est ce la bonne solution ?

    Merci.

  6. #6
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    A quel endroit comptes-tu faire le calcul de ton rectangle ?

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 25
    Par défaut
    Dans CDrawing en appelant le pointeur de fonction drwGetTextRect pointant vers une dll. J'ai récupéré une librairie pour effectuer des dxf sur http://www.codeproject.com/KB/library/cadlib.aspx

  8. #8
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    Ta classe CDrawing n'est en rien une classe de base MFC, tu l'as développé toi-même. Ce qui m'intéresse c'est dans quelle méthode tu le fais. Si ce n'est pas appelé ou fait dans une surcharge d'une méthode "classique" d'affichage je pense que le problème commence par là ...

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 25
    Par défaut
    Merci beaucoup pour ta réponse.

    Comme expliqué auparavant, j’ai repris un exemple d’une lib pour générer des fichiers dxf (drawing exchange format) et de plus je commence avec les MFC

    Après différents essai, j’ai compris mon problème : ma fenêtre principale a un control de type picture. Dans mes essais de codes, je n’arrive pas à obtenir un handle du contrôle picture, mais j’obtiens celui de ma fenêtre…

    Il y a quand même quelque chose que je ne comprend pas dans la classe CdrawingView : CtestDlg (fenêtre principale) initialise bien le contrôle IDC_DRAWINGWINDOW par :
    DDX_Control(pDX, IDC_DRAWINGWINDOW, m_DrawingWindow);

    La méthode CdrawingView ::OnPaint initialise bien le bon handle avec le code indiqué au dessus, alors que le code suivant me donne le handle de ma fenêtre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    BOOL CDrawing::MoveNailText(Str_nail *pNail, num_layer layer, double NewX, double NewY )
    {
    ....
    	CPaintDC dc(m_pDrawingView);    // Access à la classe CDrawingView
    ....
    }
    Je pensais qu’il suffisait d’initialiser l’instance de dc avec CDrawingView pour obtenir le bon handle.

    Ne serait il pas du à la déclaration dans CDrawingView de :
    afx_msg void OnPaint(); dans la définition de la classe (DrawingView.h) ?

    Dans la FAQ, j’ai vu qu’il était possible d’obtenir un pointeur vers un contrôle (IDC_). Mais avec ce pointeur comment obtenir le handle de ce fameux contrôle ?

    Encore merci.

    Hervé

  10. #10
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    Il y a quand même quelque chose que je ne comprend pas dans la classe CdrawingView : CtestDlg (fenêtre principale) initialise bien le contrôle IDC_DRAWINGWINDOW par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DDX_Control(pDX, IDC_DRAWINGWINDOW, m_DrawingWindow);
    ceci n'initialise rien mais attache une variable de contrôle à l'objet graphique ayant pour identifiant IDC_DRAWINGWINDOW

    La suite de ton post est encore plus confuse
    Quand tu veux dessiner sur un DC, tu n'as en toute logique à l'instancier que si tu comptes y faire un travail temporaire. Dans le cas où tu veux dessiner dans ta fenêtre (ou plus généralement sur un CWnd) tu récupères ce DC par exemple via les paramètres passé à la méthode dans laquelle tu dessineras (comme dans l'exemple de la méthode OnDrawItem dans mon 1er post). Si tu ne l'a pas lors de l'appel tu peux toujours le récupérer via la méthode GetDC.

    Est-ce un peu plus clair maintenant ?

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 25
    Par défaut
    Dans la fenêtre principale, il y a un objet graphique (l’endroit du dessin) et non une fenêtre type SDI.

    La fonction CDrawing::Paint( HDC hdc ) est appelée par m_DrawingView.OnPaint . L’exemple gère le zoom du graphisme…, et cette fonction OnPaint utilise GetTextExtentPoint32. Je n’obtiens pas le même résultat avec OnPaint qu’avec l’appel provenant de CDrawing::MoveNailText.

    Merci

  12. #12
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    Je ne comprends pas vraiment ta question ... vu qu'en fait il n'y a pas de question dans ton dernier post
    A mon avis, si on reprend la problématique de ton premier post, je t'ai déjà donné toutes les billes pour t'en sortir.
    Je pense que tu t'attaques à un exemple de classes que tu ne comprends pas vraiment vu tes connaissances en MFC. Essaye de revenir à la base des MFC en jetant un œil aux tutos MFC ou à la FAQ VC++ par exemple.

    Bon courage !

    PS : la doc de GetTextExtentPoint32, au cas où

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 25
    Par défaut
    Merci pour ton aide

    Effectivement, il y a des choses que j’ai du mal à saisir, et j’ai commencé depuis quelques temps à voir et revoir les tuto et FAQ…
    Je regarde également de prêt la structure DRAWITEMSTRUCT comme ton exemple. Mais la classe que j’utilise ne se sert pas de la méthode OnDrawItem mais de OnDraw…

    J’ai modifié mon code, et je pense cependant trouver mon problème.

    Cette méthode est appelé lorsqu’il y a un évènement d’un rafraîchissement du dessin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    void CDrawingView::OnPaint() 
    {
    	CPaintDC dc(this); // device context for painting
     
    	if(m_pDrawing!=NULL)
    	{
    		if(m_pDrawing->isOpen())
    		{
    			dc.SetTextAlign(TA_BASELINE | TA_CENTER);
    			dc.SetTextColor(::GetSysColor(COLOR_WHITE));
    			dc.SetBkMode(OPAQUE);
    			dc.TextOut(100, 20, "DataText OnPaint");
    		}
    	} else
    		... on dessine un carré noir 
    	}
    }
    Cette fonction membre de la même classe est appelé lors d’un appuie sur un bouton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void CDrawingView::PaintIt() 	
    {
    	CPaintDC dc(this); // device context for painting
     
    	dc.SetTextAlign(TA_BASELINE | TA_CENTER);
    	dc.SetTextColor(::GetSysColor(COLOR_WHITE));
    	dc.SetBkMode(OPAQUE);
    	dc.TextOut(10, 100, "DataText Paint it");
    }
    Pour la fonction PaintIt je n’ai pas d’affichage. Pourquoi? Parce que ce n’est pas une méthode OnDraw, appelé par le gestionnaire d’événement ? Si c’est le cas, alors quel objet graphique « est pointé par le dc » lors de l’appel de cette fonction PaintIt ?

    Je pense que ce post va bientôt passé à « résolu »…

    Hervé

  14. #14
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 526
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 526
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class CDrawingView : public CStatic
    ehhh faut qu'on m'explique un truc !
    CStatic c'est une zone de texte pour afficher du texte je ne comprends vraiment pas pourquoi faire hériter une classe de dessin d'une zone de texte.
    http://msdn.microsoft.com/en-us/libr...=vs.80%29.aspx

  15. #15
    Membre éprouvé
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Par défaut
    En suivant le lien que tu viens de donner, on trouve directement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class CStatic : public CWnd
    Tu as ta réponse à moins que tu ne saches pas ce qu'est un CWnd ...

  16. #16
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 461
    Par défaut
    Mat.M n'a pas tord.
    CStatic est une CWnd mais CWnd n'est pas une CStatic.
    Une CStatic à une "propriété" "Texte" qui n'est pas forcément pertinente.

    Donc si cette propriété ne sert pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class CDrawingView : public CWnd

Discussions similaires

  1. Diagramme des classes pour l'interface visuel
    Par robv dans le forum Diagrammes de Classes
    Réponses: 2
    Dernier message: 25/06/2004, 10h50
  2. [debutant] Comment ajouter des .class ?
    Par Slein dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 30/04/2004, 14h30
  3. Créer les get et set des classes
    Par cameleon2002 dans le forum JBuilder
    Réponses: 3
    Dernier message: 17/09/2003, 21h03
  4. specifier les chemins des .class
    Par draken dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 29/07/2003, 09h35
  5. Inserer des classes java existantes
    Par 2000 dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 20/03/2003, 12h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo