How To Package HiWord/LoWord Values Into a Long Parameter

Article translations Article translations
Article ID: 189170 - View products that this article applies to.
This article was previously published under Q189170
This article has been archived. It is offered "as is" and will no longer be updated.
Expand all | Collapse all

On This Page

SUMMARY

For some API functions, such as SendMessage or PostMessage, you may need to package two short Integer values into a Long variable to pass them as a single parameter. This article demonstrates how to package such Integers and how to unpack them if necessary.

MORE INFORMATION

The trick to packing values is bit shifting. Because Visual Basic does not provide bit shift operators to use, you need to do things the old fashioned way; through multiplication. To make an Integer the high word for a Long value, you need to multiply it by &H10000. This has the effect of shifting the bit values 16-bits (2-bytes) to the left, making room for the low word value you want to add.

Before you can add the low word value, however, you need to make an adjustment. Remember that Visual Basic Integer types are signed values, but the low word value needs to be unsigned if you plan to add it to your high word value. To make sure Visual Basic treats the low word as an unsigned integer, you need to perform a bitwise "And" on the value using &HFFFF& as a mask. In effect, this saves the value as a Long integer with the high (signed) bit cleared but keeps the original Integer's bit value preserved.

With this in mind, here is a Visual Basic function that creates a Long value from two Integers:
   Function MakeDWord(LoWord As Integer, HiWord As Integer) As Long
      MakeDWord = (HiWord * &H10000) Or (LoWord And &HFFFF&)
   End Function
				
Only a few API functions require that you unpack a double word into two short Integers. If you find that you need to perform such a task, you can use conversion routines similar to these:
   Function LoWord(DWord As Long) As Integer
      If DWord And &H8000& Then ' &H8000& = &H00008000
         LoWord = DWord Or &HFFFF0000
      Else
         LoWord = DWord And &HFFFF&
      End If
   End Function

   Function HiWord(DWord As Long) As Integer
      HiWord = (DWord And &HFFFF0000) \ &H10000
   End Function
				
Both these functions simply mask the portion of the Long integer they want to return using the bitwise "And" operator. The HiWord function shifts this value right 16-bits by dividing it by &H10000. The LoWord function can simply return the value of the "And" operation in most cases. However, because Visual Basic Integers are signed, any low word value that has its high bit set must be converted back into a negative value using the "Or" operator and a mask of &HFFFF0000.

Sample Code

  1. Open a new Standard EXE project in Visual Basic. Form1 is created by default.
  2. Add a CommandButton to the lower-right corner of Form1.
  3. Add the following code to the General Declaration section for Form1:
          Private Declare Function SendMessage Lib "user32" _
             Alias "SendMessageA" (ByVal hwnd As Long, _
                                   ByVal wMsg As Long, _
                                   ByVal wParam As Long, _
                                   ByVal lParam As Long) As Long
    
          Private Const MK_LBUTTON = &H1
          Private Const WM_LBUTTONDOWN = &H201
    
          Function MakeDWord(LoWord As Integer, HiWord As Integer) As Long
             MakeDWord = (HiWord * &H10000) Or (LoWord And &HFFFF&)
          End Function
    
          Private Sub Form_MouseDown(Button As Integer, Shift As Integer, _
          X As Single, Y As Single)
             Form1.Cls
             Form1.Print "Button Click Event Fired"
             Form1.Print "Position X:" & Str$(X / Screen.TwipsPerPixelX)
             Form1.Print "Position Y:" & Str$(Y / Screen.TwipsPerPixelY)
          End Sub
    
          Private Sub Command1_Click()
             Dim nMousePosition As Long
             ' nMousePosition stores the x (hiword) and y (loword) values
             ' of the mouse cursor as measured in pixels.
    
             Let nMousePosition = MakeDWord(16, 18)
             Call SendMessage(Me.hwnd, WM_LBUTTONDOWN, MK_LBUTTON, _
             nMousePosition)
          End Sub
    						
  4. Press the F5 key to run the project.

    You will notice that anywhere you click on the Form, the values of the mouse cursor are displayed (in pixels). When you click the CommandButton, the SendMessage call simulates a mouse click at the location 16 pixels right of the left side of the Form and 18 pixels down from the top, causing the Form_MouseDown event to fire.

REFERENCES

For additional information, please see the following article in the Microsoft Knowledge Base:
112651 How To Mimic HIWORD, LOWORD, HIBYTE, LOBYTE C Macros in VB

Properties

Article ID: 189170 - Last Review: February 24, 2014 - Revision: 3.1
APPLIES TO
  • Microsoft Visual Basic 5.0 Learning Edition
  • Microsoft Visual Basic 6.0 Learning Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic 6.0 Enterprise Edition
Keywords: 
kbnosurvey kbarchive kbhowto KB189170

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com