begin process at 2010 03 19 21:41:47
  Trouver un code source :
 
dans
 
Accueil > Forum > 

VB.NET et VB 2005

 > 

Windows

 > 

UserControl

 > 

Tranparence d'un contrôle durant son déplacement


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Tranparence d'un contrôle durant son déplacement

mercredi 26 décembre 2007 à 18:27:19 | Tranparence d'un contrôle durant son déplacement

gregory__forel

Bonjour à tous,

J'essaye d'écrire une classe pour créer un composant dont le fond sera transparent. Cela fonctionne lorsque celui ci est ajouté a la forme. L'idée finale est de créer un programme du type Visio, mais j'ai de bonnes raisons d'utiliser des contrôles plutôt que du dessin pur.
Par contre, lorsque je le déplace durant l'exécution du programme, je n'ai pas trouvé d'autre manière que de faire un refresh de la form entière, ce qui fait évidemment scintiller le tout. Quelqu'un aurait-il une idée ? Si je trouve la solution, je la mettrai dans la section code, car j'ai vu que bcp de personnes avaient ce problème.

Merci beaucoup,

Greg



Créer une form, ajouter un bouton, et écrire dans l'évènement click du bouton:
dim rect as new TransparentComponent
rect.AddToForm(Me)

Créer un composant avec le nom "TransparentComponent" par exemple et y coller le code suivant:

Public Class TranparentComponent

    Inherits System.Windows.Forms.UserControl

    Private Const WS_EX_TRANSPARENT As Int16 = &H20

    ' This part of the code allows to manage transparency
    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle() = cp.ExStyle() Or WS_EX_TRANSPARENT
            Return cp
        End Get
    End Property

    ' Set the form of the control (a rectangle in this case)
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        ' TODO: add any drawing code, if needed.
        MyBase.OnPaint(e)
        Dim p As New Pen(Color.Black, 5)
        Dim rect As New Rectangle(10, 10, 100, 100)

        e.Graphics.DrawRectangle(p, rect)
    End Sub


#Region "Add Control To Form"
    ' Add control to specified form
    Public Sub AddToForm(ByVal form As Form)
        Dim Control As New TranparentComponent

        Control.Size = New Size(Me.Width, Me.Height)
        form.Controls.Add(Control)
    End Sub
#End Region


#Region "Control Movements"
    ' Manage the movements.

    Private blnMouseDown As Boolean
    Private xControl As Integer
    Private yControl As Integer
    Private xCoord As Integer
    Private yCoord As Integer


    Private Sub Handler_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        Windows.Forms.Cursor.Current = Cursors.SizeAll

        blnMouseDown = True
        xControl = e.X
        yControl = e.Y
    End Sub


    Private Sub Handler_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        Windows.Forms.Cursor.Current = Cursors.SizeAll

        xCoord = e.X
        yCoord = e.Y

        xCoord = Me.Left + e.X
        yCoord = Me.Top + e.Y

        ' If we click on control
        If blnMouseDown Then
            ' We move control to mouse place minus first click position
            Me.Top = yCoord - yControl
            Me.Left = xCoord - xControl

             ' Update the entire form.
            Me.FindForm.Refresh ' SCINTILLEMENT !!! COMMENT FAIRE ?
        End If
    End Sub


    Private Sub Handler_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
        blnMouseDown = False
    End Sub
#End Region

End Class
mercredi 26 décembre 2007 à 21:34:46 | Re : Tranparence d'un contrôle durant son déplacement

yvesyves

Membre Club
Tu peux peut être essayer de rendre les zones graphiques de ton contrôle transparent par un calcul de moyenne entre le pixel du fond et celui du contrôle. En éque cet envoi a marché et que ça t'aidera..
mercredi 26 décembre 2007 à 21:53:14 | Re : Tranparence d'un contrôle durant son déplacement

gregory__forel

