Detect the Keyboard's Right-Click Button

Tuesday Nov 19th 2002 by Sam Huggill

Detect the keyboard's right click button

Many keyboards now support a small key in-between the Atl Gr key and the Windows Key that, when pressed, shows the default context menu for the control that is currently selected.

For example, set the focus on a text box and press the context menu key. See the context menu popup?

While developing my Developers Code Book application, I have context menus on both the treeview and the edit window. I use the context menu key a lot when programming, because I hate having to reach over for the mouse. So naturally, when I wanted to show a context menu on my treeview and edit window by pressing the context key, I had to stop and use the mouse; how irritating! So, I looked around for some way of getting around this problem.

After spending sometime searching the MSDN and other useful sources, I came to the conclusion that I would have to use subclassing. And the message I was looking for? WM_CONTEXTMENU.

I came across this message when doing a previous article, "Replacing the system menu on a form". All you have to do is set up a simple subclassing window procedure, and react to the WM_CONTEXTMENU message.

Once you have received this message, you can call your own procedure that then can call the controls MouseUp event or whatever you want to do to show your context menu. You can apply this code to many controls that don't have a built in context menu, but in this example I have simply used it on a treeview control.

NOTE: If you are planning on subclassing more than one control in the same project, then use a third party control to subclass the control (such as Steve McMahon's Subclassing Control)

OK. Lets get some code down. Start a new Standard EXE Project and add a module. To the form add a treeview control. Rename the module modSubclass and copy the following code into it:

Option Explicit

' Holds a reference to the previous window procedure 
' before we started subclassing 

Public OldProc As Long

Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _ 
(ByVal hWnd As Long, ByVal nIndex As Long, _ ByVal  dwNewLong As Long) As Long

Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _ 
(ByVal hWnd As Long, ByVal nIndex As Long) As Long

Const GWL_WNDPROC = (-4)

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

' The message that we are going to monitor

Public Const WM_CONTEXTMENU = &H7B&

Public Function WndProc(ByVal hWnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long

  ' Handle this message and call our popup routine
  WndProc = 0
  Exit Function 
End If

' Pass on all the other unhandled messages

WndProc = CallWindowProc(OldProc, hWnd, wMsg,wParam, lParam) 

End Function

Now add this code to the form:

Option Explicit

Private Sub Form_Load() 

'Store a reference to the old window procedure 

OldProc = GetWindowLong(TreeView1.hWnd,GWL_WNDPROC) 

'Set our custom window procedure for the treeview 

SetWindowLong TreeView1.hWnd, GWL_WNDPROC, AddressOf WndProc 

End Sub 

Public Sub ShowPopup()
'Carry out your popup menu code here
End Sub

Private Sub Form_Unload(Cancel As Integer)

' Restore the original window procedure

SetWindowLong TreeView1.hWnd, GWL_WNDPROC, OldProc 

End Sub


If you get stuck with this demo then download the source code. Thanks!

Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved