03 mars 2008
Advanced Windows Forms pour les nuls (et les autres)
Dans le cadre de mon Projet Industriel ESIAL, j'ai été amené à utiliser Microsoft Visual Studio 2005 afin de bénéficier de Windows Forms .NET dans le langage C#. Ce post vise à vous exposer mes conclusions par rapport à la question fatidique : "Comment réaliser un contrôle réellement transparent qui respecte les règles ancestrales du Z-Order.
Le problème de base, c'est que si l'on utilise des PictureBox classiques, et que l'on met la propriété BackColor à Transparent, on s'attend à ce que les images soient affichées sur un fond transparent. Cependant, ce n'est pas le cas. Comme vous le voyez sur la première image, le font Transparent est en réalité u fond de la couleur du fond de son parent ... Cela n'est pas très convaincant ... Pour arranger cela il nous faut réaliser un peu de magie noire dans windows forms, et créer un composant utilisateur personnalisé qui contient le code suivant :
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
// Force la transparence du contrôle.
cp.ExStyle |= WS_EX_TRANSPARENT;
return cp;
}
}
protected override void OnPaintBackground(PaintEventArgs e) {}
protected override void OnMove(EventArgs e)
{
RecreateHandle();
}
On se retrouve donc avec un composant certes transparent, mais qui ne respecte plus le Z-Order (l'ordre dans lequel les contrôles doivent être dessinés, et qui détermine accessoirement lequel sera au dessus et lequel en dessous : la propriété autorise le contrôle à être effectivement transparent, la première méthode sert à ne pas dessiner de fond (et donc à être totalement transparent), et la seconde sert à redessiner le contrôle quand on le déplace.
Nous reste donc à corriger le fameux problème du Z-Order, sans quoi l'interception des événements de souris, de clavier, et autres se feront contre le bon sens par rapport à l'affichage (tout sera reçu par le contrôle dessiné le plus au fond). Pour ce faire il suffit de rajouter le code suivant à notre classe ...
protected override void OnPaint(PaintEventArgs e)
{
Application.DoEvents();
base.OnPaint(e);
}
Cette méthode a pour effet de forcer le contrôle à attendre que les autres événements aient été traités avant de se dessiner effectivement. Ceci inverse la pile de dessin et a pour effet de rétablir la cohérence du Z-Order tant chéri.
En revanche, cette méthode a ses limites : je ne l'ai pas testé (j'ai trop peur de constater les dégâts), mais je pense que cette méthode provoquera plus de problèmes qu'elle n'en résout si il y a un mélange de contrôles transparents et non transparents ... mais aussi longtemps que tous les contrôles descendent de celui que vous venez de définir, il n'y aura aucun souci.
Commentaires
Poster un commentaire
Rétroliens
URL pour faire un rétrolien vers ce message :
http://www.canalblog.com/cf/fe/tb/?bid=64016&pid=8187154
Liens vers des weblogs qui référencent ce message :


