CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Sep 2002
    Posts
    9

    How to disable default popup menu

    Hi,
    I want to display a popup menu over a textbox. I put the relevant code under mouse down event with a check for right button.

    What i get is, that when the user right click on the mouse, it get the default popup menu of windows (cut, copy, paste ...) and only when he right click again, he gets mine.
    I guess, i can somhow disable this default popup, but dont know how.

    Thanks,
    Eran

  2. #2
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    Lightbulb Once Cakkie teached it to me

    http://www.codeguru.com/forum/showth...+default+popup

    Have a nice day
    Code:
    Option Explicit
    
    Private Sub Text1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Button = vbRightButton Then
       Text1.Enabled = False
       Call Text1_MouseUp(Button, Shift, X, Y)
    End If
    End Sub
    
    Private Sub Text1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    '
    
    If Button = vbRightButton Then
       Text1.Enabled = True
       PopupMenu mnumypop
    End If
    End Sub
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

  3. #3
    Join Date
    Apr 2002
    Location
    Egypt
    Posts
    2,210

    Thumbs up This is an interesting issue!!

    Ok Cimperiali
    There is one major disadvantage of this procedure:
    It doesn't work if the user requests the context menu (popup menu) using the keyboard (He can do so by pressing the popup menu button in new keyboards or by pressing SHIFT + F10)
    Another minor disadvantage is:
    The regular popup menu shows up when the user releases the right button not when he make the mouse down event..

    So this is my way to do it by subclassing the text box control:

    Form's code :
    Code:
    'using subclassing
    Private Sub Form_Load()
    'here:define a new window procedure for the text box
    prevProc = SetWindowLong(Text2.hwnd, GWL_WNDPROC, AddressOf WindowProc)
    End Sub
    Module's code :
    Code:
    Option Explicit
    
    'Declaration
    Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    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
    
    Public prevProc As Long
    
    Public Const GWL_WNDPROC = (-4)
    Const WM_CONTEXTMENU = &H7B
    
    'this function intercepts all messages (events) sent to the textbox
    'it forwards all messages to the default window procedure
    'except the WM_CONTEXTMENU message
    Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    If uMsg = WM_CONTEXTMENU Then
        frm.PopupMenu frm.mnu
    Else
        WindowProc = CallWindowProc(prevProc, hwnd, uMsg, wParam, lParam)
    End If
    End Function
    Attached Files Attached Files

  4. #4
    Join Date
    Dec 2001
    Posts
    6,332
    This issue seems to come up all the time. I really wanted to deal with this once and for all, but without any hooks. Well, here it is!! This demonstrates how to do multiple tricks with a textbox, including:
    1) Have a custom popup menu
    2) Have no menu whatsoever
    3) Prevent pasting, even while allowing the default menu
    4) Prevent pasting via the keyboard
    5) Prevent Alt codes


    You will see that the trick was to use the SetCapture API call.

    It accounts for Shift+F10 and the context menu key as well. It seems the context menu key bypasses the normal key events of the textbox, so it can't be set to zero like the other keys, even though it fires the KeyDown event. So, in the case of this when wanting no menu at all, focus must be diverted away from the textbox. The two solutions I found are a messagebox, or setting the focus to something else on the form. I suppose if the user is actually going to try this key, a message telling them they can't is not so bad (until today I never tried this key before). I did find one issue with the context menu key however. If you dismiss the custom menu or messagebox very very quickly, the default menu shows up. I think this is because the window message is still in the buffer, because I found that setting focus to another textbox will cause the menu for that one to show instead. If anyone finds a fix for this key, please share it

    <UPDATE>
    After all this time, a new member has found that the default menu will appear if the user double right-clicks! The fix for that was simple, and I posted an update on that thread:
    http://www.codeguru.com/forum/showth...51#post1227651
    Attached Files Attached Files
    Last edited by WizBang; September 7th, 2005 at 08:33 AM.
    Please remember to rate the posts and threads that you find useful.
    How can something be both new and improved at the same time?

  5. #5
    Join Date
    Apr 2002
    Location
    Egypt
    Posts
    2,210

    Cool window subclassing

    Originally posted by WizBang
    I really wanted to deal with this once and for all, but without any hooks.
    the way I used is (window subclassing) .. completely different from windows hooks..
    using the same way you can disallow copy,paste, some key presses , etc...
    simply this is the right way to make it

  6. #6
    Join Date
    Dec 2001
    Posts
    6,332
    the way I used is (window subclassing) .. completely different from windows hooks..
    Well, although I was not really referring to your example directly, subclassing, as well as hooks, can be rather problematic. As for being completely different, I'd guess I'm not the only one who might point out similarities. In any case, multiple controls handled in this way multiply the complexity of a project, not to mention the debugging problems that are so often encountered. Anyone who has used either of these methods will have likely crashed the IDE a number of times. Even without such techniques, vb is far from crash-proof, but that's only one issue.
    simply this is the right way to make it
    I like to say there is no single "right" way to do something. There are always alternatives, and it is up to the developer to choose the means that fill the requirements to the best of his/her ability. Whenever I find what seems like a better way, I find myself going through code which I thought was finished, and sometimes I end up putting things back the way they were. This is one reason for program updates, and new versions. Sometimes simple is better, and sometimes not. Perhaps the answer is: "it all depends".
    Please remember to rate the posts and threads that you find useful.
    How can something be both new and improved at the same time?

  7. #7
    Join Date
    Jun 2004
    Posts
    3

    Keeping it simple.

    I like to say there is no single "right" way to do something.
    Keeping this in mind, try this code *just* to eliminate the default popup.

    Private Declare Function SetCapture Lib "user32" (ByVal hWnd As Long) As Long
    Private Declare Function ReleaseCapture Lib "user32" () As Long
    Private oMenu As Menu

    Private Sub Text1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Button = vbRightButton Then
    Set oMenu = mnuContext
    SetCapture Me.hWnd
    End If
    End Sub

    Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Button = vbRightButton Then
    PopupMenu oMenu, vbPopupMenuLeftAlign Or vbPopupMenuRightButton
    ReleaseCapture
    End If
    End Sub

    In this method, the mouse_down event sets a generic menu object to the popup menu to display for the context, and triggers the capture. The mouse_up event (at the form level) then displays the context menu and, when complete, the ReleaseCapture is performed.

  8. #8
    Join Date
    Dec 2001
    Posts
    6,332
    rambotech
    Nifty. However, what to do about right-clicking on the form? If you do this before right-clicking on the textbox, the object isn't set, thus raising an error. Setting a flag can eliminate that problem. Why not use the menu directly instead of setting an object? There's still the Shift+F10 issue as well. Maybe I'll look into it later when I have more time to fully test.
    Last edited by WizBang; June 15th, 2004 at 03:18 AM.
    Please remember to rate the posts and threads that you find useful.
    How can something be both new and improved at the same time?

  9. #9
    Join Date
    Jun 2004
    Posts
    3
    Originally posted by WizBang
    rambotech
    Nifty. However, what to do about right-clicking on the form? If you do this before right-clicking on the textbox, the object isn't set, thus raising an error. Setting a flag can eliminate that problem. Why not use the menu directly instead of setting an object? There's still the Shift+F10 issue as well. Maybe I'll look into it later when I have more time to fully test.
    You answered the first part very well: I would also use a boolean, or set the menu object to nothing after the release. The test for popping up a menu would be whether the menu object was other than nothing. This was just an example of a basic technique to override that default context menu.

    The reason I didn't use the menu directly is that this example accomodates multiple objects. The menu object is simply set to the desired context menu at the MouseDown event for the particular user control receiving the right-click event. By using the object, the MouseUp event at the form-level will always show the proper context menu for the control.

    I'm not familiar with the Shift+F10 issue. Is there a thread or link that discusses it?

  10. #10
    Join Date
    Jun 2004
    Posts
    3
    Maybe this code will cover more cases. One case which I will work on is distinguishing a drap-drop operation.
    Code:
    Private Declare Function SetCapture Lib "user32" (ByVal hWnd As Long) As Long
    Private Declare Function ReleaseCapture Lib "user32" () As Long
    Private oMenu As Menu
    
    Private Sub Text1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
      If Button = vbRightButton Then
        Set oMenu = mnuContextText1
        SetCapture Me.hWnd
      End If
    End Sub
    
    Private Sub Text2_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
      If Button = vbRightButton Then
        Set oMenu = mnuContextText2
        SetCapture Me.hWnd
      End If
    End Sub
    
    Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
      If Button = vbRightButton and TypeName(oMenu) <> "Nothing" Then
        PopupMenu oMenu, vbPopupMenuLeftAlign Or vbPopupMenuRightButton
        ReleaseCapture
        Set oMenu=Nothing
      End If
    End Sub
    Last edited by Cimperiali; June 15th, 2004 at 09:34 AM.

  11. #11
    Join Date
    Dec 2001
    Posts
    6,332
    That is basically what I was thinking, although I would make use of the Is operator to check the object.

    Code:
    Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
      If Button = vbRightButton And Not oMenu Is Nothing Then
        PopupMenu oMenu, vbPopupMenuLeftAlign Or vbPopupMenuRightButton
        ReleaseCapture
        Set oMenu = Nothing
      End If
    End Sub
    As for the Shift+F10 issue, just try that key combination while the textbox has focus, and you'll see the default menu pop up.
    Please remember to rate the posts and threads that you find useful.
    How can something be both new and improved at the same time?

  12. #12
    Join Date
    Aug 2006
    Location
    Hubli, India
    Posts
    70

    Smile Re: How to disable default popup menu

    Hello friends, I am a new guy, I saw all the solutions here, but, i wanted a easy way to do it you know easy and tricky.

    well i found it myself , here it goes

    Dim SCM As Menu

    Private Sub Form_Load()
    Set SCM = mnuShortCut
    End Sub

    Private Sub Text1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Button = 2 Then
    Text1.Enabled = False
    Text1.Enabled = True
    PopupMenu SCM
    End If
    End Sub

    NOTE : you can do it only in mouse down event not the mouse up .

  13. #13
    Join Date
    Apr 2002
    Location
    Egypt
    Posts
    2,210

    Re: How to disable default popup menu

    Quote Originally Posted by RajWolf
    Hello friends, I am a new guy, I saw all the solutions here, but, i wanted a easy way to do it you know easy and tricky.
    Cimperiali already sent a similar solution
    the problem with it is when the user uses SHIFT+F10 or the context menu key
    anyway..Good try and welcome to CG
    Hesham A. Amin
    My blog , Articles


    <a rel=https://twitter.com/HeshamAmin" border="0" /> @HeshamAmin

  14. #14
    Join Date
    Aug 2006
    Location
    Hubli, India
    Posts
    70

    Lightbulb Re: How to disable default popup menu

    Quote Originally Posted by hspc
    Cimperiali already sent a similar solution
    the problem with it is when the user uses SHIFT+F10 or the context menu key
    anyway..Good try and welcome to CG
    Thanks for viewing my reply/post and thanks for letting me know the shift+F10 problem, I would have left that bug in my programme, any way I think I found a solution for that too. Here it goes

    First you must handle the built in key for right click (I don’t know what it is called) it is a special key something like the built in windows logo key …. Ok its ASCII value is 93

    Second you must handle only F10 key don’t consider the Shift key , the F10 key ASCII is 121

    Then there was …..

    Dim SCM As Menu

    Private Sub Form_Load()
    Set SCM = mnuShortCut
    End Sub

    Private Sub Text1_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 121 Or KeyCode = 93 Then
    Text1.Enabled = False
    Text1.Enabled = True
    Text1.SetFocus ' other wise it will go to the next control
    PopupMenu SCM
    End If
    End Sub

    Private Sub Text1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Button = 2 Then
    Text1.Enabled = False
    Text1.Enabled = True
    Text1.SetFocus ' same here also
    PopupMenu SCM
    End If
    End Sub


    Note : It is left to take care of the menu popup position in case of key down.

  15. #15
    Join Date
    Aug 2006
    Location
    Hubli, India
    Posts
    70

    Re: How to disable default popup menu

    Hey pals , nobody replied back how this code works, is it working or is there any new bug in that, please let me know...............

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured