понедельник, 5 октября 2009 г.

EMF

Attribute VB_Name = "modOLEPicture"
Option Explicit

' OLE Picture helper library 1.1
' Written by Mike D Sutton of EDais
'
' E-Mail: EDais@mvps.org
' WWW: Http://www.mvps.org/EDais/
'
' Written: 01/05/2004
' Last edited: 07/04/2006

'Version history:
'----------------

' Version 1.1 (07/04/2006):
' PtrToPicture() - Creates an IPicture from a data pointer
' IPictureGUID() - Returns the GUID for an IPicture interface

' Version 1.02 (11/09/2004):
' Added destroy-on-fail option to GDIToPicture() to automatically clean up input object
' if the routine fails - This is set to false by default for backwards compatibility

' Version 1.01 (11/07/2004):
' HimetricToPixelsX() - Converts hi-metric to pixels in the X-axis
' HimetricToPixelsY() - Converts hi-metric to pixels in the Y-axis
' PixelsToHimetricX() - Converts pixels to hi-metric in the X-axis
' PixelsToHimetricY() - Converts pixels to hi-metric in the Y-axis
' ConvertPixelHimetric() - [Private] Converts between hi-metric and pixel scale modes
'
' Version 1.0 (01/05/2004):
' GDIToPicture() - Takes an HBITMAP, HCURSOR, HICON, HMETAFILE or HENHMETAFILE
' and wraps it in a StdPicture object for use in VB.
' WMFToEMF() - Converts a Windows format metafile to an enhanced metafile
'------------

Private Declare Function OleCreatePictureIndirect Lib "OLEPro32.dll" (ByRef PicDesc As Any, ByRef RefIID As GUID, ByVal fPictureOwnsHandle As Long, ByRef IPic As IPicture) As Long
Private Declare Function GetObjectType Lib "GDI32.dll" (ByVal hGDIObj As Long) As Long
Private Declare Function GetIconInfo Lib "User32.dll" (ByVal hIcon As Long, ByRef piconinfo As ICONINFO) As Long
Private Declare Function DeleteObject Lib "GDI32.dll" (ByVal hObject As Long) As Long
Private Declare Function GetMetaFileBitsEx Lib "GDI32.dll" (ByVal hMF As Long, ByVal nSize As Long, ByRef lpvData As Any) As Long
Private Declare Function SetWinMetaFileBits Lib "GDI32.dll" (ByVal cbBuffer As Long, ByRef lpbBuffer As Byte, ByVal hDCRef As Long, lpMFP As MetaFilePict) As Long
Private Declare Function GetEnhMetaFileHeader Lib "GDI32.dll" (ByVal hEMF As Long, ByVal cbBuffer As Long, ByRef lpEMH As EnhMetaHeader) As Long
Private Declare Function DeleteEnhMetaFile Lib "GDI32.dll" (ByVal hEMF As Long) As Long
Private Declare Function DeleteMetaFile Lib "GDI32.dll" (ByVal hMF As Long) As Long
Private Declare Function DestroyIcon Lib "User32.dll" (ByVal hIcon As Long) As Long

Private Declare Function CreateEnhMetaFile Lib "GDI32.dll" Alias "CreateEnhMetaFileA" (ByVal hDCRef As Long, ByVal lpFileName As String, ByRef lpRect As Any, ByVal lpDescription As String) As Long
Private Declare Function CloseEnhMetaFile Lib "GDI32.dll" (ByVal hDC As Long) As Long
Private Declare Function PlayMetaFile Lib "GDI32.dll" (ByVal hDC As Long, ByVal hMF As Long) As Long
Private Declare Function GetDeviceCaps Lib "GDI32.dll" (ByVal hDC As Long, ByVal nIndex As Long) As Long
Private Declare Function CreateIC Lib "GDI32.dll" Alias "CreateICA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, ByRef lpInitData As Any) As Long
Private Declare Function DeleteDC Lib "GDI32.dll" (ByVal hDC As Long) As Long
Private Declare Function MulDiv Lib "Kernel32.dll" (ByVal nNumber As Long, ByVal nNumerator As Long, ByVal nDenominator As Long) As Long

Private Declare Function CreateStreamOnHGlobal Lib "OLE32.dll" (ByVal hGlobal As Long, ByVal fDeleteOnRelease As Long, ByRef ppStm As Any) As Long
Private Declare Function OleLoadPicture Lib "OLEPro32.dll" (ByRef pStream As Any, ByVal lSize As Long, ByVal fRunMode As Long, ByRef riid As GUID, ByRef ppvObj As Any) As Long
Private Declare Function GlobalAlloc Lib "Kernel32.dll" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "Kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Function GlobalLock Lib "Kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "Kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Sub RtlMoveMemory Lib "Kernel32.dll" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)

Private Const LOGPIXELSX As Long = 88 ' Logical pixels/inch in X
Private Const LOGPIXELSY As Long = 90 ' Logical pixels/inch in Y

Private Type PictDescGeneirc
pdgSize As Long
pdcPicType As Long
pdcHandle As Long
pdcExtraA As Long ' xExt for metafile, hPal for Bitmap
pdcExtraB As Long ' yExt for metafile
End Type

Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type

Private Type ICONINFO
fIcon As Long
xHotspot As Long
yHotspot As Long
hbmMask As Long
hbmColor As Long
End Type

Private Type MetaFilePict
mm As Long
xExt As Long
yExt As Long
hMF As Long
End Type

Private Type RectL
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Private Type SizeL
cx As Long
cy As Long
End Type

Private Type EnhMetaHeader
iType As Long
nSize As Long
rclBounds As RectL
rclFrame As RectL
dSignature As Long
nVersion As Long
nBytes As Long
nRecords As Long
nHandles As Integer
sReserved As Integer
nDescription As Long
offDescription As Long
nPalEntries As Long
szlDevice As SizeL
szlMillimeters As SizeL
End Type

Private Const OBJ_BITMAP As Long = &H7
Private Const OBJ_METAFILE As Long = &H9
Private Const OBJ_ENHMETAFILE As Long = &HD

Private Const PICTYPE_BITMAP As Long = &H1
Private Const PICTYPE_METAFILE As Long = &H2
Private Const PICTYPE_ICON As Long = &H3
Private Const PICTYPE_ENHMETAFILE As Long = &H4
Private Const GMEM_MOVEABLE As Long = &H2

Private Const S_OK As Long = &H0

Public Function GDIToPicture(ByVal inGDIObj As Long, _
Optional ByVal inOwnObj As Boolean = True, _
Optional ByVal inPal As Long = &H0, _
Optional ByVal inDestroyOnFail As Boolean = False) As IPicture
Dim IconInf As ICONINFO
Dim PicDesc As PictDescGeneirc
Dim RetPic As IPicture
Dim TempEMF As Long
Dim MetaHead As EnhMetaHeader
Dim ObjType As Long

ObjType = GetObjectType(inGDIObj)
Select Case ObjType
Case OBJ_BITMAP
PicDesc.pdgSize = 16
PicDesc.pdcPicType = PICTYPE_BITMAP
PicDesc.pdcExtraA = inPal
Case OBJ_METAFILE ' UNTESTED!
PicDesc.pdgSize = 20
PicDesc.pdcPicType = PICTYPE_METAFILE

' WMF objects don't store bounds information so perform
' temporary conversion to EMF and read header structure
TempEMF = WMFToEMF(inGDIObj)
If (TempEMF) Then
Call GetEnhMetaFileHeader(TempEMF, Len(MetaHead), MetaHead)
PicDesc.pdcExtraA = MetaHead.rclBounds.Right
PicDesc.pdcExtraB = MetaHead.rclBounds.Bottom
Call DeleteEnhMetaFile(TempEMF)
End If
Case OBJ_ENHMETAFILE
PicDesc.pdgSize = 12
PicDesc.pdcPicType = PICTYPE_ENHMETAFILE
Case Else ' Test for icon/cursor
If (GetIconInfo(inGDIObj, IconInf)) Then
PicDesc.pdgSize = 12
PicDesc.pdcPicType = PICTYPE_ICON

' Clean up Bitmap copies
Call DeleteObject(IconInf.hbmColor)
Call DeleteObject(IconInf.hbmMask)
End If
End Select

' Couldn't match this object against known types
If (PicDesc.pdgSize = 0) Then Exit Function

' Set object handle
PicDesc.pdcHandle = inGDIObj

If (OleCreatePictureIndirect(PicDesc, IPictureGUID(), _
inOwnObj, RetPic) = S_OK) Then Set GDIToPicture = RetPic
Set RetPic = Nothing

