Control et Transparent

Résolu
Ordinastie Messages postés 93 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 17 octobre 2008 - 16 août 2005 à 05:04
Ordinastie Messages postés 93 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 17 octobre 2008 - 17 août 2005 à 17:36
Salut.

J'ai une carte déssinée dans un pictureBox et j'ai besoin d'ajouter des marqueurs à differents endroits sur cette carte. J'ai plus ou moins réussi à faire ce que je cherchais en faisant hériter mes marqueurs de System.Windows.Forms.Control et en onverridant la méthode OnPaint de Control.
Le problème, c'est que mes marqueurs seraient plutot rond et que j'aimerais par conséquent que le fond du controle soit plutot transparent.
Sachant que le BackColor = Color.Transparent génère une execption, si quelqu'un à un idée pour remédier à ce problème...

Merci d'avance,
Ordinastie.

14 réponses

bucherb Messages postés 412 Date d'inscription lundi 26 mai 2003 Statut Membre Dernière intervention 13 août 2007
17 août 2005 à 15:24
Ptêtre une autre méthode

Tu hérite de usercontrol, tu dessine ta carte a la main en overridant OnPaint, et tu override le mousemove pour tester si le curseur se trouve sur un de tes carrés (si j'ai bien tout compris) Au moins t'as tout qui est géré au même endroit.

-------------------------
Trambert le vert
3
Ordinastie Messages postés 93 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 17 octobre 2008 2
17 août 2005 à 15:55
Salut.

Bon, je crois qu'on va oublier l'API Win32

@bucherb
Oui c'est ce que je pensais vers quoi me tourner. Dessiner les marqueurs dans l'override de la map, et appeler les event des marqueurs dans les override de la map aussi, du genre:
(dans map : pictureBox)
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e); // pour dessiner la carte
Marqueurs.PaintAll(e); //passe en revue ts les marqueurs et les dessine sur e
}

protected override void OnMouseMove(EventArgs e)
{
Markeur mark = Marqueur.getMarqueurOnPos(e.X, e.Y);
if(mark != null)
{
mark.OnMouseHover();
}
}

enfin un truc comme ca quoi.

Mais j'aurai quand même préférer que les event du marqueur soient déclenchés automatiquement

Merci encore pour vos réponses
Ordinastie.
3
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
16 août 2005 à 09:51
ajoute dans le constructeur de ton contrôle :

this.SetStyle(ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.SupportsTransparentBackColor, true);

comme ca tu pourras mettre ton Background à transparent.


<HR>
Sébastien FERRAND

Blog : http://blogs.developpeur.org/sebmafate
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
16 août 2005 à 15:59
Il me semble que dériver de UserControl c'est mieux que de dériver de Control. Pour le double buffer il faudrait aussi activer le style "AllPaintingInWmPaint", mais du coup je ne sais pas quel comportement va avoir le style "SupportsTransparentBackColor", finallement c'est peut être plus simple si tu as plusieurs marqueurs de les dessiner directement sur la carte.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Ordinastie Messages postés 93 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 17 octobre 2008 2
16 août 2005 à 16:34
@Sebmafate:
Effectivement, maintenant il accepte la couleur transparente, mais il dessine pas pour autant ce qui est censé etre derriere le controle, a savoir la carte. Je sais pas ce qu'il dessine, mais j'ai l'impression que le controle ne le sait pas lui même

@Lutinore
Ca ete ma premiere solution, qui marche effectivement de facon niquel, mais j'ai besoin de la gestion des evenements de la souris pour les marqueurs. (Click, MouseHover, etc...). Y'a t-il une classe dont je pourrais dériver pour implémenter les "Listeners" et les events?

Merci pour vos réponses,
Ordinastie
0
Ordinastie Messages postés 93 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 17 octobre 2008 2
16 août 2005 à 16:36
Petite rectification: le transparent marche en fait, mais si je pouvais implémenter la deuxième solution, ca serait plus efficace =)
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
16 août 2005 à 17:00
Y'a bien IMessageFilter, mais c'est un peu lourd. Ce que tu veux faire c'est un peu comme un sprite dans un jeu , et tester si la souris clique dessus !?
0
Ordinastie Messages postés 93 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 17 octobre 2008 2
16 août 2005 à 17:23
Oui, voila, il faut que mes marqueurs réagissent à la souris, à son click et à son survol. L'ideal serait qu'il puisse aussi réagir aux touches du clavier.

C'est pour ca que j'avais essayé de faire dériver de Control au début car il y avait de base tous les events. Mais je prefererai faire ma propre implémentation, déjà pour apprendre, mais aussi parce que je pense que ca serait plus propre

J'ai commencé par créer mon event avec mon delegate, mais maintenant, il faudrait qu'il soit appelé quand il faut, cad au survol de la souris ou au click.

