views:

303

answers:

1

If a mouse has other buttons in addition to the standard left/right/middle (e.g. forward/back), how can we detect those button clicks in Delphi?

An example of how this is used is the Internet Explorer, where the forward/back button on the side of a Logitech or MS mouse cycles forward and back between any loaded web pages. This seems to replicate the Backspace/CTRL+Backspace on the keyboard but I tried to detect that using KeyPreview and the KeyPress event but it does not pick it up.

Any idea how to detect clicks on these extended mouse buttons?

+8  A: 

You need to capture the WM_APPCOMMAND message and then extract the specific command request using GET_APPCOMMAND_LPARAM. Basically, something like this:

type
  TMyForm = class(TForm)
  private
    procedure WMAppCommand(var Msg: TMessage); message WM_APPCOMMAND;
  end;

procedure TMyForm.WMAppCommand(var Msg: TMessage);
begin
  case GET_APPCOMMAND_LPARAM(Msg.LParam) of
    APPCOMMAND_BROWSER_BACKWARD:
    begin
      // Do "go back" code
      Msg.Result := 1;
    end;
  end;
end;

Here's the relevant header translation:

unit AppCommand;

{$RANGECHECKS OFF}

interface

uses
  Windows;

const
  WM_APPCOMMAND = $0319;

const
  // Windows 2000, ME, and above
  APPCOMMAND_BROWSER_BACKWARD                   = 1;
  APPCOMMAND_BROWSER_FORWARD                    = 2;
  APPCOMMAND_BROWSER_REFRESH                    = 3;
  APPCOMMAND_BROWSER_STOP                       = 4;
  APPCOMMAND_BROWSER_SEARCH                     = 5;
  APPCOMMAND_BROWSER_FAVORITES                  = 6;
  APPCOMMAND_BROWSER_HOME                       = 7;
  APPCOMMAND_VOLUME_MUTE                        = 8;
  APPCOMMAND_VOLUME_DOWN                        = 9;
  APPCOMMAND_VOLUME_UP                          = 10;
  APPCOMMAND_MEDIA_NEXTTRACK                    = 11;
  APPCOMMAND_MEDIA_PREVIOUSTRACK                = 12;
  APPCOMMAND_MEDIA_STOP                         = 13;
  APPCOMMAND_MEDIA_PLAY_PAUSE                   = 14;
  APPCOMMAND_LAUNCH_MAIL                        = 15;
  APPCOMMAND_LAUNCH_MEDIA_SELECT                = 16;
  APPCOMMAND_LAUNCH_APP1                        = 17;
  APPCOMMAND_LAUNCH_APP2                        = 18;
  APPCOMMAND_BASS_DOWN                          = 19;
  APPCOMMAND_BASS_BOOST                         = 20;
  APPCOMMAND_BASS_UP                            = 21;
  APPCOMMAND_TREBLE_DOWN                        = 22;
  APPCOMMAND_TREBLE_UP                          = 23;
  // Windows XP and above
  APPCOMMAND_MICROPHONE_VOLUME_MUTE             = 24;
  APPCOMMAND_MICROPHONE_VOLUME_DOWN             = 25;
  APPCOMMAND_MICROPHONE_VOLUME_UP               = 26;
  APPCOMMAND_HELP                               = 27;
  APPCOMMAND_FIND                               = 28;
  APPCOMMAND_NEW                                = 29;
  APPCOMMAND_OPEN                               = 30;
  APPCOMMAND_CLOSE                              = 31;
  APPCOMMAND_SAVE                               = 32;
  APPCOMMAND_PRINT                              = 33;
  APPCOMMAND_UNDO                               = 34;
  APPCOMMAND_REDO                               = 35;
  APPCOMMAND_COPY                               = 36;
  APPCOMMAND_CUT                                = 37;
  APPCOMMAND_PASTE                              = 38;
  APPCOMMAND_REPLY_TO_MAIL                      = 39;
  APPCOMMAND_FORWARD_MAIL                       = 40;
  APPCOMMAND_SEND_MAIL                          = 41;
  APPCOMMAND_SPELL_CHECK                        = 42;
  APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE  = 43;
  APPCOMMAND_MIC_ON_OFF_TOGGLE                  = 44;
  APPCOMMAND_CORRECTION_LIST                    = 45;
  // Windows XP SP1 and above
  APPCOMMAND_MEDIA_PLAY                         = 46;
  APPCOMMAND_MEDIA_PAUSE                        = 47;
  APPCOMMAND_MEDIA_RECORD                       = 48;
  APPCOMMAND_MEDIA_FAST_FORWARD                 = 49;
  APPCOMMAND_MEDIA_REWIND                       = 50;
  APPCOMMAND_MEDIA_CHANNEL_UP                   = 51;
  APPCOMMAND_MEDIA_CHANNEL_DOWN                 = 52;

  FAPPCOMMAND_MOUSE = $8000;
  FAPPCOMMAND_KEY   = 0;
  FAPPCOMMAND_OEM   = $1000;
  FAPPCOMMAND_MASK  = $F000;

  // Mouse buttons;  remaining ones are declared in Windows.pas
  MK_XBUTTON1 = $20;
  MK_XBUTTON2 = $40;

function GET_APPCOMMAND_LPARAM(lParam: LPARAM): Short;
function GET_DEVICE_LPARAM(lParam: LPARAM): Word;
function GET_KEYSTATE_LPARAM(lParam: LPARAM): Word;


implementation

function GET_APPCOMMAND_LPARAM(lParam: LPARAM): Short;
begin
  Result := HiWord(lParam) and not FAPPCOMMAND_MASK;
end;

function GET_DEVICE_LPARAM(lParam: LPARAM): Word;
begin
  Result := HiWord(lParam) and FAPPCOMMAND_MASK;
end;

function GET_KEYSTATE_LPARAM(lParam: LPARAM): Word;
begin
  Result := LoWord(lParam);
end;

end.
Craig Peterson
I assumed you meant GET_APPCOMMAND_LPARAM, thank you!
EagleOfToledo

related questions