DESSINER UN METAFILE
C'est un sujet qui m'a donné du
fil à retordre. En effet, il existe des images de type METAFILE
et d'autres de type ENHANCED METAFILE. Ces 2 types ne sont pas
vraiment compatibles, et Microsoft SDK décommande l'utilisation
des API spécifiques des METAFILES.
Ils recommandent de convertir d'abord le METAFILE en ENHANCED
METAFILE, puis d'effectuer les traitements avec les API des
enhanced metafiles.
La difficulté réside dans la
position et la taille de l'image dessinée. Comme le mode
METAFILE ne précise pas vraiment de dimension d'image, la taille
de l'image dessinée ou imprimée est imprévisible.
De plus, les 2 OS W95-98 et WNT ne se comportent pas du tout de
la même façon, et certains codes fonctionnent bien sous l'un et
mal sous l'autre.
Néanmoins, je propose une méthode qui semble fonctionner dans tous les cas.
On suppose qu'on dispose déjà du
Handle (descripteur) d'une image en mode metafile. Ce handle peut
par exemple, être la propriété .Picture (en fait,
.Picture.Handle par défaut) d'un PictureBox si elle contient un
WMF.
Exemple :
PicHandle = MyPictureBox.Picture
Ce Handle peut aussi être obtenu
directement à partir d'un fichier image. Par exemple :
PicHandle =
LoadPicture("ImageTest.wmf").Handle
Attention :
dans ce cas, le Handle doit être détruit après usage au moyen
de l'API DeleteObject
Dans l'exemple suivant, on demande ensuite de dessiner l'image résultante sur un périphérique d'affichage (Device Context) dont le Handle est HDCdest
Déclarations : |
Private Const
NULLPTR = 0&
Private Const MM_ANISOTROPIC = 8
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare
Function GetDC Lib "user32" (ByVal hwnd As Long) As
Long
Private Declare Function ReleaseDC Lib "user32" (ByVal
hwnd As Long, ByVal hdc As Long) As Long
' GESTION DE LA
MEMOIRE
Private Declare Function GlobalAlloc Lib "kernel32"
(ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalLock Lib "kernel32"
(ByVal hmem As Long) As Long
Private Declare Function GlobalFree Lib "kernel32"
(ByVal hmem As Long) As Long
' METAFILES
Private Type METAFILEPICT
mm As Long
xExt As Long
yExt As Long
hMF As Long
End Type
Private Declare Function DeleteEnhMetaFile Lib "gdi32"
(ByVal hemf As Long) As Long
Private Declare Function PlayEnhMetaFile Lib "gdi32"
(ByVal hdc As Long, ByVal hemf As Long, lpRect As RECT) As Long
Private Declare Function GetMetaFileBitsEx Lib "gdi32"
(ByVal hMF As Long, ByVal nSize As Long, lpvData As Long) As Long
Private Declare Function SetWinMetaFileBits Lib "gdi32"
(ByVal cbBuffer As Long, lpbBuffer As Long, ByVal hdcRef As Long,
lpmfp As METAFILEPICT) As Long
Dim hmem As Long, hMemPtr As Long, rc As Long
Dim RecDest As RECT
Dim hEnhMetaFile As Long
Dim nSize As Long
Dim HDesk As Long
Dim EMF As METAFILEPICT
Code : |
' On suppose que
PicHandle est le handle d'un metafile
' On va
transformer le Metafile en Enhanced-Metafile
' On obtient la longueur du buffer nécessaire
nSize = GetMetaFileBitsEx(PicHandle, 0&, ByVal 0&)
' On réserve
un espace mémoire pour y stocker l'image en mode METAFILE
hmem = GlobalAlloc(&H40, nSize)
hMemPtr = hmem
rc = GetMetaFileBitsEx(PicHandle, nSize, ByVal hMemPtr)
EMF.mm = MM_ANISOTROPIC
EMF.xExt = 0
EMF.yExt = 0
' On récupère le
handle du enhanced metafile
hEnhMetaFile = SetWinMetaFileBits(nSize, ByVal hMemPtr, HDCdest,
EMF)
' On libère
la mémoire
rc = GlobalFree(hmem)
RecDest.Left = Xdest
RecDest.Top = Ydest
RecDest.Right = Xdest +
Widthdest
RecDest.Bottom = Ydest +
Heightdest
' On dessine
l'image sur le périphérique de destination
rc = PlayEnhMetaFile(HDCdest, hEnhMetaFile, RecDest)
' On nettoie
DeleteEnhMetaFile hEnhMetaFile