Responding to AppCommands
Interact with remote controls and additional keys on the keyboard.
The WM_APPCOMMAND message was added to Windows 2000 and ME to provide a mechanism to send the events from extended keys on newer keyboards to applications on the system. Extended keys are things like the back, forward and search button. This tip demonstrates how to intercept events from these keys in a VB application.
Responding to AppCommands
As with other mouse and keyboard messages, the WM_APPCOMMAND message is sent to the input window (which is the currently active control in the foreground window). However, unlike the other messages if the control doesn't explicitly respond to the message it is bubbled up through all parent windows of the active control until either it is processed. Finally, if no processing has occurred the WH_SHELL hook is fired with code HSHELL_APPCOMMAND. If no installed hook consumes this event then finally the system default action associated with the AppCommand (if any) is performed.
This means you can choose to intercept AppCommands in one of two ways: either by installing a WH_SHELL hook or by installing a subclass on the top level window of your application. This tip uses subclassing to intercept App Commands, using the Subclassing and Timer Assistant. For information on how to install a suitable shell hook, refer to the vbAccelerator Hook Library article.
An WM_APPCOMMAND message provides three pieces of information encoded into the lParam parameter of the message:
The code below shows how the WM_APPCOMMAND message is processed. Note that if the event is processed, the code must return true (1) to Windows and consume the message, otherwise it must call the DefWindowProc to ensure the message bubbles up through the other windows and the Shell hook.
Private Property Get ISubclass_MsgResponse() As EMsgResponse ISubclass_MsgResponse = emrConsume End Property Private Function ISubclass_WindowProc( _ ByVal hWnd As Long, ByVal iMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Select Case iMsg Case WM_APPCOMMAND Dim cmd As Long ' app command is the hiword of the message with the ' device details in the highest 4 bits excluded: cmd = (lParam And &HFFF0000) / &H10000 Dim fromDevice As Long ' the device is derived from the highest 4 bits: fromDevice = (lParam And &H70000000) / &H10000 If (lParam And &H80000000) = &H80000000 Then fromDevice = fromDevice Or &H8000& End If Dim keys As Long ' the key details are in the loword: keys = lParam And &HFFFF& Dim processed As Boolean RaiseEvent AppCommand(cmd, fromDevice, keys, processed) If (processed) Then ' tell windows we've used it: ISubclass_WindowProc = 1 Else ' pass on to next handler: ISubclass_WindowProc = CallOldWindowProc(hWnd, iMsg, wParam, lParam) End If End Select End Function
The download includes this code wrapped up in a reusable class called cAppCommand. To use this class in your project, create a WithEvents instance and then call the Attach method passing in the window handle of the top level window of the application. The class then raises AppCommand events whenever one of the AppCommand keys is pressed.
The predefined AppCommands are listed below: