
Artículo: Q170570
Antes de la salida de Visual Basic 5.0, muchos desarrolladores usaban utilidades para el manejo de mensajes de terceras partes o desarrollados por ellos mismos con herramientas como Microsoft Visual C++. Con la función AddressOf de Visual Basic 5.0, los desarrolladores pueden ahora crear sus propias rutinas para el manejo de mensajes en sus aplicaciones Visual Basic.
Por ejemplo, cuando un usuario pulsa con el botón derecho del ratón sobre un text box en Windows 95 o Windows NT 4.0, el sistema operativo muestra automáticamente el menú contextual por defecto. Esto ocurre antes de que se dispare el evento MouseUp. Sin el uso de un "manejador" de mensajes, no hay ma de reemplazar el menú por defecto por uno propio. (Realmente esto no es así y en estas mismas páginas hay un truco para hacerlo).
ATENCION: el uso de AddressOf puede causar resultados impredecibles si no comprendes completamente el uso de las funciones callback. Debes comprender cómo trabaja la parte de Basic y la DLL a la que estás pasando la dirección de tu función. La depuración es muy difícil porque el programa corre en el mismo proceso que el entorno de desarrollo, e incluso en algunos casos es imposible.
El siguiente ejemplo muestra cómo construir una rutina para el manejo de mensajes para atrapar y descartar el mensaje del click con el botón derecho para reemplazar el menú contextual por defecto con uno construido por nosotros:
1 - Abrir un nuevo proyecto.
2 - Añadir dos opciones de menú :
- En la primera, ponemos la propiedad Caption a "Mi Popup", la Name a "mnuPopup" y la propiedad Visible a "False"
- En la segunda, submenú de la primera, la propiedad Caption a "Mi Contexto" y la propiedad Name a "mnuPopupContext".
3 - Añadimos dos botones y un textbox al formulario:
- Al primer botón lo llamamos "cmdHook" y ponemos la propiedad Caption a "&Hook".
- Al segundo lo llamamos "cmdUnHook" y ponemos el Caption a "&UnHook".
- Al textbox lo llamamos "txtHook".
4 - Añadimos el siguiente código en el formulario:
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
5 - Añadimos un módulo al proyecto.
6 - Añadimos el siguiente código en el nuevo módulo:
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
7 - Grabamos el proyecto y lo ejecutamos. Si pulsamos con el botón derecho sobre el textbox aparece el menú contextual por defecto antes que el nuestro. Pinchamos en el botón "Hook" para activar la rutina de manejo de mensajes. Si pinchamos ahora con el botón derecho sobre el textbox ya no aparece el menú por defecto. Asegúrate de pinchar en el botón UnHook antes de cerrar la aplicación. Si pulsas el botón End mientras ejecutas el ejemplo con el hook activado se provoca un error de protección general.