Je ne voyais pas ca si compliqué... Je vais attendre de voir si j'ai d'autres réponses, et si c'est vraiment la seule solution, j'essaierai.
D'ailleurs, je me suis mal exprimé, parceque ce n'est pas transparent que je veux, mais complètement invisible sauf pour les parties dessinées (côtés d'un carré par exemple)


Merci !
jeudi 27 décembre 2007 à 01:57:55 | Re : Tranparence d'un contrôle durant son déplacement

Kevin.Ory

Salut,

Un simple "Control.BackColor = Color.Transparent" ne pourrait-il pas remplacer tous ce code que tu nous a mis?

Mais ne compte pas sur des mouvements fluides avec cette méthode, surtout si tu mets une image de fond au conteneur...

Sinon, tu peux redéfinir la région du control avec sa propriété "Region". Les parties exclues de la région ne seront pas du tout dessiné (contrairement à la méthode "backcolor=transparent" qui ne fait que copier le fond du conteneur sur sa surface) et donc les mouvements seront fluides.

Et je te conseil fortement de tout faire avec des BufferedGraphics, sinon tout sera lent et moche. Mais par contre je te déconseil de faire ca avec des controls séparé plutot qu'en "dessin pur", ca va t'apporter plus de problèmes que d'avantages au final
jeudi 27 décembre 2007 à 03:37:04 | Re : Tranparence d'un contrôle durant son déplacement

gregory__forel

Salut,

Je vais essayer avec les régions, c'est peut-être une bonne option, merci !


jeudi 27 décembre 2007 à 08:44:06 | Re : Tranparence d'un contrôle durant son déplacement

divadav

Membre Club
Salut !

Dans ton constructeur, il faut que tu joues avec la fonction SetStyle
Cette fonction te permet en deux secondes de gérer la transparence + un double buffer pour éviter le scintillement...


Divad
Techniques de Web Design, Traductions d'articles sur le Web Design, Astuces .Net
jeudi 27 décembre 2007 à 17:08:15 | Re : Tranparence d'un contrôle durant son déplacement

Kevin.Ory

Réponse acceptée !
"Cette fonction te permet en deux secondes de gérer la transparence + un double buffer pour éviter le scintillement..."

J'ai jamais utilisé la transparence par le SetStyle, mais je pense qu'il s'agit de la même chose que d'appliquer la couleur transparente comme couleur de fond (BackColor = Color.Transparent). Et donc, si tu as des mouvements, c'est absolument pas performant. Cette technique, comme je l'ai déjà dis, n'est pas de la vraie transparence. Il s'agit d'une copie du fond du conteneur (qui contient ton contrôle transparent) sur la surface du contrôle "transparent" en question. Et donc:

- Seul le fond du conteneur est copié sur la surface du contrôl, mais rien d'autre. Donc par exemple si tu as 2 contrôle qui se chevauchent, le contrôle du dessous ne sera pas visible à travers les parties transparentes du contrôle du dessus. Je pense que c'est justement cela que tu voudrais; pouvoir superposer des contrôles tout en voyant ceux de dessous, pas de mettre une image de fond à ton plan de travail. Et donc cette technique ne s'applique absolument pas à ton cas.
- A chaque mouvement du contrôle, il faut redessiner sa surface d'après le fond du conteneur. Ceci prend du temps, et donc lorsque ton contrôle bougeras, tu aura l'impression que l'image de fond suivra les mouvements du contrôle (dans sa région de dessin seulement, c'est a dire dans le carré du contrôle définit par sa position et sa taille). C'est très moche. Et encore une fois, seul le fond du conteneur (une image?) sera appliqué comme fond au contrôle.

Avec la région, tu redéfinit justement la zone de dessin du contrôle, qui ne sera plus définit par sa position et sa taille, mais par sa région (en fait la région correspond au rectangle du contrôle par défaut). Mais:

