OVH Cloud OVH Cloud

Dessiner une ligne

15 réponses
Avatar
Mathieu Chavoutier
Bonjour.

Je voudrais dessiner une ligne à l'écran, en fonction de la souri :

L'utilisateur clique à un point, qui est l'origine de la droite, et il
déplace sa souris. La droite est dessinée entre le point d'origine, et la
position courrante de la souris, surtout si la souris bouge.

Pour le moment, je fais un invalidate() avec un rectangle allant du point
d'origine à la position de la souris. Cependant, ca blink :o/

Donc, comment faire ?

Je vous remercie

10 réponses

1 2
Avatar
Phildes
Le plus classique est le double-buffering

Tu dessines la zone à modifier dans un "Bitmap" (note : cette zone doit
contenir le fond + l'ancien trait effacé + le nouveau trait)
puis tu dessines ce Bitmap sur ta zone de dessin.






Mathieu Chavoutier a écrit dans le message :
OP#
Bonjour.

Je voudrais dessiner une ligne à l'écran, en fonction de la souri :

L'utilisateur clique à un point, qui est l'origine de la droite, et il
déplace sa souris. La droite est dessinée entre le point d'origine, et la
position courrante de la souris, surtout si la souris bouge.

Pour le moment, je fais un invalidate() avec un rectangle allant du point
d'origine à la position de la souris. Cependant, ca blink :o/

Donc, comment faire ?

Je vous remercie




Avatar
Xavier Lelievre
Il faut effectuer le traitement sur le MouseUp (pas d'Invalidate), garder
les coordonnées pour que cela se redessine également lors d'un paint

Graphics g = la_form.CreateGraphics();
// g.DrawLine(...
g.Dispose();

Xavier


"Mathieu Chavoutier" a écrit dans le message de news:
OP#
Bonjour.

Je voudrais dessiner une ligne à l'écran, en fonction de la souri :

L'utilisateur clique à un point, qui est l'origine de la droite, et il
déplace sa souris. La droite est dessinée entre le point d'origine, et la
position courrante de la souris, surtout si la souris bouge.

Pour le moment, je fais un invalidate() avec un rectangle allant du point
d'origine à la position de la souris. Cependant, ca blink :o/

Donc, comment faire ?

Je vous remercie




Avatar
Mathieu Chavoutier
"Xavier Lelievre" a écrit dans le message de
news:%23%
Il faut effectuer le traitement sur le MouseUp (pas d'Invalidate), garder
les coordonnées pour que cela se redessine également lors d'un paint

Graphics g = la_form.CreateGraphics();
// g.DrawLine(...
g.Dispose();



J'ai fait des tests avant de répondre :
Pourquoi faire un dispose ?
Pourquoi dans le mouseup ? Je l'ai mis dans le mousemove.
En ce moment, le trai ne s'efface jamais. Comment ne garder que celui que je
veux, et supprimer les autres ?

Je vous remercie.
Avatar
LEBRUN Thomas
Les objets de tpe graphics, paint, etc... consomme pas mal de mémoire d'où l'intérêt de Dispose, pour libérer l'objet (et donc la mémoire) lorsque tu as finis de t'en servir.

Pour le mouseup :

Si tu regarde la définition de l'envenement :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwindowsformscontrolclassmouseuptopic.asp

tu liras que c'est lorsque la souris est sur un controle (ta form par exemple) et qu'un des boutons est relaché (ce qui correspond bien à ce que tu veux faire)

A+

--
LEBRUN Thomas
http://morpheus.developpez.com


"Mathieu Chavoutier" a écrit :


"Xavier Lelievre" a écrit dans le message de
news:%23%
> Il faut effectuer le traitement sur le MouseUp (pas d'Invalidate), garder
> les coordonnées pour que cela se redessine également lors d'un paint
>
> Graphics g = la_form.CreateGraphics();
> // g.DrawLine(...
> g.Dispose();

J'ai fait des tests avant de répondre :
Pourquoi faire un dispose ?
Pourquoi dans le mouseup ? Je l'ai mis dans le mousemove.
En ce moment, le trai ne s'efface jamais. Comment ne garder que celui que je
veux, et supprimer les autres ?

Je vous remercie.





Avatar
Julien Bakmezdjian [MS]
Bonjour,

Je pense que Mathieu souhaite que la deuxième extrémité de la ligne "suive"
le pointeur de la souris, pendant tout le temps que le bouton est pressé.

Pourquoi ne pas essayer un Graphics.DrawRectangle pour 'effacer' la ligne
précédente, suivi d'un DrawLine ? Le tout dans le mousemove. Peut-être que
ce sera plus rapide que le Invalidate...

Julien


"LEBRUN Thomas" <lebrun_thomas_at_hotmail.com> a écrit dans le message de
news:
Les objets de tpe graphics, paint, etc... consomme pas mal de mémoire d'où


l'intérêt de Dispose, pour libérer l'objet (et donc la mémoire) lorsque tu
as finis de t'en servir.

Pour le mouseup :

Si tu regarde la définition de l'envenement :



http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwindowsformscontrolclassmouseuptopic.asp

tu liras que c'est lorsque la souris est sur un controle (ta form par


exemple) et qu'un des boutons est relaché (ce qui correspond bien à ce que
tu veux faire)

A+

--
LEBRUN Thomas
http://morpheus.developpez.com


"Mathieu Chavoutier" a écrit :

>
> "Xavier Lelievre" a écrit dans le message de
> news:%23%
> > Il faut effectuer le traitement sur le MouseUp (pas d'Invalidate),


garder
> > les coordonnées pour que cela se redessine également lors d'un paint
> >
> > Graphics g = la_form.CreateGraphics();
> > // g.DrawLine(...
> > g.Dispose();
>
> J'ai fait des tests avant de répondre :
> Pourquoi faire un dispose ?
> Pourquoi dans le mouseup ? Je l'ai mis dans le mousemove.
> En ce moment, le trai ne s'efface jamais. Comment ne garder que celui


que je
> veux, et supprimer les autres ?
>
> Je vous remercie.
>
>
>


Avatar
Mathieu Chavoutier
"Phildes" a écrit dans le message de
news:
Le plus classique est le double-buffering

Tu dessines la zone à modifier dans un "Bitmap" (note : cette zone doit
contenir le fond + l'ancien trait effacé + le nouveau trait)
puis tu dessines ce Bitmap sur ta zone de dessin.



Pour le double buffering, oui, je l'applique déjà :o)
Mais pour afficher une ligne qui suit la souris, je sais pas :o/
Avatar
Mathieu Chavoutier
"Julien Bakmezdjian [MS]" a écrit dans le
message de news:
Bonjour,

Je pense que Mathieu souhaite que la deuxième extrémité de la ligne


"suive"
le pointeur de la souris, pendant tout le temps que le bouton est pressé.



Exacte :o)

Pourquoi ne pas essayer un Graphics.DrawRectangle pour 'effacer' la ligne
précédente, suivi d'un DrawLine ? Le tout dans le mousemove. Peut-être que
ce sera plus rapide que le Invalidate...



Comment je peux faire un DrawRectangle sans passer par l'evenement
drawPanel.Paint += new PaintEventHandler(repaint) ?

Pour le moment, pour dessiner, j'invalide, ce qui lance l'évèmenent paint,
puis je dessine dans la fonction repaint.

(dans la fonction repaint, je peux dessiner, parce qu'il y a

System.Windows.Forms.PaintEventArgs e)
Avatar
Phildes
> Mais pour afficher une ligne qui suit la souris, je sais pas :o/


C'est le même principe :
a - on construit une image dans un Bitmap-de-travail
a.1 - on efface l'ancien trait en redessinant le fond
a.2 - on dessine le nouveau trait
b - on dessine ce Bitmap dans la zone client de la fenêtre.

------------------------------------
A - Voici la méthode la plus simple (et la plus bestiale) : pour effacer
l'ancien trait, on replace le TOUT le fond dans le Bitmap-de-travail. Puis
on dessine le nouveau trait. Enfin on dessine tout le Bitmap-de-travail dans
la fenêtre

Voyez les étapes :
1 - lors du Mouse-Down
a - Créer un Bitmap pour récupérer l'image actuellement affiché (ce sera
l'image de fond)
b - dessiner le 1er trait
c - Créer le Bitmap-de-travail

2 - lors du Mouse-Move
a - dessiner le fond dans le Bitmap-de-travail
b - dessiner le nouveau trait
c - dessinner le Bitmap-de-travail dans la fenêtre

3 - MouseUp
a - libérer les Bitmaps

------------------------------------
B - Evidemment, il est conseillé d'affiner cette méthode en ne copiant que
les zones modifiées.
- Lors du Mouse-move
a - calculer la zone qui englobe le trait a effacer + le trait à dessiner
b - copier cette zone : depuis le Bitmap-de-Fond vers el le
Bitmap-de-travail.
c - dessiner le nouveau trait
d - dessiner cette zone du Bitmap-de-travail sur la fenêtre.





Mathieu Chavoutier a écrit dans le message :
OTZ#

"Phildes" a écrit dans le message de
news:
> Le plus classique est le double-buffering
>
> Tu dessines la zone à modifier dans un "Bitmap" (note : cette zone doit
> contenir le fond + l'ancien trait effacé + le nouveau trait)
> puis tu dessines ce Bitmap sur ta zone de dessin.

Pour le double buffering, oui, je l'applique déjà :o)
Mais pour afficher une ligne qui suit la souris, je sais pas :o/




Avatar
Mathieu Chavoutier
"LEBRUN Thomas" <lebrun_thomas_at_hotmail.com> a écrit dans le message de
news:
Les objets de tpe graphics, paint, etc... consomme pas mal de mémoire d'où


l'intérêt de Dispose, pour libérer l'objet (et donc la mémoire) lorsque tu
as finis de t'en servir.

J'aurai besoin de précisions :
Si je dessine toujours les mêmes images, ai-je besoin de les disposer quand
meme ?

Pour le mouseup :

Si tu regarde la définition de l'envenement :



http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwindowsformscontrolclassmouseuptopic.asp

tu liras que c'est lorsque la souris est sur un controle (ta form par


exemple) et qu'un des boutons est relaché (ce qui correspond bien à ce que
tu veux faire)

Justement, non :o)
Je ne veux pas dessiner uniquement lorsque la souris est en mouseup, je veux
dessiner a partir du moment ou la souris est relachée, et jusqu'a ce qu'il
clique a nouveau : je veux, comme pour les logiciels de dessin, que
lorsqu'il clique a un endroit (X), il y ait un trait dessiné entre X et la
position courante de la souris, et meme lorsque la souris bouge.
Avatar
Julien Bakmezdjian [MS]
Bonjour,

Il faut créer un objet Graphics grâce à la méthode statique
Graphics.FromHwnd. En lui passant le handle du panel, vous devriez pouvoir
récupérer un graphics qui y est associé.

Julien

"Mathieu Chavoutier" a écrit dans le message de
news:

"Julien Bakmezdjian [MS]" a écrit dans le
message de news:
> Bonjour,
>
> Je pense que Mathieu souhaite que la deuxième extrémité de la ligne
"suive"
> le pointeur de la souris, pendant tout le temps que le bouton est


pressé.

Exacte :o)

> Pourquoi ne pas essayer un Graphics.DrawRectangle pour 'effacer' la


ligne
> précédente, suivi d'un DrawLine ? Le tout dans le mousemove. Peut-être


que
> ce sera plus rapide que le Invalidate...

Comment je peux faire un DrawRectangle sans passer par l'evenement
drawPanel.Paint += new PaintEventHandler(repaint) ?

Pour le moment, pour dessiner, j'invalide, ce qui lance l'évèmenent paint,
puis je dessine dans la fonction repaint.

(dans la fonction repaint, je peux dessiner, parce qu'il y a

System.Windows.Forms.PaintEventArgs e)




1 2