Re: How to use GUID in VB6?
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:
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
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.
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.
Re: How to use GUID in VB6?
This code gives me the willies:
Code:
Public Function Base64Encode(vArr As Variant) As String
Const Routine As String = "Base64.Base64Encode"
Dim xmlDoc As Object
Dim xmlNode As Object
Set xmlDoc = CreateObject("MSXML2.DOMDocument")
Set xmlNode = xmlDoc.createElement("b64")
xmlNode.DataType = "bin.base64"
xmlNode.nodeTypedValue = vArr
Base64Encode = xmlNode.Text
End Function
Why are you late binding those MSXML2 objects?
Why are you passing vArr As Variant? As far as I can tell that code will only work in the case where you pass a Byte array, so why not make it type safe and declare it like:
Code:
Public Function Base64Encode(ByRef Bytes() As Byte) As String
Just like the previous code above, it works... with warts... as long as you hold your mouth right and cross your fingers.
Re: How to use GUID in VB6?
dilettante, sorry I take a long time to responded to it. Many thanks for your code and example. I use the base64 encoding method to process this picture. i use the previous program that i asked for an explanation. It succeeded, but is there any other method to process the jpeg picture? actually I will send the data in the radio module that needs a binary input.
Quote:
Originally Posted by
dilettante
This code gives me the willies:
Code:
Public Function Base64Encode(vArr As Variant) As String
Const Routine As String = "Base64.Base64Encode"
Dim xmlDoc As Object
Dim xmlNode As Object
Set xmlDoc = CreateObject("MSXML2.DOMDocument")
Set xmlNode = xmlDoc.createElement("b64")
xmlNode.DataType = "bin.base64"
xmlNode.nodeTypedValue = vArr
Base64Encode = xmlNode.Text
End Function
Why are you late binding those MSXML2 objects?
Why are you passing
vArr As Variant? As far as I can tell that code will only work in the case where you pass a Byte array, so why not make it type safe and declare it like:
Code:
Public Function Base64Encode(ByRef Bytes() As Byte) As String
Just like the previous code above, it works... with warts... as long as you hold your mouth right and cross your fingers.