That code uses the Interface Identifier (IID) for the IPicture interface. An IID happens to be of GUID type, so it can cause some confusion leading to poor and further misleading code like that shown above.
That code is even worse in a way because it unnecessarily copies the Byte array before using it, chewing up extra memory and CPU cycles.
I'd use this instead:
But it is essentially the same thing without the clumsy overhead. If you call it multiple times it would help to assign IID_IPicture once before calling the LoadPictureBytes() function.Code:Private Const READ_ALL As Long = 0 Private Const WIN32_FALSE As Long = 0 Private Type IID Data1 As Long Data2 As Integer Data3 As Integer Data4(0 To 7) As Byte End Type Private Declare Function CLSIDFromString Lib "ole32" ( _ ByVal lpsz As Long, _ ByRef clsid As IID) As Long Private Declare Function OleLoadPicture Lib "oleaut32" ( _ ByVal Stream As IUnknown, _ ByVal lSize As Long, _ ByVal fRunmode As Long, _ ByRef riid As IID, _ ByRef Picture As IPicture) As Long Private Declare Function SHCreateMemStream Lib "shlwapi" Alias "#12" ( _ ByRef Init As Byte, _ ByVal cbInit As Long) As IUnknown Private Function LoadPictureBytes(ByRef Bytes() As Byte) As IPicture Dim Count As Long Dim Stream As IUnknown Dim IID_IPicture As IID Count = UBound(Bytes) - LBound(Bytes) + 1 If Count < 1 Then Exit Function Set Stream = SHCreateMemStream(Bytes(LBound(Bytes)), Count) If Not (Stream Is Nothing) Then CLSIDFromString StrPtr("{7BF80980-BF32-101A-8BBB-00AA00300CAB}"), IID_IPicture OleLoadPicture Stream, READ_ALL, WIN32_FALSE, IID_IPicture, LoadPictureBytes End If End Function
If you want to know what OleLoadPicture() does you can look it up in your MSDN Library Help. Every legal copy of VB6 Pro and Enterprise came with the online Help and Samples on CDs. You can also find it at OleLoadPicture function (olectl.h).
OleLoadPicture() returns an object reference upon success. The object is a StdPicture but you need to tell it which public interface you want a pointer to. That is why the reference to interface identifier (riid, a pointer to an IID) is needed.
There are two: IPicture and IPictureDisp. So we pick one since we don't care in VB6 because when we need to query for another interface that gets handled for us through coercion behind the scenes.
VB6 does a lot of things like that for us, either emitting code or calls into the runtime to coerce data. But once we try to creep below the covers by making explicit API calls we have to be a lot more careful and handle more details.




Reply With Quote