Visual Basic Subclassing Routines
WM_CONTEXTMENU: Kill the Default Text Box Context Menu
     
Posted:   Wednesday July 1, 1998
Updated:   Monday December 26, 2011
     
Applies to:   VB5, VB6
Developed with:   VB6, Windows 98
OS restrictions:   None
Author:   MSKB,  VBnet - Randy Birch
     

Related:  

 

WM_CONTEXTMENU: Kill the Default Text Box Context Menu
SendMessage: Make a Style-0 Combo Edit Read-Only
FindWindowEx: Obtain Combo Box Edit Window Handle
GetComboBoxInfo: Obtain Combo Box Edit and List Handles on Win98/NT5
     
 Prerequisites
VB5 or VB6.

contextmenu.gif (6385 bytes)This is the correct procedure, using subclassing, to intercept display of the default context menu for a textbox, in order to either suppress it completely, or to substitute your own menu in its place.

This routine is based on the Microsoft Knowledge Base article Q224302 How To Suppress a TextBox Control's Popup Menu.

 BAS Module Code
Place the following code into the general declarations area of a bas module:

Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private 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

Private 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 As Long = (-4)
Private Const WM_CONTEXTMENU As Long = &H7B
Public defWndProc As Long


Public Sub Hook(hwnd As Long)

   If defWndProc = 0 Then
    
      defWndProc = SetWindowLong(hwnd, _
                                 GWL_WNDPROC, _
                                 AddressOf WindowProc)
   End If
                                 
End Sub


Public Sub UnHook(hwnd As Long)

    If defWndProc > 0 Then
    
      Call SetWindowLong(hwnd, GWL_WNDPROC, defWndProc)
      defWndProc = 0
      
   End If
   
    
End Sub


Public Function WindowProc(ByVal hwnd As Long, _
                           ByVal uMsg As Long, _
                           ByVal wParam As Long, _
                           ByVal lParam As Long) As Long

   Select Case uMsg
      Case WM_CONTEXTMENU
      
        'this executes when the window is hooked
         Form1.PopupMenu Form1.mnuPopup
         WindowProc = 1
          
      Case Else
      
         WindowProc = CallWindowProc(defWndProc, _
                                     hwnd, _
                                     uMsg, _
                                     wParam, _
                                     lParam)
   End Select
    
End Function
 Form Code
To a form, add a top level menu (mnuPopup), and any number of submenu items under it. Add a text box (Text1), and two command buttons (Command1, Command2) to the form along with the following code:

Option Explicit
         
Private Sub Form_Load()

   Command1.Caption = "Hook Textbox"
   Command2.Caption = "Unhook"
   
End Sub         


Private Sub Command1_Click()

   Call Hook(Text1.hwnd)

End Sub


Private Sub Command2_Click()

   Call UnHook(Text1.hwnd)

End Sub


Private Sub Form_Unload(Cancel As Integer)

  'just in case, assure the 
  'textbox is unhooked before exiting
   Call UnHook(Text1.hwnd)
   
End Sub


Private Sub Text1_MouseUp(Button As Integer, _
                           Shift As Integer, _
                           X As Single, Y As Single)

  'this executes only when the window is unhooked
  'and shows the default behaviour - first the
  'generic textbox menu is shown, then on closing
  'the custom textbox popup appears
   If defWndProc = 0 Then
      If Button = vbRightButton Then
          PopupMenu mnuPopup
      End If
   End If
   
End Sub
 Comments
Save then run the project. Running using the Full Compile option is recommended when creating or changing the form, as once the form becomes subclassed, you can not edit the code should an error occur. Once running, right-click the textbox. If the Hook button has not been pressed, you will see the default menu followed by the popup menu you defined.  After pressing the Hook button, the default menu is suppressed.

To hook more than one textbox on the form, some method of storing the original window procs is needed.  The HookMe code from www.mvps.org/vb/ does the trick nicely.


 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

Hit Counter