Forms avec transparence par pixel, problèmes avec GDI
stefsouron
Messages postés8Date d'inscriptionsamedi 20 octobre 2007StatutMembreDernière intervention29 octobre 2007
-
24 oct. 2007 à 11:38
stefsouron
Messages postés8Date d'inscriptionsamedi 20 octobre 2007StatutMembreDernière intervention29 octobre 2007
-
24 oct. 2007 à 19:43
Bonjour,
J'ai besoin d'aide pour résoudre un problème d'utilsation des API GDI sous VB 2005. Je sais que mon post est très long, et j'en suis désolé, mais pour obtenir une aide précise, je suis obligé de décrire tout le cheminement effectué...
Mais j'avais aussi besoin de pouvoir modifier la taille d'affichage de la form en question (dans le code proposé, la form ne s'affiche que dans la taille native du fichier PNG choisi).
J'ai commencé par modifier la classe pngForm pour qu'elle soit un peu plus pratique à utiliser :
J'ai ajouté ces variables privées :
ImageContainer As System.Drawing.Image pour y stocker l'image originale
ImageWidth As Integer pour y stocker la largeur d'affichage
ImageHeight As Integer pour y stocker la hauteur d'affichage
ImageOpacity As Byte pour la valeur alpha générale de la form
Puis j'ai implémenté des propriétés publiques permettant de lire et modifier ces valeurs. A la fin de chaque Set de ces propriétés, je fais appel à une fonction UpdateForm() qui actualise la form à l'écran.
UpdateForm() est une modification de la fonction SetImage(Bitmap, Opacity) écrite dans son code par PymCorp. J'y ai d'abord retiré les paramètres puisque j'utilise les conteneurs créés ci-dessus. Cette fonction, à la base, créait un Device Context GDI en mémoire, y sélectionnait le bitmap et se s'en servait pour appeller la fonction UpdateLayeredWindow (une fonction de user32.dll).
J'ai d'abord essayé de redimensionner directement le bitmap contenu dans ImageContainer, mais les propriétés Width et Height dans la classe System.Drawing.Image sont Read Only.
J'ai alors essayé de jouer sur le paramètre size de UpdateLayeredWindow, mais en fait, cela ne modifie que la taille d'affichage de la layered window : si on la réduit, l'image est rognée.
J'ai donc fini par utiliser les fonctions de l'api GDI32.DLL : Je crée un bitmap supplémentaire, de la taille voulue pour l'affichage final, avec un Device Context associé. J'y recopie la version redimensionnée de l'image avec StretchBlt, et je me sers de ce DC lors de l'appel à UpdateLayeredWindow.
Sauf que ça ne marche pas...
Voici le code de ma procédure (les fonctions API sont définies dans un module, il n'y a pas d'exception PInvoke à l'éxécution):
Public
Sub UpdateForm()
' Gets the screen's Device Context Handle :
Dim hScreenDC
As IntPtr = GetDC(IntPtr.Zero)
' Creates a GDI Bitmap from ImageContainer, with a transparent background :
Dim hOriginalBMP
As IntPtr =
CType(ImageContainer, Bitmap).GetHbitmap(Color.FromArgb(0, 0, 0, 0))
' Creates a screen compatible memory Device Context :
Dim hOriginalDC
As IntPtr = CreateCompatibleDC(hScreenDC)
' Associates this Device Context with the bitmap :
SelectObject(hOriginalDC, hOriginalBMP)
' Creates the bitmap that will receive the resized image, with the final dimensions :
A l'affichage, il n'y a rien. En fait, il semblerait que le Device Context final (pointé par hResizedDC) soit vide. Si je remplace, dans l'appel à UpdateLayeredWindow, hResizedDC par hOriginalDC, alors cela fonctionne.
Je pense que le problème se situe au niveau de l'opération StretchBlt. J'ai consulté toute la documentation MSDN Library sur l'utilisation de GDI, et n'ai trouvé aucune piste. J'en appelle donc à la communauté, pour voir si quelqu'un entrevoit une solution...
Merci pour la patience de ceux qui ont lu jusque là...
@ + (j'espère, et je continue à chercher...)
A voir également:
Forms avec transparence par pixel, problèmes avec GDI