|
-
Jun 23rd, 2021, 10:35 PM
#1
Thread Starter
Junior Member
How to use GUID in VB6?
Hello. I was looking for how to convert image to byte array, and i found this https://www.vbforums.com/showthread....-on-Picturebox. It works on my case, but i have no idea why is the code like that, what is GUID, and why i must use that. Can i use the identifier randomly? i need an explanation for this code. i've tried to googled it but still can't understand. Here's the code.
Code:
Private Function ArrayToPicture(inArray() As Byte, Offset As Long, Size As Long) As IPicture
' function creates a stdPicture from the passed array
' Offset is first item in array: 0 for 0 bound arrays
' Size is how many bytes comprise the image
Dim o_hMem As Long
Dim o_lpMem As Long
Dim aGUID(0 To 3) As Long
Dim IIStream As IUnknown
aGUID(0) = &H7BF80980 ' GUID for stdPicture
aGUID(1) = &H101ABF32
aGUID(2) = &HAA00BB8B
aGUID(3) = &HAB0C3000
o_hMem = GlobalAlloc(&H2&, Size)
If Not o_hMem = 0& Then
o_lpMem = GlobalLock(o_hMem)
If Not o_lpMem = 0& Then
CopyMemory ByVal o_lpMem, inArray(Offset), Size
Call GlobalUnlock(o_hMem)
If CreateStreamOnHGlobal(o_hMem, 1&, IIStream) = 0& Then
Call OleLoadPicture(ByVal ObjPtr(IIStream), 0&, 0&, aGUID(0), ArrayToPicture)
End If
End If
End If
End Function
I use it with this code
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
-
Jun 24th, 2021, 02:10 AM
#2
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.
-
Jun 24th, 2021, 02:20 AM
#3
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.
-
Jul 16th, 2021, 11:39 AM
#4
Thread Starter
Junior Member
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.
 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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|