Ordinastie.

PS: Je viens de voir ton lien, effectivement, ca m'a l'air un peu lourd . Mais je trouve ca étonant qu'il n'y ait pas d'interface de listeners, un peu comme en Java "MouseEventListener" ou "EventListener" (de mémoire). C'était bien pratique quand même. Enfin, je continue de chercher
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
16 août 2005 à 18:22
Peut être que ca existe !? Je vais regarder, ca m'intéresse aussi..
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
16 août 2005 à 19:26
Je me suis amusé à utiliser des marqueurs comme si c'etait des sprites:

namespace HitTest
{
public class Mark
{
private Bitmap bmp;
private Color mask;
private Rectangle bounds;


public Rectangle Bounds { get { return bounds; } }


public Mark( Bitmap bmp, Rectangle bounds )
{
this.bmp = bmp;
this.bounds = bounds;
this.mask = bmp.GetPixel( 0, 0 );
}


public void Draw( Graphics g )
{
if ( bmp != null )
{
g.DrawImage( bmp, bounds ); // Add try/catch.
}
}


public bool Hit( int x, int y )
{
if ( bounds.Contains( x, y ) )
{
x = x - bounds.X;
y = y - bounds.Y;

if ( bmp.GetPixel( x, y ) != mask )
{
return true;
}
}

return false;
}
}


public class MainForm : Form
{
private Bitmap bmp;
private ArrayList marks;


public MainForm( ) : base( )
{
this.Text = "HitTest";
this.SetStyle( ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true );
this.Visible = true;


bmp = new Bitmap( "mark.bmp" ); // Add try/catch
bmp.MakeTransparent( bmp.GetPixel( 0, 0 ) );


marks = new ArrayList( );
marks.Add( new Mark( bmp, new Rectangle( 0, 0, 48, 48 ) ) );
marks.Add( new Mark( bmp, new Rectangle( 100, 100, 48, 48 ) ) );
}


protected override void OnMouseDown( MouseEventArgs e )
{
//base.OnMouseDown( e );


if ( e.Button == MouseButtons.Left )
{
foreach( Mark m in marks )
{
if ( m.Hit( e.X, e.Y ) )
{
MessageBox.Show( "Hit !" );
}
}
}
}


protected override void OnPaint( PaintEventArgs e )
{
//base.OnPaint( e );


Graphics g = e.Graphics;


foreach( Mark m in marks )
{
m.Draw( g );
}
}


[ STAThread ]
private static void Main( )
{
Application.EnableVisualStyles( );
Application.Run( new MainForm( ) );
}
}
}

Par exemple si le marqueur ressemble au drapeau japonais, càd détouré avec une couleur unique et un rond au centre, c'est seulement en cliquant sur le rond que le message "Hit !" apparaît, si c'est pas ce que tu veux faire c'est pas grave, ca servira à d'autres, me suis amusé : )
0
Ordinastie Messages postés 93 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 17 octobre 2008 2
17 août 2005 à 00:27
C'est interessant, mais non, c'est pas vraiment ce que je cherche :p
Ce que je cherche de quoi la classe Mark (dans ton code) doit hériter pour pouvoir implémenter les envent MouseHover/MouseDown etc...
Parce que si je crée un event perso avec un delegate et tout, il n'est pas déclenché par la souris, faut le declencher manuellement. Et je sais pas trop comment faire.

Je pourrais me servir des evenements de la map (pictureBox) et tester si c'est sur un marqueurs, mais je preferais le faire directement a partir du marqueur.

En tout cas, merci pour tes recherches.
Ordinastie
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
17 août 2005 à 05:22
Si tu connais bien l'API Win32 tu peux dériver de NativeWindow, c'est une classe "bas niveau" qui remplace les méthodes natives RegisterClassEx et CreateWindowEx.
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
17 août 2005 à 16:30
Bha, ce que vient de dire Bucherb, c'est exactement ce que j'ai montré dans mon code pécédent, à part que pour l'exemple je fais tout directement dans la forme sans passer par un UserConttrol ou une PictureBox, c'est le OnPaint de ma forme qui dessine tout les marqueurs et c'est le OnMouseDown de ma forme qui test si la souris a cliqué sur un marqueur. : )
0
Ordinastie Messages postés 93 Date d'inscription samedi 29 janvier 2005 Statut Membre Dernière intervention 17 octobre 2008 2
17 août 2005 à 17:36
Oui, c'est vrai, mais à la base, c'est pas vraiment ce que je cherchais
Je cherchais un classe dont dériver pour pouvoir implémenter directement les event souris sans passer par System.Windows.Forms.Control

Mais apparement, ca n'a pas l'air d'exister alors j'ai pas trop le choix en fait.
Tant pis =)

Ordinastie.
0
Rejoignez-nous