Este ejemplo utiliza un Hook para interceptar los mensajes de Windows que llegan a nuestra aplicación, y de esta forma poder deshabilitar el menú contextual de un TextBox al hacer click derecho (el menú de copiar, pegar, seleccionar todo, …)
Para inicializar el hook se debe llamar a la función Hook y para removerlo o finalizarlo , la función UnHook.
A los dos procedimientos, se le debe pasar como parámetro el Hwnd del control Textbox.
Para deshabilitar el menú:
Call Hook (Text1.Hwnd)
Para habilitar el menú:
Call UnHook (Text1.hwnd)
Colocar un control Textbox llamado Text1 en el formulario. El Hook o procedimiento que procesa los mensajes, debe estar obligatoriamente declarado en un modulo:
'Función Api SetWindowLong
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
' Función Api CallWindowProc
Public 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
'Constantes
' mensaje para el menú contextual
Public Const WM_CONTEXTMENU = &H7B
Global lpPrevWndProc As Long
'Comienza el Hook
Public Sub Hook(Handle As Long)
lpPrevWndProc = SetWindowLong(Handle, -4, AddressOf WinProc)
End Sub
'Termina el Hook
Public Sub Unhook(Handle As Long)
Call SetWindowLong(Handle, -4, lpPrevWndProc)
End Sub
'Procedimiento chequea los mensajes que llegan para ver si se despliega el menú contextual en el textbox indicado
Public Function WinProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
' Chequea si el mensaje es WM_CONTEXTMENU (el menú contextual)
If Msg = WM_CONTEXTMENU Then
WinProc = True
Else
WinProc = CallWindowProc(lpPrevWndProc, hWnd, Msg, wParam, lParam)
End If
End Function
Y colocar esto en el formulario:
Option Explicit
Private Sub Form_Load()
'Inicializa el Hook ( Indicar el Textbox a deshabiltar )
Call Hook(Text1.hWnd)
End Sub
<p>Private Sub Form_Unload(Cancel As Integer)
'Remueve
Call Unhook(Text1.hWnd)
End Sub
Si quisieramos deshabilitar el menú contextual de todos los controles textbox que hay en el form, podemos hacerlo con un bucle For Each:
Option Explicit
Private Sub Form_Load()
Dim Ctrl As Control
'Recorre todos los textbox del formulario
For Each Ctrl In Me.Controls
'Verifica que el control es un textbox
If TypeOf Ctrl Is TextBox Then
'Inicia el hook
Hook Ctrl.hWnd
End If
Next
End Sub
Private Sub Form_Unload(Cancel As Integer)
Dim Ctrl As Control
'Recorre en un bucle todos los textbox del form
For Each Ctrl In Me.Controls
'¿ Es un textbox ?
If TypeOf Ctrl Is TextBox Then
'Finaliza el hook
Unhook Ctrl.hWnd
End If
Next
End Sub
Otra forma de poder realizar esto sin un Hook, es creando nuestro propio menú con el editor de Visual basic, y en el evento mouseDown del textbox, desplegamos un menú propio:
Private Sub Text1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button <> vbRightButton Then Exit Sub
Text1.Enabled = False
Text1.Enabled = True
Text1.SetFocus
'Despliega el PopupMenu en el textbox
Me.PopupMenu mnu_popUp
End Sub
Fuente: www.recursosvisualbasic.com.ar