Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type
Private Declare Function CreateStreamOnHGlobal Lib "ole32.dll" (ByRef hGlobal As Any, ByVal fDeleteOnResume As Long, ByRef ppstr As Any) As Long
Private Declare Function OleLoadPicture Lib "olepro32.dll" (ByVal lpStream As IUnknown, ByVal lSize As Long, ByVal fRunMode As Long, ByRef riid As GUID, ByRef lplpObj As Any) As Long
Private Declare Function CLSIDFromString Lib "ole32.dll" (ByVal lpsz As Long, ByRef pclsid As GUID) As Long
' convert a byte array to IPicture
Public Function PictureFromRes(ByRef b() As Byte) As IPicture
On Error GoTo errorhandler
Dim istrm As IUnknown
Dim tGuid As GUID
If Not CreateStreamOnHGlobal(b(LBound(b)), False, istrm) Then
CLSIDFromString StrPtr(SIPICTURE), tGuid
OleLoadPicture istrm, UBound(b) - LBound(b) + 1, False, tGuid, PictureFromRes
End If
Set istrm = Nothing
Exit Function
errorhandler:
Debug.Print "Could not convert to IPicture!"
End Function
Const GMEM_MOVEABLE = &H2
Const GMEM_ZEROINIT = &H40
Const GHND = (GMEM_MOVEABLE Or GMEM_ZEROINIT)
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Const PictureID = &H746C&
Private Type PictureHeader
Magic As Long
Size As Long
End Type
Public Sub Picture2Array(ByVal oObj As StdPicture, aBytes() As Byte)
Dim oIPS As IPersistStream
Dim oStream As IStream
Dim hGlobal As Long
Dim lPtr As Long
Dim lSize As Long
Dim Hdr As PictureHeader
Set oIPS = oObj
Set oStream = CreateStreamOnHGlobal(0, True)
oIPS.Save oStream, True
hGlobal = GetHGlobalFromStream(oStream)
lSize = GlobalSize(hGlobal)
lPtr = GlobalLock(hGlobal)
If lPtr Then
lSize = lSize - Len(Hdr)
ReDim aBytes(0 To lSize - 1)
MoveMemory aBytes(0), ByVal lPtr + Len(Hdr), lSize
End If
GlobalUnlock hGlobal
Set oStream = Nothing
End Sub
Public Function Array2Picture(aBytes() As Byte) As StdPicture
Dim oIPS As IPersistStream
Dim oStream As IStream
Dim hGlobal As Long
Dim lPtr As Long
Dim lSize As Long
Dim Hdr As PictureHeader
Set Array2Picture = New StdPicture
Set oIPS = Array2Picture
lSize = UBound(aBytes) - LBound(aBytes) + 1
hGlobal = GlobalAlloc(GHND, lSize + Len(Hdr))
If hGlobal Then
lPtr = GlobalLock(hGlobal)
Hdr.Magic = PictureID
Hdr.Size = lSize
MoveMemory ByVal lPtr, Hdr, Len(Hdr)
MoveMemory ByVal lPtr + Len(Hdr), aBytes(0), lSize
GlobalUnlock hGlobal
Set oStream = CreateStreamOnHGlobal(hGlobal, True)
oIPS.Load oStream
Set oStream = Nothing
End If
End Function
Private Sub Command1_Click()
Dim buff() As Byte
Picture2Array Picture1.Picture, buff
'测试
Set Picture2.Picture = Array2Picture(buff)
End Sub