| How to prevent the default context menu from coming up over the TextBox |
Applies To |
|
| OS: VB: |
NT, 9x, 2000 5, 6 |
|
As any Windows user knows, when you right-click over the textbox, a helpful menu pops up. Since Windows 95 came out on the market, there have been a lot of whacky code written on how to get rid of the context menu. First there were convoluted solutions based on disabling the textbox in the MouseDown down event. Then the next generation of code used third-party components such as MessageHook OCX from Mabry to try and catch the message. Yet other code tries to catch WM_RBUTTONUP, thus disabling mouse event handling for right button click. Here is how to do the right way using VB code only. As one may have guessed it involves subclassing and catching the WM_CONTEXTMENU menu.
Warning: never end programs that use AddressOf operator by pressing the End button on the VB toolbar. End the program by clicking the X (close) button on the form.
This project is also available as a download .
| Project Creation Instructions. |
|---|
| Add the following to a .BAS module |
|---|
Option Explicit
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
Private Const GWL_WNDPROC = -4
Private IsHooked As Boolean
Private lpPrevWndProc As Long
Private Const WM_CONTEXTMENU = &H7B
Public ShowCustomMenu As Boolean
Public TextHandle As Long
Public Sub Hook()
If IsHooked Then
MsgBox "You are already hooked for this handle."
Else
'this tells windows to send all the messages that
'are intended for this form to sub WindowProc
lpPrevWndProc = SetWindowLong(TextHandle, GWL_WNDPROC, _
AddressOf WindowProc)
IsHooked = True
End If
End Sub
Public Sub Unhook()
Dim temp As Long
If IsHooked Then
'this tells windows to send all the messages that
'are intended for this form to sub WindowProc
temp = SetWindowLong(TextHandle, GWL_WNDPROC, lpPrevWndProc)
IsHooked = False
End If
End Sub
Function WindowProc(ByVal hw As Long, ByVal uMsg As _
Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If uMsg = WM_CONTEXTMENU Then
If ShowCustomMenu Then Form1.PopupMenu Form1.mnuCustom
Debug.Print "Default Right click prevented"
Else
WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
End If
End Function
| Add the following code to Form1 |
|---|
Option Explicit
Private Sub ToggleControls(flag As Boolean)
btnHook.Enabled = flag
btnUnhook.Enabled = Not flag
chkCustomMenu.Enabled = Not flag
End Sub
Private Sub btnHook_Click()
'start subclassing
Hook
ToggleControls False
End Sub
Private Sub btnUnhook_Click()
'end subclassing
Unhook
ToggleControls True
End Sub
Private Sub chkCustomMenu_Click()
ShowCustomMenu = IIf(chkCustomMenu.Value = vbChecked, True, False)
End Sub
Private Sub Form_Load()
'record the name of the textbox we want to manipulate
TextHandle = Me.Text1.hwnd
ToggleControls True
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
'end subclassing
Unhook
End Sub
| Remarks |
|---|