If ((GDIToPicture Is Nothing) And inDestroyOnFail) Then
Select Case ObjType ' Call appropriate cleanup routine
Case OBJ_BITMAP: Call DeleteObject(inGDIObj)
Case OBJ_METAFILE: Call DeleteMetaFile(inGDIObj)
Case OBJ_ENHMETAFILE: Call DeleteEnhMetaFile(inGDIObj)
Case Else: Call DestroyIcon(inGDIObj)
End Select
End If
End Function

Public Function PtrToPicture(ByVal inPtr As Long, ByVal inSize As Long) As IPicture
Dim hGlobal As Long, DataPtr As Long
Dim hStream As IUnknown

If (inSize > 0) Then ' Create global memory object
hGlobal = GlobalAlloc(GMEM_MOVEABLE, inSize)

If (hGlobal) Then ' Get pointer to data
DataPtr = GlobalLock(hGlobal)

If (DataPtr) Then ' Copy picture data into object
Call RtlMoveMemory(ByVal DataPtr, ByVal inPtr, inSize)
Call GlobalUnlock(hGlobal)

' Create new IPicture object from global memory object's data
If (CreateStreamOnHGlobal(hGlobal, 1&, hStream) = S_OK) Then _
Call OleLoadPicture(ByVal ObjPtr(hStream), inSize, 0&, IPictureGUID(), PtrToPicture)
End If

' Clean up on failure
If (PtrToPicture Is Nothing) Then _
Call GlobalFree(hGlobal)
End If
End If
End Function

Private Function WMFToEMF(ByVal inWMF As Long) As Long
Dim EMetaDC As Long

' Create a new Enhanced metafile device context
EMetaDC = CreateEnhMetaFile(0, vbNullString, ByVal 0&, vbNullString)
Call PlayMetaFile(EMetaDC, inWMF)
WMFToEMF = CloseEnhMetaFile(EMetaDC)

If (WMFToEMF = 0) Then ' If first method fails, try copy method
Dim WMFSize As Long, WMFData() As Byte
Dim MetaInf As MetaFilePict

' Query WMF data size
WMFSize = GetMetaFileBitsEx(inWMF, 0, ByVal 0&)
If (WMFSize) Then ' Allocate data buffer and extract WMF data
ReDim WMFData(WMFSize - 1) As Byte
Call GetMetaFileBitsEx(inWMF, WMFSize, WMFData(0))

MetaInf.hMF = inWMF ' Convert WMF data to EMF
WMFToEMF = SetWinMetaFileBits(WMFSize, WMFData(0), 0, MetaInf)
End If
End If
End Function

Public Function HimetricToPixelsX(ByVal inHimetric As Long) As Long
HimetricToPixelsX = ConvertPixelHimetric(inHimetric, True, True)
End Function

Public Function HimetricToPixelsY(ByVal inHimetric As Long) As Long
HimetricToPixelsY = ConvertPixelHimetric(inHimetric, True, False)
End Function

Public Function PixelsToHimetricX(ByVal inPixels As Long) As Long
PixelsToHimetricX = ConvertPixelHimetric(inPixels, False, True)
End Function

Public Function PixelsToHimetricY(ByVal inPixels As Long) As Long
PixelsToHimetricY = ConvertPixelHimetric(inPixels, False, False)
End Function

Private Function ConvertPixelHimetric(ByVal inValue As Long, _
ByVal ToPix As Boolean, inXAxis As Boolean) As Long
Dim TempIC As Long, GDCFlag As Long

Const HimetricInch As Long = 2540

TempIC = CreateIC("DISPLAY", vbNullString, vbNullString, ByVal 0&)

If (TempIC) Then
If (inXAxis) Then GDCFlag = LOGPIXELSX Else GDCFlag = LOGPIXELSY

If (ToPix) Then _
ConvertPixelHimetric = MulDiv(inValue, GetDeviceCaps(TempIC, GDCFlag), HimetricInch) _
Else _
ConvertPixelHimetric = MulDiv(inValue, HimetricInch, GetDeviceCaps(TempIC, GDCFlag))

Call DeleteDC(TempIC)
End If
End Function

Private Function IPictureGUID() As GUID
' IPicture GUID {7BF80980-BF32-101A-8BBB-00AA00300CAB}
With IPictureGUID
.Data1 = &H7BF80980
.Data2 = &HBF32
.Data3 = &H101A
.Data4(0) = &H8B
.Data4(1) = &HBB
.Data4(2) = &H0
.Data4(3) = &HAA
.Data4(4) = &H0
.Data4(5) = &H30
.Data4(6) = &HC
.Data4(7) = &HAB
End With
End Function

Комментариев нет:

Отправить комментарий