Control et Transparent [Résolu]

Signaler
Messages postés
93
Date d'inscription
samedi 29 janvier 2005
Statut
Membre
Dernière intervention
17 octobre 2008
-
Messages postés
93
Date d'inscription
samedi 29 janvier 2005
Statut
Membre
Dernière intervention
17 octobre 2008
-
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

Messages postés
412
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
13 août 2007

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
Messages postés
93
Date d'inscription
samedi 29 janvier 2005
Statut
Membre
Dernière intervention
17 octobre 2008
2
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.
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
33
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
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
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.
Messages postés
93
Date d'inscription
samedi 29 janvier 2005
Statut
Membre
Dernière intervention
17 octobre 2008
2
@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
Messages postés
93
Date d'inscription
samedi 29 janvier 2005
Statut
Membre
Dernière intervention
17 octobre 2008
2
Petite rectification: le transparent marche en fait, mais si je pouvais implémenter la deuxième solution, ca serait plus efficace =)
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
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 !?
Messages postés
93
Date d'inscription
samedi 29 janvier 2005
Statut
Membre
Dernière intervention
17 octobre 2008
2
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
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
Peut être que ca existe !? Je vais regarder, ca m'intéresse aussi..
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
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é : )
Messages postés
93
Date d'inscription
samedi 29 janvier 2005
Statut
Membre
Dernière intervention
17 octobre 2008
2
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
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
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.
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
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. : )
Messages postés
93
Date d'inscription
samedi 29 janvier 2005
Statut
Membre
Dernière intervention
17 octobre 2008
2
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.