Le mystère des PictureBox
Un PictureBox contient 2 images accessibles par ses 2 propriétés : .Picture et .Image. Mais ces 2 propriétés sont en fait très différentes. Voici l'explication de ces 2 propriétés :
Propriété ".Picture" (image d'origine) |
MyPictureBox.Picture
est un objet StdPicture
(IPictureDisp) défini par la
bibliothèque StdOle2.tlb ("OLE Automation" doit
apparaître dans la liste des références : menu Projet --> Références).
Voir les propriétés de StdPicture dans l'explorateur
d'objet de VB. Cet objet possède les propriétés suivantes :
Handle (par
défaut), height, Width, hPal, et Type
et une méthode : Render (hdc As Long, x As Long, y As Long, cx As
Long, cy As Long, xSrc As OLE_XPOS_HIMETRIC, ySrc As
OLE_YPOS_HIMETRIC, cxSrc As OLE_XSIZE_HIMETRIC, cySrc As
OLE_YSIZE_HIMETRIC, prcWBounds As Any)
Cette image est
l'image originale qui a été chargée dans la propriété .Picture du PictureBox.
Ce
n'est pas l'image affichée dans le Device Context du PictureBox.
Son type est obligatoirement un des 3 suivants :
BITMAP
WINDOWS METAFILE
(ext.: wmf)
ENHANCED METAFILE
(ext.: emf)
Cette image d'origine
n'est pas altérée par le dimensionnement du PictureBox, ni par
les procédures GDI (Graphic Device Interface) qu'on lui
applique. Cette image est stockée en mémoire, et son Handle
permet de la manipuler. Son Handle est :
MyPictureBox.Picture.Handle.
On peut connaître le type de cette image avec l'API : GetObjectType qui s'utilise ainsi :
Private Declare Function GetObjectType Lib "gdi32" (ByVal hgdiobj As Long) As Long
Private Const OBJ_BITMAP = 7
Private Const OBJ_METAFILE = 9
Private Const OBJ_ENHMETAFILE = 13
Select Case GetObjectType(MyPictureBox.Picture.Handle)
Case OBJ_BITMAP ' (C'est un BITMAP)
Case OBJ_METAFILE ' (Métafile)
Case OBJ_ENHMETAFILE ' (Enhanced Metafile)
End Select
Comme .Handle est la
propriété par défaut de l'objet MyPictureBox.Picture, on peut
récupérer le Handle ainsi :
Dim MyPictureHandle As Long
MyPictureHandle = myPictureBox.Picture (ou : MyPictureHandle =
myPictureBox.Picture.Handle)
Par exemple :
Dim Hwnd As Long
Hwnd = MyPictureBox.Picture '(ne
renvoie pas d'erreur)
MyPictureBox.Picture = Hwnd '(renvoie
une erreur)
Propriété ".Image" (image apparente ou dessinée) |
MyPictureBox.Image est aussi un objet StdPicture (IPictureDisp) défini par la bibliothèque StdOle2.tlb. Son Handle est celui de l'image affichée dans le Device Context du PictureBox. Cette image est toujours une image BITMAP, même si l'image d'origine définie par la propriété .Picture n'est pas une image BITMAP. Les dimensions en pixels de cette image dépendent des dimensions et du clipping du PictureBox, et sont donc modifiées en cas de redimensionnement du contrôle
De plus, les procédures GDI qu'on applique (quand on dessine des formes ou qu'on écrit du texte dans le DC du PictureBox) modifient l'affichage et donc l'image BITMAP définie par ce Handle (la propriété .AutoRedraw du PictureBox doit être mise à VRAI).
Le fait de récupérer cette image peut être intéressant si on a dessiné ou écrit dedans et qu'on désire imprimer ou enregistrer le résultat, mais il faut prendre garde de bien dimensionner le PictureBox en fonction de la résolution qu'on désire obtenir. Un PictureBox trop petit donnera une image de médiocre qualité.
Rappelons
que, si la propriété .ScaleMode du conteneur est
"Twip", les dimensions intérieures (données
par les propriétés .ScaleHeight et .ScaleWidth) du
PictureBox sont égales à 15 fois le nombre de pixels en standard (Screen.TwipsPerPixelY
et Screen.TwipsPerPixelX) Exemple : un PictureBox tel que .ScaleWidth = 3000 et .ScaleHeight = 6000 donnera une image de 400 x 200 pixels. |
Les fonction LoadPicture et SavePicture |
Function LoadPicture([filename]) As IPictureDisp
Le résultat de cette fonction est un objet StdPicture (IPictureDisp),
membre de VB.Global
(Remarque : Il existe un autre LoadPicture, membre de stdole.StdFunctions et
qui autorise 4 arguments)
Sub SavePicture(Picture As
IPictureDisp, filename As String)
On peut par
exemple les utiliser ainsi :
Chargement
d'une image dans le PictureBox :
Dim IPic As
StdPicture,
PicHandle As Long
Set IPic =
LoadPicture(App.Path & "\Imagetest.bmp")
PicHandle = IPic.Handle
Set MyPictureBox.Picture =
IPic
Récupération
de l'image chargée dans le PictureBox (ne dépend pas de la taille du
PictureBox) :
Dim IPic As
StdPicture
Set IPic = MyPictureBox.Picture
SavePicture P,
"C:\plop.bmp"
Récupération de l'image dessinée dans le PictureBox (dépend de la taille du
PictureBox) :
Dim IPic As
StdPicture
Set IPic = MyPictureBox.Image
SavePicture P, "C:\plop.bmp"