支持多功能键盘和鼠标消息
微软鼠标或Logitech的鼠标,有的时候有很多个键,例如IE4包括前进,后退等键,微软多功能键盘包括一排多出来的键,那么在程序里面如何支持这些鼠标动作或者键盘按键呢?
来自: xn0enfr494zml3006@newsgroups.borland.com
作者: Peter Below(TeamB)
There are two levels at which you can intercept these events. Using
these extra mouse buttons posts WM_XBUTTONDOWN and UP messages to your
active control. You can catch them with a handler for these messages.
The second (and easier) way to do deal with these extra mouse buttons
(and extra keys on multimedia keyboards as well) is to ignore the
low-level messages. The default processing done for them will send a
WM_APPCOMMAND message to the control, and if that does not handle it it
will get forwarded up the parent chain until it reaches the form. This
means you can easily handle this stuff on the form level, by adding a
handler for WM_APPCOMMAND. Here is a bit of code to play with. Note
that in my tests the message did not quite come with the parameters the
SDK help indicates. For me the Flags and Device parts of the message
record were always zero.
type
TWMAppCommand = packed record
Msg: Cardinal;
Wnd: HWND;
Flags: Word;
Cmd : Byte;
Device: Byte;
Result: Longint;
end;
TForm1 = class(TForm)
Memo: TMemo;
private
protected
procedure Display(const S: string); overload;
procedure Display(const Fmt: string; const A: array of const);
overload;
procedure WMAppCommand(var Message: TWMAppCommand); message
WM_APPCOMMAND;
public
end;
var
Form1: TForm1;
implementation
uses Math;
{$R *.dfm}
const
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;
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;
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;
AppCommandStrings : array [APPCOMMAND_BROWSER_BACKWARD ..
APPCOMMAND_MEDIA_CHANNEL_DOWN] of string = (
'APPCOMMAND_BROWSER_BACKWARD',
'APPCOMMAND_BROWSER_FORWARD',
'APPCOMMAND_BROWSER_REFRESH',
'APPCOMMAND_BROWSER_STOP',
'APPCOMMAND_BROWSER_SEARCH',
'APPCOMMAND_BROWSER_FAVORITES',
'APPCOMMAND_BROWSER_HOME',
'APPCOMMAND_VOLUME_MUTE',
'APPCOMMAND_VOLUME_DOWN',
'APPCOMMAND_VOLUME_UP',
'APPCOMMAND_MEDIA_NEXTTRACK',
'APPCOMMAND_MEDIA_PREVIOUSTRACK',
'APPCOMMAND_MEDIA_STOP',
'APPCOMMAND_MEDIA_PLAY_PAUSE',
'APPCOMMAND_LAUNCH_MAIL',
'APPCOMMAND_LAUNCH_MEDIA_SELECT',
'APPCOMMAND_LAUNCH_APP1',
'APPCOMMAND_LAUNCH_APP2',
'APPCOMMAND_BASS_DOWN',
'APPCOMMAND_BASS_BOOST',
'APPCOMMAND_BASS_UP',
'APPCOMMAND_TREBLE_DOWN',
'APPCOMMAND_TREBLE_UP',
'APPCOMMAND_MICROPHONE_VOLUME_MUTE',
'APPCOMMAND_MICROPHONE_VOLUME_DOWN',
'APPCOMMAND_MICROPHONE_VOLUME_UP',
'APPCOMMAND_HELP',
'APPCOMMAND_FIND',
'APPCOMMAND_NEW',
'APPCOMMAND_OPEN',
'APPCOMMAND_CLOSE',
'APPCOMMAND_SAVE',
'APPCOMMAND_PRINT',
'APPCOMMAND_UNDO',
'APPCOMMAND_REDO',
'APPCOMMAND_COPY',
'APPCOMMAND_CUT',
'APPCOMMAND_PASTE',
'APPCOMMAND_REPLY_TO_MAIL',
'APPCOMMAND_FORWARD_MAIL',
'APPCOMMAND_SEND_MAIL',
'APPCOMMAND_SPELL_CHECK',
'APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE',
'APPCOMMAND_MIC_ON_OFF_TOGGLE',
'APPCOMMAND_CORRECTION_LIST',
'APPCOMMAND_MEDIA_PLAY',
'APPCOMMAND_MEDIA_PAUSE',
'APPCOMMAND_MEDIA_RECORD',
'APPCOMMAND_MEDIA_FAST_FORWARD',
'APPCOMMAND_MEDIA_REWIND',
'APPCOMMAND_MEDIA_CHANNEL_UP',
'APPCOMMAND_MEDIA_CHANNEL_DOWN'
);
function DeviceIsMouse(Dev: Byte): Boolean;
begin
Result := (Dev and $80) <> 0;
end;
function DeviceIsKey(Dev: Byte): Boolean;
begin
Result := (Dev and $80) = 0;
end;
function AppCommandToString( Cmd: Word ): String;
begin
if Math.InRange(Cmd, Low(AppCommandStrings), High(AppCommandStrings))
then
Result := AppCommandStrings[Cmd]
else
Result := Format('Unknown appcommand: %u',[Cmd]);
end;
function FlagsToString( Flags: Word ): string;
type
TFlag = record Value: Word; Name: string; end;
const
MK_XBUTTON1 = $0020;
MK_XBUTTON2 = $0040;
AFlags : array [0..6] of TFlag = (
( value: MK_CONTROL; Name: 'CONTROL'),
( value: MK_LBUTTON; Name: 'LBUTTON'),
( value: MK_MBUTTON; Name: 'MBUTTON'),
( value: MK_RBUTTON; Name: 'RBUTTON'),
( value: MK_SHIFT; Name: 'SHIFT'),
( value: MK_XBUTTON1; Name: 'XBUTTON1'),
( value: MK_XBUTTON2; Name: 'XBUTTON2'));
var
Sl: TStringList;
I: Integer;
begin
Sl := TStringList.Create();
try
for I := Low(AFlags) to High(AFLags) do
if (Flags and AFLags[I].Value) = AFlags[I].Value then
Sl.Add(AFlags[I].Name);
Result := Format('[%s]', [sl.Commatext]);
finally
Sl.Free;
end;
end;
procedure TForm1.Display(const S: string);
begin
Memo.Lines.Add(S);
end;
procedure TForm1.Display(const Fmt: string; const A: array of const);
begin
Display(Format(Fmt, A));
end;
procedure TForm1.WMAppCommand(var Message: TWMAppCommand);
begin
/// 如果要继续交给Windows处理,请增加下面一行
// inherited;
Message.Result := 0;
Display('%s, Mouse: %s, Key: %s, Flags: %s',
[AppCommandToString(Message.Cmd),
BoolToStr(DeviceIsMouse(Message.Device), true),
BoolToStr(DeviceIsKey(Message.Device), true),
FlagsToString(Message.Flags)]);
end;