|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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. |
|
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. |
|
|
|
|||||
|
|||||
|
|||||
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |