Deshabilitar el menú contextual en textbox y combos
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 SubFuente: www.recursosvisualbasic.com.ar


