Many returned values from Win32 API function calls are returned as packed Longs or packed Integers. While programmers in c and Delphi have functions readily available that will unpack a long into a pair of integers or an integer into a pair of bytes, Visual Basic programmers aren't quite so fortunate. In fact, it wasn't until recently that the BYTE data type was even available to Visual Basic programmers, which forced the use of much slower string functions or the use of external libraries to handle the unpacking these values.
Below you will find four functions that will take care of the unpacking process for you. I choose to use functions since I prefer not to use temporary variables to store results. They should easily convert to subroutines if you prefer returning both HI/LO values at once.
In case you aren't up to speed on bytes and words and how they relate to integers and longs, I have included the table below to help clarify the relationships:
| VB Data Type | AKA | Contains |
| Byte | Byte | Smallest variable type, with values ranging from 0 to 255. |
| Integer | Word | 2 bytes. |
| Long | Double-word (often denoted in API declarations as dwVar) |
2 words, or 4 bytes. |
Just because a data type has the length of a word, doesn't mean that it is a VB integer. Visual Basic only supports signed integers, which provides both negative and positive values. Other languages support unsigned integers, which support only positive numbers. Word and byte are best used when describing the amount of memory used by a particular variable. Integer and Long describe precisely what a given word or double-word contain.
Public Function LoByte(ByVal IntegerVal As Integer) As Byte
LoByte = IntegerVal And &HFF&
End Function
Public Function HiByte(ByVal IntegerVal As Integer) As Byte
If IntegerVal = 0 Then
highbyte = 0
Exit Function
End If
HiByte = IntegerVal \ &H100 And &HFF&
End Function
Public Function LoWord(ByVal LongVal As Long) As Integer
LoWord = LongVal And &HFFFF&
End Function
Public Function HiWord(ByVal LongVal As Long) As Integer
If LongVal = 0 Then
HiWord = 0
Exit Function
End If
HiWord = LongVal \ &H10000 And &HFFFF&
End Function
This source is, for the most part, converted directly from a Microsoft example contained in Knowledge Base article #Q160215. The code Microsoft provided is flawed, failing to account for division by 0 errors, which this code traps. The Microsoft example is implemented as a pair of subroutines, so it will be worth examining if you want to convert this example into a subroutine but aren't quite sure about where to start.
Hopefully, future versions of Visual Basic will have functions built-in that will unpack packed integers and words. The Professional Edition of BASIC (BASCOM) spanned 8 versions, and VB was at version 4 before support for a byte data type was added. Now that the base data types exists, it should just be a matter of time before they add functions to actually use them.
Post new comment