IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

[VB.NET] Form avec des Nuances de Transparence !!


Sujet :

Windows Forms

  1. #1
    Nouveau membre du Club
    Inscrit en
    Décembre 2005
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 61
    Points : 28
    Points
    28
    Par défaut [VB.NET] Form avec des Nuances de Transparence !!
    Bonjour,

    Je félicite tout d'abord les auteurs de ce sujet sur le forum "Delphi" de Developpez.com:
    http://www.developpez.net/forums/vie....php?p=1398111

    Car il traite d'un sujet qui n'est que trop peu abordé sur la toile.
    J'essaye depuis plusieurs semaines de créer une Form avec des dégradés de transparence. Comme il est possible de le voir sur les widgets de yahoo ou d'opéra.

    Je sais maintenant qu'il s'agit de paramétrisation pointu du "Layered Windows" grâcé particulierement à l'API "UpdateLayeredWindow" permettant d'appliquer une transparence pixel par pixel sur une Form.

    Voici aussi le seul autre sujet qui traite réellement du sujet, avec même des sources en C#, et une démonstration exeptionnelle de ce qu'il est possible d'obtenir:
    http://www.thecodeproject.com/cs/med...lpha_sharp.asp

    Alors j'essaye de faire pareil en VB.NET, mais evidement, je n'y arrive pas! Je pense qu'il y a une tonne d'erreur! Voici mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    		Private Structure BLENDFUNCTION
    		  Dim BlendOp As Byte
    		  Dim BlendFlags As Byte
    		  Dim SourceConstantAlpha As Byte
    		  Dim AlphaFormat As Byte
    		End Structure
     
    		Const GWL_EXSTYLE = (-20)
    		Const WS_EX_LAYERED = &H80000
     
    		Private Declare Function UpdateLayeredWindow Lib "user32.dll" Alias "GetClassLongA" (ByVal hWnd As IntPtr,hdcDst As IntPtr, pptDst As Point,psize As Size, hdcSrc As IntPtr,pptSrc As Point, crKey As Integer,pblend As BLENDFUNCTION, dwFlags As Integer) As Boolean
    		Private Declare Auto Function SetWindowLong Lib "User32.Dll" (ByVal hWnd As IntPtr,ByVal nIndex As Integer,ByVal dwNewLong As Integer) As Integer
     
     
    	'Le code suivant est un traduction du code delphi posté sur le forum de developpez.com
    	'J'ai postionné ce code dans le chargement de ma form
    		Dim bitmaptest As Bitmap = Image.FromFile("c:\test77.png")
     
    		SetWindowLong(Me.Handle, GWL_EXSTYLE,WS_EX_LAYERED)
     
    		Dim screenDc As IntPtr = nothing
    		Dim memDc As IntPtr = nothing
    		Dim hBitmap As IntPtr = IntPtr.Zero
    		Dim oldBitmap As IntPtr = IntPtr.Zero 
     
     
    		hBitmap = bitmaptest.GetHbitmap(Color.FromArgb(0)) 'grab a GDI handle from this GDI+ bitmap 
     
    		Dim size As Size = new Size(bitmaptest.Width, bitmaptest.Height)
    		Dim PointSource As Point = new Point(0, 0) 
    		Dim topPos As Point = new Point(Left, Top) 
    		Dim blend As BLENDFUNCTION = new BLENDFUNCTION()
    		blend.BlendOp             = 0 
    		blend.BlendFlags          = 0
    		blend.SourceConstantAlpha = 255
    		blend.AlphaFormat         = 1
     
    		Dim bResultat As Boolean = UpdateLayeredWindow(Me.Handle, screenDc, topPos, size, memDc, pointSource, 0, blend, 1)
     
    		MessageBox.show(bResultat)
    J'ai essayé de traduire le code delphi du lien que je vous ai mis en début de ce post.
    A la fin, j'ai un "False" qui s'affiche, donc la fonction "UpdateLayeredWindow" a échoué!

    Voilà, en espérant avoir un peu d'aide

    PS: d'un point de vue didactique, ça serait tres interessant d'arriver à faire fonctionner ce code, car il n'existe aucun exemple sur internet de cette API utilisé en VB.NET et c'est pas des blagues

  2. #2
    Nouveau membre du Club
    Inscrit en
    Décembre 2005
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 61
    Points : 28
    Points
    28
    Par défaut
    Bon ben les mecs, j'y suis arrivé! Je pense que c'est le seul code VB.NET disponible sur le sujet sur la toile!

    Mes déclarations qui me seront utiles dans le code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Public Structure BLENDFUNCTION
    	        Public BlendOp As Byte
    	        Public BlendFlags As Byte
    	        Public SourceConstantAlpha As Byte
    	        Public AlphaFormat As Byte
    	    End Structure
     
    	    Public Const ULW_COLORKEY As Integer = 1
    	    Public Const ULW_ALPHA As Integer = 2
    	    Public Const ULW_OPAQUE As Integer = 4
    	    Public Const AC_SRC_OVER As Byte = 0
    	    Public Const AC_SRC_ALPHA As Byte = 1
    	    Public Const GWL_EXSTYLE = (-20)
     
    	    Public Declare Function UpdateLayeredWindow Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal hdcDst As IntPtr, ByRef pptDst As Point, ByRef psize As Size, ByVal hdcSrc As IntPtr, ByRef pprSrc As Point, ByVal crKey As Integer, ByRef pblend As BLENDFUNCTION, ByVal dwFlags As Integer) As Boolean
    		Private Declare Auto Function SetWindowLong Lib "User32.Dll" (ByVal hWnd As IntPtr,ByVal nIndex As Integer,ByVal dwNewLong As Integer) As Integer	
    		Private Declare Auto Function GetWindowLong Lib "User32.Dll" (ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Integer
    	    Public Declare Function GetDC Lib "user32.dll" (ByVal hWnd As IntPtr) As IntPtr
    	   	Public Declare Function ReleaseDC Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Integer	
    	    Public Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hDC As IntPtr) As IntPtr
    	    Public Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As IntPtr) As Boolean
    	    Public Declare Function SelectObject Lib "gdi32.dll" (ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr
    	    Public Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As IntPtr) As Boolean
    La méthode permettant à partir d'une image PNG et ses dégradés de transparence d'appliquer cette transparence à la Form:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    Public Sub SetBitmap(ByVal PNG As Bitmap, ByVal opacity As Byte)
     
    			'L'image doit absolument être au format 32bpp
    	        If Not (PNG.PixelFormat = PixelFormat.Format32bppArgb) Then
    	            Throw New ApplicationException("The bitmap must be 32ppp with alpha-channel.")
    	        End If
     
    	        'Toute la procédure que je ne comprend pas completement :(
    	        Dim screenDc As IntPtr = GetDC(IntPtr.Zero)
    	        Dim memDc As IntPtr = CreateCompatibleDC(screenDc)
    	        Dim hBitmap As IntPtr = IntPtr.Zero
    	        Dim oldBitmap As IntPtr = IntPtr.Zero
    	        Try
    	            hBitmap = PNG.GetHbitmap(Color.FromArgb(0))
    	            oldBitmap = SelectObject(memDc, hBitmap)
    	            Dim size As Size = New Size(PNG.Width, PNG.Height)
    	            Dim pointSource As Point = New Point(0, 0)
    	            Dim topPos As Point = New Point(Left, Top)
    	            Dim blend As BLENDFUNCTION = New BLENDFUNCTION
    	            blend.BlendOp = AC_SRC_OVER
    	            blend.BlendFlags = 0
    	            'Alpha constant appliqué à toute la fênetre
    	            blend.SourceConstantAlpha = opacity
    	            blend.AlphaFormat = AC_SRC_ALPHA
    	            UpdateLayeredWindow(Handle, screenDc, topPos, size, memDc, pointSource, 0, blend, ULW_ALPHA)
    	        Finally
    	            ReleaseDC(IntPtr.Zero, screenDc)
    	            If Not (hBitmap.Equals(IntPtr.Zero)) Then
    	                SelectObject(memDc, oldBitmap)
    	                DeleteObject(hBitmap)
    	            End If
    	            DeleteDC(memDc)
    	        End Try
    	    End Sub
    Code que j'ai mis dans l'evenement de charge de ma Form:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Dim Param As Long
    	    	Param = GetWindowLong(Me.Handle, GWL_EXSTYLE)
    	    	Call SetWindowLong(Me.Handle, GWL_EXSTYLE, Param  Or (524288))
    			Call SetBitmap(Me.BackgroundImage,255)
    Voilà, le résultat est franchement sympathique! Vous pouvez ajouter du code pour bouger votre fênetre avec la souris ça n'est pas un pb

    Je pense que les widgets sont affichés comme celà!

    Nouveau pb: Apres ce traitement, tous les contrôles de la Form disparaissent completement, sauriez vous me dire comment faire pour pouvoir conserver mes controles sur la Form? Surtout vue que les widget ont bien des composants en mouvement à l'interieur

  3. #3
    Nouveau membre du Club
    Inscrit en
    Décembre 2005
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 61
    Points : 28
    Points
    28
    Par défaut
    Alors apres de nombreuses études, une Form avec un alpha-blending de transparence, comme cité au-dessus, a juste un problème de painting sur les contrôles.
    C'est à dire que les contrôles sont bien présents sur la Form, mais il n'est pas possible de les voir! Car la Form est transformé, d'apres ce que j'ai pû comprendre sur des forums US, en quelques choses de "dessin" qui ne peut pas affiché des controles. MAis il réagissent bien aux clicks!

    Alors l'astuce est de redessiner, reappliquer l'alpha-blending sur la Form, apres chaque changement d'état d'un côntrole.
    En fait, il faut dessiné sur sa PNG le contrôle.

    L'avantage de cette méthode, et que on peut personnalisé à 100% tous les composants sur la Form!
    Le désavantage c est que c'est plus long, et moins pratique, tout doit être dessiné!

    Voilà, l'affaire est dans le sac

    PS: je vous conseille de regarder la source Csharp cité dans le premeir post aussi, et ce lien ci décrivant clairement les possibilités de transparences dans windowXP: http://msdn.microsoft.com/library/de...l/layerwin.asp
    Cette méthode est celle utilisé poru afficher des widgets sur WindowXP: http://www.developpez.net/forums/vie...063&highlight=

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment modifier la position d'une Form avec des RadioButton ?
    Par bionicleman dans le forum Composants VCL
    Réponses: 1
    Dernier message: 18/12/2007, 18h19
  2. Problème de form avec des frames
    Par coco38 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 12
    Dernier message: 04/06/2007, 15h11
  3. [vb.net]Problème avec des fichiers DLL
    Par nakata77 dans le forum VB.NET
    Réponses: 1
    Dernier message: 20/09/2006, 19h40
  4. [VB.NET] Requete avec des dates dans un DataSet
    Par leSeb dans le forum Windows Forms
    Réponses: 2
    Dernier message: 02/10/2005, 15h30
  5. [VB.NET] Form avec comportement msgbox
    Par Berns dans le forum Windows Forms
    Réponses: 2
    Dernier message: 14/06/2004, 12h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo