Using Data Resources


Let’s start with raw binary data—if you know how that works, you can figure out what to do with other kinds of data. You can cram any binary data you want into a resource file. Use the predefined RT_RCDATA type, or invent your own resource type name. Of course, WinWatch won’t know how to handle unknown data types; the best it can do is dump the binary data in hex format.


The goal is to turn a resource into an array of bytes, which is the approved way for Visual Basic to handle binary data. You can also handle data as strings, but that’s politically incorrect, particularly in a chapter such as this, which deals with multiple languages. Here’s how ShowData reads and dumps generic data:

Sub ShowData(ByVal hMod As Long, sData As String, _
Optional sDataType As String = “RCDATA”)

Dim hRes As Long, hmemRes As Long, cRes As Long
Dim pRes As Long, abRes() As Byte
If sDataType = “RCDATA” Then
hRes = FindResourceStrId(hMod, sData, RT_RCDATA)
Else
hRes = FindResourceStrStr(hMod, sData, sDataType)
End If
If hRes = hNull Then
pbResource.Print “Can’t display data: “ & sCrLf & sCrLf & _
WordWrap(ApiError(Err.LastDllError), 25)
Exit Sub
End If
‘ Allocate memory block and get its size
hmemRes = LoadResource(hMod, hRes)
cRes = SizeofResource(hMod, hRes)
‘ Don’t dump more than 500 bytes
If cRes > 500 Then cRes = 500
‘ Lock it to get pointer
pRes = LockResource(hmemRes)
‘ Allocate byte array of right size
ReDim abRes(cRes)
‘ Copy memory block to array
CopyMemory abRes(0), ByVal pRes, cRes
‘ Free resource (no need to unlock)
Call FreeResource(hmemRes)
pbResource.Print HexDump(abRes, False)

End Sub

First you use FindResourceStrId or FindResourceStrStr (aliases for FindResource) to get a handle to the resource. Then you move through the memory-allocation fire drill described in the sidebar, “The Zen of Windows Memory Management,” page 454: allocate, lock, process, unlock, free. You’ll learn to recognize this pattern. The process step in ShowData copies the resource to a byte array. Refer back to the sidebar, “CopyMemory: A Strange and Terrible Saga,” page 90, to find the story of CopyMemory and its aliased friends CopyMemoryToStr and CopyMemoryRef.


You can probably guess what the HexDump function (or its cousins, HexDumpS and HexDumpB) looks like; check it out in UTILITY.BAS. It dumps in either
8-byte rows (if you pass False as the second argument) or the traditional 16-byte format used by most debuggers. I use the 8-byte form in WinWatch so that the dump will fit in the picture box. Your dumps will look a lot better if you set the font of the output object (label, text box, picture box, printer) to a mono­space font.