- Avec les régions, c'est du tout ou rien. Impossible de faire des régions semi-transparente à ton contrôle (tu devra utiliser la méthode précédement expliqué pour le faire, et donc tu héritera de son problème). De plus il ne sera pas question d'appliquer un quelconque lissage à tes formes mais surtout à ton texte, ca ne sera donc pas joli (par défaut, tout est lissé)
- Il peut être difficile de définir la région lorsque ce que tu dois afficher est une forme complexe (un carré ou un cercle = facile, mais si tu commence à afficher des graphiques complexe ou du texte, va faloir faire un algo qui te créé ces régions, au pixel près). (c'est dans ce processus qu'il est impossible de travailer avec des pixels semi-transprent (lissage))
- Hors d'une région, le MouseDown, MouseClick ou MouseMove par exemple, ne seront pas détecté. Impossible donc de sélectionner un rectangle à fond transparent en cliquant dans sa zone transparente.
- Va falloir redéfinir la région en temps réel si ta forme change (par exemple si tu change sa taille ou si tu modifie du texte sur fond transparent), ca peut vite devenir impossible.

Je ne sais pas vraiment ce que tu veux faire. Si tu veux faire un truc vite fait mais qui fonctionne, utlise les régions, mais ne compte pas sur les fonds transparents ou ce genre de chose. Si tu veux un truc qui rivalise avec les prgrammes d'édition graphique (genre visio), tu n'a pas le choix: fais ça en dessin pur. Aucun programme de dessin ou de création graphique existant n'utlise une superposition de contrôle, c'est impossible de faire qqch de potable de cette facon.
Il faut plutôt utilise un système de couche graphique (chaque forme est une couche, ça permet de travailler séparément sur chaque forme) et les superposer au moment du dessin. Il n'y a plus de limitation avec cette technique, aussi bien au niveau modifications qu'au niveau semi-transparence et lissage.
En parallèle aux couches graphique, tu peux faire des couches de régions. Ca te permetra de facilement gérer les événements souris sur ta surface de travail.
Et enfin, en couche supérieur, tu affiche tous les éléments de sélection (genre les petits carrée aux coins d'une forme sélectionnée)

Le problème, c'est qu'il faut tout faire sois-même, par exemple l'édition du texte. (il y a des programmes ou le texte n'est pas modifié directement dans la forme, mais dans un contrôle séparé, ce n'est pas pour rien)

Au niveau des performances, ça va si t'as pas une multitude de forme et surtout pas de grandes images à afficher. Si vraiment ce n'est pas assez performant, va falloir créer un système de couche graphique avec des CachedBitmap (des bitmaps en mémoire bcp plus rapides que les images normales de .NET), malheureusement celle-ci ne sont pas implémenté avant le framework 3.5, il faudra donc sois même accéder à GDI+ (la DLL qui permet de dessiner dans windows, tout ce qui est graphique dans .NET y fait référence) si tu utilise une version antérieur du framework .NET.

Ben voilà ce que j'avais à dire :) si t'as d'autre questions, n'hésite pas. Mais c'est clair que tout ceci n'est pas tout facile, y'a du boulot.



J'ajoute juste encore une remarque au sujet du commentaire de divadav:
Si tu fait du dessin double-bufferé de cette facon, ca reste quand même du dessin direct, c'est a dire que tu dois redessiner à chaque événement paint du contrôle. Avec un DoubleBuffer, tu redessine seulement lorsque qqch change, le reste du temps suffit de faire un render (super-rapide). Les 2 techniques ne sont donc pas vraiment comparables.



Bonne soirée,
Kevin
jeudi 27 décembre 2007 à 19:24:41 | Re : Tranparence d'un contrôle durant son déplacement

gregory__forel

Ca c'est de la réponse Kevin !!! J'ai suivi ton premier conseil et utilisé les régions, ca marche, et évidemment, ce n'est pas absolument propre, lisse, etc. mais c'est un bon début.

En revanche, ton analyse est exacte, donc je vais prendre plus de temps et essayer de développer les classes nécessaires pour faire du "tout dessiné". Probablement une gestion de layouts, de regions, etc. Je n'ai d'ailleurs pas trouvé de classes gratuites ou open source pour faire tout ca, à moins d'extraire des parties de code de Paint.NET. Si quelqu'un en connaît une toute prête, je m'économiserais bien ces dizaines (centaines ?) d'heures de travail.

Encore merci pour ton analyse plus que complète !

Greg
jeudi 27 décembre 2007 à 19:26:26 | Re : Tranparence d'un contrôle durant son déplacement

gregory__forel

Je précise par ailleurs que SetStyle "doubble buffer" et "transparent" ne sont pas compatibles, cela affiche un gros carré noir en lieu et place du contrôle.
vendredi 28 décembre 2007 à 07:47:01 | Re : Tranparence d'un contrôle durant son déplacement

divadav

Membre Club
Si si, c'est compatible... Il faut faire :

        Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or _
                    ControlStyles.UserPaint Or _
                    ControlStyles.SupportsTransparentBackColor Or _
                    ControlStyles.OptimizedDoubleBuffer, True)
        Me.DoubleBuffered = True

Puis redéfinir la méthode OnPaint de ton contrôle... Mais c'est vrai que ce n'est pas la technique la plus optimisée ! C'est bien pour redéfinir un petit contrôle, un bouton ou quelque chose du style... Pas pour ce que tu veux faire !


Divad
Techniques de Web Design, Traductions d'articles sur le Web Design, Astuces .Net

1 2

Cette discussion est classée dans : form, end, windows, private, control


Répondre à ce message

Sujets en rapport avec ce message

load et unload en VB6 [ par SLAINE ] Bonjour,je cherche a enregistrer une form contenant des cases à cocher de sorte que lorsque j'exécute l'exe je retrouve les cases cochées à la fermetu Pourquoi mon ecran de veille marche pas [ par luke44 ] Il y aurait-il qqn qui aurait la gentillesse de me dire pourquoi ma form de screensaver reste noire quand elle part! Merci. (Note, la procedure termin Form_LostFocus qui ne marche pas [ par titom59 ] Salut à tousje developpe un petit prog avec les skins (source_19448) et j'essaye de cacher ma fenetre principale lorsque je clique en dehors.je voudra gestion ouverture et fermeture de form [ par geii82 ] bonjour à tous, j'espère que vou spourrez m'aider, alors voilà je suis débutant en vb.net et  j'ai un cthi bout de code qui ne marche pas et j'aimerai [déplacé VB.NET -> VBA] Désactiver évènement "wheel" de la souris sur formulare Access 2003 [ par willytito ] Bonjour à toutes et à tous, J'ai trouvé ce code sur le FAQ de developpez.com. Option Compare Database Option Explicit Private WithEvents clsMouseWhe naviguer dans un recordset [ par wahide8 ] Bonjour, je suis débutant en programmation, je suis entrains de concevoir une application VB ACCESS monoposte. J’ai pris ici un exemple simple pour détecter la touche ENTER sur un usercontrol INPUTBOX [ par Adn56 ] Bonsoir à tous, Voici mon soucis : J'ai récupéré et modifié la source de Marco Bellinaso, mais voila pas possible d'activer le dialog.result.ok si l'u Mauvaise récéption d'info. [ par Makia42 ] Bonjour, Voilà je travaille actuellement sur le dévellopement d'une interface Graphique simple qui ouvre une socket client et se connecte au serveur mise à l'échelle automatique dans les windows form [ par sl300 ] Bonjour. Débutant, je suis moi aussi confronté au problème de la mise à l'échelle automatique des applications selon les innombrables résolutions écra hook (global) sur le clavier - empêcher le traitement ultérieur (local) de la touche [ par Nicolas_75 ] Bonjour, J'apprécierais de l'aide sur le problème suivant. Mon but final est que l'appui sur la touche F12 entraîne l'impression de la date (par Sen


Nos sponsors


Sondage...

CalendriCode

Mars 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,264 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales