Dessiner sur un control

Résolu
madkeyboard Messages postés 100 Date d'inscription mercredi 27 avril 2011 Statut Membre Dernière intervention 21 décembre 2012 - 30 nov. 2012 à 16:26
madkeyboard Messages postés 100 Date d'inscription mercredi 27 avril 2011 Statut Membre Dernière intervention 21 décembre 2012 - 12 déc. 2012 à 10:58
Bonjour !

Je viens vers vous pour un problème pour lequel je peine à trouver solution satisfaisante sur le net :
je cherche à dessiner quelques lignes toutes bêtes sur une richTextBox.

Ayant fait une IHM bien personnalisée, j'ai déjà une méthode qui réagit à l'évènement Paint de ma form pour gérer le design de mon appli.
J'ai donc essayé de rajouter mes lignes en vrac là dedans, bien entendu la richTextBox recouvre tout !

J'ai fouillé le net, notamment ici et
ça ne m'a guère aidé, à part à me dire que c'est pas évident !

Du coup, j'ai essayé ça, dans ma méthode Paint :
private void FormIHMProcedures_Paint(object sender, PaintEventArgs pevent)
{
    Graphics g = pevent.Graphics;
    Graphics gRichTextBox = richTextBoxInfoBar.CreateGraphics();   //C'est l'objet graphique que j'ai rajouté en espérant
                                                                   //pouvoir dessiner directement sur la richTextBox...
    //Test d'une ligne (je précise : ça ne fonctionne pas) :
    //Note : ma richTextBox fait 923pixels/44, et est positionnée en 5; 542
    gRichTextBox.DrawLine(new Pen(Color.FromArgb(241, 120, 226)), new Point(500, 3), new Point(500, 13));

    //Dessins divers...
    g.DrawLine(new Pen(Color.FromArgb(236, 233, 216), 2), new Point(0, 593), new Point(935, 593));
    g.DrawLine(new Pen(Color.FromArgb(172, 168, 153)), new Point(0, 594), new Point(934, 594));
    g.DrawLine(new Pen(Color.FromArgb(113, 111, 100)), new Point(0, 595), new Point(934, 595));
    g.DrawLine(new Pen(Color.FromArgb(172, 168, 153)), new Point(0, 658), new Point(934, 658));
    //...
}

Le tout ne fonctionne pas...
Je me suis donc dis : je vais trouver la méthode Paint du control (intuition suite à la lecture du premier lien donné ci-dessus), et ben y'en a pas pour une richTextBox (Note : y'en a pas exemple pour une pictureBox) !! Est-ce que c'est moi qui a mal fouillé ?

Bref, quelqu'un voit-il une solution ?

Merci d'avance !
Mad Keyboard

2 réponses

yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 24
30 nov. 2012 à 22:23
Salut,

Il y a une solution très complexe et cela necessite une bonne connaissance du protocole RTF :

Ne pas dessiner directement sur le controle mais passer par une image insérée une fois dessinée.

Cela consiste à dessiner dans une image MetaFile puis de l'insérer bit à bit dans le code rtf avec une entete du genre :
rtf.Append(@"{\pict\wmetafile8\picw0000\pich0000\picwgoal0000\pichgoal0000 ");
Les 0 étant les vrais valeurs de
largeur, hauteur metafile et largeur/hauteur en twips de la destination
puis ferme le protocole
rtf.Append(@"} ");

Pour le bit a bit il faut utiliser p-invoke :

[DllImportAttribute("gdiplus.dll")]
private static extern uint GdipEmfToWmfBits(IntPtr hEmf, uint bufferSize, byte[] buffer, int mappingMode, EmfToWmfBitsFlags flags);


EmfToWmfBitsFlags est une énumération à redéclarer.
Certaines constantes sont aussi à prendre dans les fichiers #include C++ comme par exemple : MM_ANISOTROPIC

Puis utiliser un code du genre (NON COMPLET !!)
Ce serait trop long ici

Metafile metaFile = null;
IntPtr hdc;
MemoryStream stream = new MemoryStream();
using ( graphics = richEdit.CreateGraphics() )
{
hdc = graphics.GetHdc();
metaFile = new Metafile(stream, hdc);
graphics.ReleaseHdc(hdc);
}
// Enhanced Metafile graphics context 
using ( graphics = Graphics.FromImage(metaFile) )
{
graphics.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height));
}
IntPtr hEmf = metaFile.GetHenhmetafile();
uint bufferSize = GdipEmfToWmfBits(hEmf, 0, null, MM_ANISOTROPIC, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
byte[] buffer = new byte[bufferSize];
uint convertedSize = GdipEmfToWmfBits(hEmf, bufferSize, buffer, MM_ANISOTROPIC, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);

StringBuilder rtf = new StringBuilder((int)bufferSize);
for ( int i = 0; i < buffer.Length; ++i )
rtf.Append(String.Format("{0:X2}", buffer[i]));



Au final tu as le dessin que tu voulait mais avec un "calque" pour ainsi dire.

Bye...
3
madkeyboard Messages postés 100 Date d'inscription mercredi 27 avril 2011 Statut Membre Dernière intervention 21 décembre 2012 1
12 déc. 2012 à 10:58
Salut !

Je reviens après une bonne période de crève ^^
Merci beaucoup pour ta réponse, je garde ça dans un coin si un jour je dois faire quelques de compliqué allant dans ce sens là !

Mais dans l'immédiat, je ne dois faire qu'une pauvre ligne de séparation, je vais donc faire une bête pictureBox avec ma ligne chargée dedans (j'ai déjà pas mal d'images dans mon appli, 1 de plus ou 1 de moins...) que je mettrais en avant plan par rapport à ma richTextBox, ce sera plus simple !
J'espérais qu'il y avait une solution un peu plus basique, ou plus "propre" pour ainsi dire.

Merci pour ton aide et à bientôt !
Mad Keyboard
3
Rejoignez-nous