HOWTO: Build a Windows Message Handler with AddressOf in VBID: Q170570
|
Prior to the release of Visual Basic 5.0, many developers used third-party
Windows message-handling tools or developed their own with tools such as
Microsoft Visual C++. With the addition of the AddressOf function to Visual
Basic 5.0 and higher, developers can now create their own Windows message-
handling routines within their Visual Basic applications.
For example, when a user right-clicks on a textbox in Windows 95 or Windows
98 or Windows NT 4.0, the operating system automatically displays a default
context menu. This default behavior occurs before the Visual Basic
application fires the MouseUp event. Without the use of a Windows message
handler, there is no way to replace the default context menu with a custom
built context menu.
WARNING: Using AddressOf may cause unpredictable results if you don't
completely understand the concept of function callbacks. You must
understand how the Basic portion of the callback works, and also the code
of the DLL into which you are passing your function address. Debugging such
interactions is difficult because the program runs in the same process as
the development environment. In some cases, systematic debugging may not be
possible. See details in the REFERENCES section of this article for more
information.
The following sample shows how to build a Windows message handler to trap
and discard the right-click message to replace the default context menu
with a custom built one:
Private Sub cmdHook_Click()
Hook
End Sub
Private Sub cmdUnHook_Click()
UnHook
End Sub
Private Sub Form_Load()
gHW = txtHook.hWnd
End Sub
Private Sub txtHook_MouseUp(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
If Button = vbRightButton Then
PopupMenu mnuPopup
End If
End Sub
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, _
ByVal hWnd As Long, _
ByVal Msg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Public Const GWL_WNDPROC = -4
Public Const WM_RBUTTONUP = &H205
Global lpPrevWndProc As Long
Global gHW As Long
Public Sub Hook()
lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, _
AddressOf WindowProc)
End Sub
Public Sub UnHook()
Dim lngReturnValue As Long
lngReturnValue = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)
End Sub
Function WindowProc(ByVal hw As Long, _
ByVal uMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Select Case uMsg
Case WM_RBUTTONUP
Form1.PopupMenu Form1.mnuPopup
Case Else
WindowProc = CallWindowProc(lpPrevWndProc, hw, _
uMsg, wParam, lParam)
End Select
End Function
This as an advanced topic for users experienced with using callbacks,
typically C developers. If you are not familiar with the use of callbacks,
then the following references may apply:
The Visual Basic 5.0 Programmers Guide to the Win32 API by Dan Appleman,
ISBN 1-56276-446-2 published by Ziff-Davis
The Win32 SDK Online Help
(c) Microsoft Corporation 1997, All Rights Reserved.
Contributions by David Sceppa, Microsoft Corporation
Additional query words: AddressOf subclass sub-class
Keywords : kbAPI kbVBp500 kbVBp600 kbWinOS98
Version :
Platform :
Issue type : kbhowto
Last Reviewed: May 12, 1999