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 :

Comment tracer une ligne comme dans Paint et Word sous MFC


Sujet :

MFC

  1. #1
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut Comment tracer une ligne comme dans Paint et Word sous MFC
    Bonjour, jsuis encore novice sous cet éditeur !

    Je parle de tracer une ligne et lorsque l'on maintient toujours le bouton de la souris, la ligne est maintenue. Je pense qu'il suffit de manipuler le message WM_MOUSEMOVE ou WM_LBUTTONDOWN mais je ne sais pas comment redessiner à chaque mouvement et ne pas laisser de trace à l'ancienne place : j'ai essayé d'utiliser des variables pour stocker les positions précédentes puis avant de tracer la nouvelle ligne après move, on trace à la position stockée une ligne blanche mais ça laisse des traces !

    Mais je serai si comblé si quelqu'un pourrait m'expliquer le fonctionnement de la ligne dans l'application échantillon de MFC nommé DrawCLI, il s'agit d'une ligne comme sous Word, qu'on peut déplacer, repositionner et redimensionner. Génial non mais comment ?

  2. #2
    Membre confirmé Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Points : 521
    Points
    521
    Par défaut
    Bonsoir,

    Il faut utiliser un mode de mixage, une operation XOR lors du tracé.
    La technique est de dessiner la ligne avec une logique XOR, c'est à dire, qu'un second dessin de la meme ligne l'effacera (1 XOR 1 = 0)

    Pour cela utiliser la fonction SetROP2 du Device Context:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    pDC->SelectStockObject(BLACK_PEN);     // stylo noir --> a adapter
    pDC->SetROP2(R2_NOTXORPEN);            // réglage du mode de mixage
    // pour effacer la ligne précédente
    pDC->MoveTo(x1,y1);
    pDC->LineTo(oldx,oldy);
    // pour dessiner la nouvelle ligne
    pDC->MoveTo(x1,y1);
    pDC->LineTo(newx,newy);
    C'est la technique la plus efficace pour dessiner une ligne qui bouge avec la souris.

    @+

  3. #3
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut
    Bonjour,

    J'ai écirt le code suivant avec ton bout de code Stephdim et il ne s'affiche rien, quoi dois-je ajouter pour le rendre opérationnel
    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
    18
    19
    20
    21
    22
    23
    24
    int oldx,oldy,x1,y1;
     
    void CTracerLigneView::OnMouseMove(UINT nFlags, CPoint point) 
    {
    	CPaintDC pDC(this);
    	if ((nFlags & MK_LBUTTON) == MK_LBUTTON){
    		pDC.SelectStockObject(BLACK_PEN);     // stylo noir --> a adapter
    		pDC.SetROP2(R2_NOTXORPEN);            // réglage du mode de mixage
    		// pour effacer la ligne précédente
    		pDC.MoveTo(x1,y1);
    		pDC.LineTo(oldx,oldy);
    		// pour dessiner la nouvelle ligne
    		pDC.MoveTo(x1,y1);
    		pDC.LineTo(point.x,point.y);
    		oldx = point.x;oldy = point.y;
    	}
    	CView::OnMouseMove(nFlags, point);
    }
     
    void CTracerLigneView::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    	x1=point.x;y1=point.y;
    	CView::OnLButtonDown(nFlags, point);
    }
    Entre temps, je comprends la technique du XOR, elle s'applique aussi donc pour le drag d'objet (rectangle, etc.) et bitmap, je veux éviter les trainées qui suivent les drag.

    Comment faire aussi des traits comme sous WinWord, un trait déplaçable, qu'on peut déplacer à la fois les 2 extrêmités de la droite ? Le sample de MSDN qui est DrawCLI m'inspire mais il n'y a pas d'explications, donc difficile à comprendre, sauf qu'il y a de l'OLE là dedans.

  4. #4
    Membre confirmé Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Points : 521
    Points
    521
    Par défaut
    Le code est juste sauf que c'est pas CPaintDC qu'il faut utiliser, mais CClientDC.

    Avec CPaintDC, le Device Context est préparé (au niveau clippage) pour redessiner des zones préalablement déclarées invalides, ici en l'occurence il n'y en a pas, donc rien n'est dessinable ...

    Le bug vient de là

    De manière générale: CPaintDC uniquement dans OnPaint !

    @+

  5. #5
    Membre confirmé Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Points : 521
    Points
    521
    Par défaut
    Quand on fais un Drag'n'Drop en général, on capture la souris par SetCapture(), de maniere a detecter la souris meme si elle sort de la fenetre. (après on peut faire un AutoScroll, défilement automatique, lorsque la souris est en dehors de la fenetre)

    Si on redessine bien la meme ligne (les memes coordonnées d'extremité) il n'y a pas de trainée qui reste ...
    Je procède tjrs comme ça j'ai aucun soucis.

    Pour déplacer ta ligne, il faut déjà détecté un clic sur cette ligne.
    Après la fonction DragDetect() de l'API Windows peut t'aider.

    Après c'est le meme principe, mais on deplace les deux extrémités en meme temps.

    @+

  6. #6
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut
    Bonjour,

    Et si on travaille dans OnPaint, comment tirer bénéfice des messages MouseMove et LButtonDown . En fait, avant d'utiliser CPaintDC, j'ai utilisé CClientDC, même si c'est pas approprié, ça ne trace rien au moins je crois il doit y avoir des gribouillis dans le View de l'application SDI.

    Concernant les lignes comme dans WinWord, je vais m'informer sur cette méthode DragDetect(). Merci stephdim !
    Je suis toujours partant pour des explications sur la ligne dans le sample DrawCLI

  7. #7
    Membre confirmé Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Points : 521
    Points
    521
    Par défaut
    Pourquoi CClientDC n'est il pas approprié ???

    CClientDC te retourne un 'Device Context' de toute la zone "dessinable" de la fenetre. CPaintDC te retourne un 'Device Context' sur la region invalide de la fenetre.

    Si tu utilises CPaintDC, et les fonctions Invalidate(), tu vas avoir un gros probleme de 'flicker' (clignotement lors de l'affichage)

    Je te mets ci dessous a titre d'exemple un bout de code que j'avais realisé pour faire un 'RubberBand' (un rectangle étirable pour sélectionner une zone)

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
     
    void OnLButtonDown(UINT nFlags,CPoint point)
    {
      CRect rect;
      if (TrackRubberBand(rect,point))
      {
        if (!rect.IsRectEmpty())
        {
           rect.right++;
           rect.bottom++;
     
           // ici rect est le rectangle sélectionné
     
        }
      }
    }
     
    // gestion du rectangle de sélection
    bool TrackRubberBand(LPRECT pRect,CPoint refpt)
    {
      bool result=false;
     
      if (GetCapture()==NULL)
      {
        CPen pen;
        if (pen.CreatePen(PS_DOT,0,RGB(0,0,0)))
        {
          UpdateWindow();                             // mise à jour de l'affichage
     
          AfxLockTempMaps();
     
          SetCapture();                               // capture de la souris
     
          CRect oldrect;                              // rectangle de l'ancienne sélection
          bool visible=false;                         // drapeau 'rectangle visible'
     
          while (GetCapture()==this)
          {
            MSG msg;
            VERIFY(GetMessage(&msg,NULL,0,0));
     
            switch (msg.message)
            {
              case WM_MOUSEMOVE:
              {
                CRect newrect;                        // rectangle de la nouvelle sélection
     
                if (!CalcRubberBand(newrect,refpt,msg.lParam))
                  StartAutoScroll();                  // démarrage du défilement automatique
                else
                  StopAutoScroll();                   // arret du défilement automatique
     
                if (!newrect.IsRectEmpty())
                {
                  newrect.right++;
                  newrect.bottom++;
     
                  if (visible)
                  {
                    if (DrawRubberBand(&pen,oldrect,newrect))
                      oldrect=newrect;
                  }
                  else
                  {
                    visible=DrawRubberBand(&pen,newrect);
                    if (visible)
                      oldrect=newrect;
                  }
                }
                else
                {
                  if (visible)
                  {
                    if (!DrawRubberBand(&pen,oldrect))
                    {
                      Invalidate();
                      UpdateWindow();
                    }
     
                    visible=false;
                  }
                }
     
                continue;
              }
              case WM_LBUTTONUP:
              {
                if (visible)
                  if (!DrawRubberBand(&pen,oldrect))  // effacement du rectangle de sélection
                    Invalidate();
     
                CalcRubberBand(pRect,refpt,msg.lParam);   // calcul du rectangle de sélection
     
                result=true;
     
                break;
              }
              case WM_KEYDOWN:
              {
                if (msg.wParam==VK_ESCAPE)
                  break;
     
                continue;
              }
              case WM_TIMER:
              {
                if (msg.wParam==ID_AUTOSCROLL_TIMER)
                {
                  if (visible)
                    if (!DrawRubberBand(&pen,oldrect))
                      Invalidate();
     
                  LONG oldx=m_XOrigin;
                  LONG oldy=m_YOrigin;
     
                  DispatchMessage(&msg);
     
                  UpdateWindow();
     
                  refpt.x+=m_XOrigin-oldx;
                  refpt.y+=m_YOrigin-oldy;
     
                  CPoint newpt;
                  GetCursorPos(&newpt);
                  ScreenToClient(&newpt);
     
                  CalcRubberBand(oldrect,refpt,newpt);
     
                  if (!oldrect.IsRectEmpty())
                  {
                    oldrect.right++;
                    oldrect.bottom++;
     
                    visible=DrawRubberBand(&pen,oldrect);
                  }
                  else
                    visible=false;
                }
                else
                  DispatchMessage(&msg);
     
                continue;
              }
              default:
              {
                if (  (msg.message<WM_MOUSEFIRST  ||  msg.message>WM_MOUSELAST) &&
                      (msg.message<WM_KEYFIRST    ||  msg.message>WM_KEYFIRST)  )
                {
                  DispatchMessage(&msg);
                }
     
                continue;
              }
            }
     
            ReleaseCapture();                         // libération de la souris
            break;
          }
     
          StopAutoScroll();                         // arret du défilement automatique
          AfxUnlockTempMaps(FALSE);
        }
      }
     
      return result;
    }
     
    // calcul du rectangle de sélection
    bool CalcRubberBand(LPRECT pRect,CPoint refpt,CPoint newpt)
    {
      CRect rect;
      GetClientRect(rect);
     
      bool inside=true;
     
      if (newpt.x<0)
      {
        newpt.x=0;
        inside=false;
      }
      else
        if (newpt.x>=rect.right)
        {
          newpt.x=rect.right-1;
          inside=false;
        }
     
      if (newpt.y<0)
      {
        newpt.y=0;
        inside=false;
      }
      else
        if (newpt.y>=rect.bottom)
        {
          newpt.y=rect.bottom-1;
          inside=false;
        }
     
      if (refpt.x<newpt.x)
      {
        pRect->left=refpt.x;
        pRect->right=newpt.x;
      }
      else
      {
        pRect->left=newpt.x;
        pRect->right=refpt.x;
      }
     
      if (refpt.y<newpt.y)
      {
        pRect->top=refpt.y;
        pRect->bottom=newpt.y;
      }
      else
      {
        pRect->top=newpt.y;
        pRect->bottom=refpt.y;
      }
     
      return inside;
    }
     
    // dessin du rectangle de sélection
    bool DrawRubberBand(CPen *pPen,LPCRECT pRect1,LPCRECT pRect2 = /*NULL*/ )
    {
      CDC *pDC=GetDC();                             // 'Device Context' de la fenetre
      if (pDC==NULL)
        return false;                               // erreur
     
      CPen *pOldPen=pDC->SelectObject(pPen);        // sélection du stylo
      CGdiObject *pOldBrush=pDC->SelectStockObject(HOLLOW_BRUSH);   // sélection de la brosse
      int ROP=pDC->SetROP2(R2_NOTXORPEN);           // sélection du mode de mixage
     
      pDC->Rectangle(pRect1);
     
      if (pRect2!=NULL)
        pDC->Rectangle(pRect2);
     
      pDC->SetROP2(ROP);                            // restitution de l'ancien mode de mixage
      pDC->SelectObject(pOldBrush);                 // restitution de l'ancienne brosse
      pDC->SelectObject(pOldPen);                   // restitution de l'ancien stylo
     
      ReleaseDC(pDC);                               // libération du 'Device Context'
     
      return true;                                  // succès
    }
    Comme tu peux le voir, il y a du code
    Mais aucun probleme d'affichage, et aucun conflit avec WM_PAINT.

    A s'inspirer, et a adapter

    @+

  8. #8
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut
    Bonjour,

    J'ai créé l'ID pour le timer : ID_AUTOSCROLL_TIMER et les variables: m_XOrigin et m_YOrigin.
    J'ai déclaré les fonctions
    bool TrackRubberBand(LPRECT pRect,CPoint refpt);
    bool CalcRubberBand(LPRECT pRect,CPoint refpt,CPoint newpt);
    bool DrawRubberBand(CPen *pPen,LPCRECT pRect1,LPCRECT pRect2);
    comme membre du CTrackRubberView
    Il y a les erreurs suivantes:
    - error C2660: 'CTrackRubberView:rawRubberBand' : function does not take 2 arguments
    Cette fonction a 3 arguments à la déclaration mais on l'utilise avec 2 arg après ex: f (!DrawRubberBand(&pen,oldrect))
    - error C3861: 'StartAutoScroll': identifier not found
    - error C3861: 'StopAutoScroll': identifier not found

    Voici comment j'ai implémenté le code sur tracer une ligne après, pourquoi ça ne marche pas :
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    int oldx,oldy,x1,y1,newx,newy;
     
    void CTracerLigneView::OnDraw(CDC* pDC)
    {
    		CTracerLigneDoc* pDoc = GetDocument();
    		ASSERT_VALID(pDoc);
    		if (!pDoc)
    			return;
    		pDC->SelectStockObject(BLACK_PEN);     // stylo noir --> a adapter
    		pDC->SetROP2(R2_NOTXORPEN);            // réglage du mode de mixage
    		// pour effacer la ligne précédente
    		pDC->MoveTo(x1,y1);
    		pDC->LineTo(oldx,oldy);
    		// pour dessiner la nouvelle ligne
    		pDC->MoveTo(x1,y1);
    		pDC->LineTo(newx,newy);
    		oldx = newx;oldy = newy;
    }
    void CTracerLigneView::OnMouseMove(UINT nFlags, CPoint point) 
    {
    	newx=point.x;newy=point.y;
    	CView::OnMouseMove(nFlags, point);
    }
     
    void CTracerLigneView::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    	x1=point.x;y1=point.y;
    	CView::OnLButtonDown(nFlags, point);
    }

  9. #9
    Membre confirmé Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Points : 521
    Points
    521
    Par défaut
    L'exemple que je t'ai donné n'était pas prévu pour etre compilé, tu n'as pas tout les morceaux ... c'etait un copier-coller d'une partie d'une classe CView que j'avais developpé --> uniquement a titre indicatif

    J'ai un peu de temps, voici un bout de code (simple) adapté a ton cas :

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
     
    // fonction qui dessine une ou deux lignes (si pPt2!=NULL)
    // avec un mode de mixage XOR
    // ligne 1 (pPt0-->pPt1)
    // ligne 2 (pPt0-->pPt2)
    bool CMyView::DrawLine(LPPOINT pPt0,LPPOINT pPt1,LPPOINT pPt2)
    {
      CDC *pDC=GetDC();
      if (pDC==NULL)
        return false;        // échec
     
      int ROP=pDC->SetROP2(R2_XORNOTPEN);
      CGdiObject *pOldPen=pDC->SelectStockObject(BLACK_PEN);    // stylo noir
     
      pDC->MoveTo(pPt0->x,pPt0->y);
      pDC->LineTo(pPt1->x,pPt1->y);                 // première ligne
     
      if (pPt2!=NULL)
      {
        pDC->MoveTo(pPt0->x,pPt0->y);
        pDC->LineTo(pPt2->x,pPt2->y);               // deuxieme ligne
      }
     
      pDC->SelectObject(pOldPen);
      pDC->SetROP2(ROP);
     
      ReleaseDC(pDC);
     
      return true;              // succès
    }
     
    // fonction pour définir l'extrémité d'une ligne
    bool CMyView::TrackLine(LPPOINT pPtOrg,LPPOINT pPtExt)
    {
      bool result=false;
     
      if (GetCapture()==NULL)          // pas de capture de souris en cours ?
      {
        UpdateWindow();                 // mise à jour de l'affichage
        SetCapture();                      // capture de la souris
     
        CPoint ptold;                       // ancien point d'extrémité
        bool visible=false;                 // drapeau 'ligne visible'
     
        // au début la ligne n'est pas visible car le point d'extrémité = le point d'origine
     
        while (GetCapture()==this)
        {
          MSG msg;
          VERIFY(GetMessage(&msg,NULL,0,0));
     
          switch (msg.message)
          {
            case WM_MOUSEMOVE:
            {
              // la souris bouge
              CPoint ptnew(msg.lParam);    // nouvelle extrémité
     
              if (pPtOrg->x!=ptnew.x || pPtOrg->y!=ptnew.y)
              {
                 if (visible)
                 {
                    // la ligne etait visible et reste visible - on efface l'ancienne et on dessine la nouvelle
                    if (DrawLine(pPtOrg,&ptold,&ptnew))
                    {
                       // l'affichage est a jour
                       ptold=ptnew;
                    }
                 }
                 else
                 {
                    // la ligne n'etait pas visible et devient visible - on dessine uniquement la nouvelle ligne
                    visible=DrawLine(pPtOrg,&ptnew,NULL);
                    if (visible)
                    {
                       // l'affichage est a jour
                       ptold=ptnew;
                    }
                 }
              }
              else
              {
                 // l'extrémité et l'origine est confondue --> on efface l'ancienne ligne si elle est visible
                 if (visible)
                 {
                   if (!DrawLine(pPtOrg,&ptold,NULL))
                   {
                      // on n'a pas reussi a l'effacer --> on repeint toute la vue
                      Invalidate();
                      UpdateWindow();      // important ! mise à jour de l'affichage
                   }
                   visible=false;               // la ligne n'est plus visible
                 }
              }
     
              continue;                         // on continue la boucle
            }
            case WM_LBUTTONUP:
            {
              // le bouton gauche est relaché
              if (visible)
              {
                 // la ligne etait visible, il faut l'effacer
                 DrawLine(pPtOrg,&ptold,NULL);
              }
     
               CPoint ptnew(msg.lParam);          // nouvelle extrémité
     
                // on renvoi le point a l'appelant
               pPtExt->x=ptnew.x;
               pPtExt->y=ptnew.y;
     
               result=true;                              // tout c'est bien passé
     
               break;                                      // on va vers ReleaseCapture() et sortie de boucle
            }
            default:
            {
              // on filtre les messages de la souris et les messages du clavier pour ne pas les traiter
              if ( (msg.message<WM_MOUSEFIRST || msg.message>WM_MOUSELAST) &&
                   (msg.message<WM_KEYFIRST || msg.message>WM_KEYLAST) )
              {
                 DispatchMessage(&msg);
              }
              continue;                                    // on continue la boucle
            }
          }
     
          ReleaseCapture();
          break;
        }
      }
     
      return result;
    }
     
    void CMyView::OnLButtonDown(UINT nFlags,CPoint point)
    {
      CPoint ptext;
      if (TrackLine(&point,&ptext))
      {
        // ici ptext=le point de l'extrémité
        // et point est l'origine
     
         ....
     
      }
    }
    Pour implémenter le code:
    Créer une classe CMyView dérivée de CView
    Mettre les deux prototypes suivants dans le header de la classe:
    bool DrawLine(LPPOINT,LPPOINT,LPPOINT);
    bool TrackLine(LPPOINT,LPPOINT);

    Créer le gestionnaire pour WM_LBUTTONDOWN

    Et ca devrait fonctionner

    @+

  10. #10
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut
    Bonjour,

    Pour le code que tu as posté Stephdim ! ça marche très bien et je vais m'inspirer sur !
    A propos de la technique du mode de mixage, on utilise toujours pDC->SelectStockObject(BLACK_PEN); c-à-d un stylo noir mais comment faire pour d'autres couleurs !

    Merci bcp pour l'entraide Stephdim !

  11. #11
    Membre confirmé Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Points : 521
    Points
    521
    Par défaut
    Bonjour,

    Pour créer un nouveau stylo regarde la classe CPen des MFC et sa fonction CreatePen --> voir dans MSDN
    Le mieux serait de créer ton stylo perso avant d'entrer dans la boucle, et placer un pointeur du stylo en parametre a la fonction DrawLine()

    Tous type de stylo (fin/epais, pointilles, couleurs ...) fonctionne avec cette methode

    @+

  12. #12
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut
    Ok ! Je crois que mon thread est résolu. Merci à tous ceux qui de près ou de loin répondus à cette discussion.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VBA] Comment supprimer une ligne entiere dans excel
    Par babouoles dans le forum Macros et VBA Excel
    Réponses: 16
    Dernier message: 06/07/2017, 08h34
  2. Réponses: 17
    Dernier message: 18/09/2011, 13h45
  3. Réponses: 8
    Dernier message: 05/10/2009, 18h46
  4. Réponses: 2
    Dernier message: 22/09/2007, 19h38
  5. Comment tracer une ligne verticale dans un graphique
    Par developpeur82 dans le forum MATLAB
    Réponses: 3
    Dernier message: 03/04/2007, 14h06

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