按下一个键最好用SendMessage,用sndkey32.pas无疑会增加程序尺寸。
组合键(超过两个以上)用sndkey32.pas就显出优势来了。
另一种解决方法,下例模拟按下Alt+Down,可参见Delphi SDK的帮助:
; keybd_event( VK_MENU, MapVirtualKey( VK_MENU, 0 ), 0 , 0 ); ; ; // Alt down
; keybd_event( VK_DOWN, MapVirtualKey( VK_DOWN, 0 ), 0 , 0 ); ; ; // down arrow key down
; keybd_event( VK_DOWN, MapVirtualKey( VK_DOWN, 0 ), KEYEVENTF_KEYUP , 0 ); ;// down arrow key up
; keybd_event( VK_MENU, MapVirtualKey( VK_MENU, 0 ), KEYEVENTF_KEYUP , 0 ); ;// Alt key up
让 WIN95 模拟按了一个按键,例如按下 ENTER或者 TAB 键?
PostMessage(Object.Handle, WM_KEYDOWN, VK_TAB, 0);
////////////////////////////////
unit Unit1;
interface
uses
; SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
; Forms, Dialogs, StdCtrls;
type
; TForm1 = class(TForm)
; ; Button1: TButton;
; ; Button2: TButton;
; ; procedure Button1Click(Sender: TObject);
; ; procedure Button2Click(Sender: TObject);
; ; procedure FormKeyPress(Sender: TObject; var Key: Char);
; private
; ; AppInst: THandle;
; ; AppWind: THandle;
; public
; ; { Public declarations }
; end;
var
; Form1: TForm1;
implementation
{$R *.DFM}
uses ShellAPI;
;
procedure SendShift(H: HWnd; Down: Boolean);
var vKey, ScanCode, wParam: Word;
; ; lParam: longint;
begin
; vKey:= $10;
; ScanCode:= MapVirtualKey(vKey, 0);
; wParam:= vKey or ScanCode shl 8;
; lParam:= longint(ScanCode) shl 16 or 1;
; if not(Down) then lParam:= lParam or $C0000000;
; SendMessage(H, WM_KEYDOWN, vKey, lParam);
end;
procedure SendCtrl(H: HWnd; Down: Boolean);
var vKey, ScanCode, wParam: Word;
; ; lParam: longint;
begin
; vKey:= $11;
; ScanCode:= MapVirtualKey(vKey, 0);
; wParam:= vKey or ScanCode shl 8;
; lParam:= longint(ScanCode) shl 16 or 1;
; if not(Down) then lParam:= lParam or $C0000000;
; SendMessage(H, WM_KEYDOWN, vKey, lParam);
end;
procedure SendKey(H: Hwnd; Key: char);
var vKey, ScanCode, wParam: Word;
; ; lParam, ConvKey: longint;
; ; Shift, Ctrl: boolean;
begin
; ConvKey:= OemKeyScan(ord(Key));
; Shift:= (ConvKey and $00020000) <> 0;
; Ctrl:= (ConvKey and $00040000) <> 0;
; ScanCode:= ConvKey and $000000FF or $FF00;
; vKey:= ord(Key);
; wParam:= vKey;
; lParam:= longint(ScanCode) shl 16 or 1;
; if Shift then SendShift(H, true);
; if Ctrl then SendCtrl(H, true);
; SendMessage(H, WM_KEYDOWN, vKey, lParam);
; SendMessage(H, WM_CHAR, vKey, lParam);
; lParam:= lParam or $C0000000;
; SendMessage(H, WM_KEYUP, vKey, lParam);
; if Shift then SendShift(H, false);
; if Ctrl then SendCtrl(H, false);
end;
function EnumFunc(Handle: HWnd; TF: TForm1): Bool; Far;
begin
; TF.AppWind:= 0;
; if GetWindowWord(Handle, GWW_HINSTANCE) = TF.AppInst then
; ; TF.AppWind:= Handle;
; result:= (TF.AppWind = 0);
end;
procedure TForm1.Button1Click(Sender: TObject);
var Text: Array[0..255] of char;
begin
; AppInst:= ShellExecute(Handle, 'open', 'notepad.exe', nil, '', SW_NORMAL);
; EnumWindows(@EnumFunc, longint(self));
; AppWind:= GetWindow(AppWind, GW_CHILD);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
; SendKey(AppWind, 'T');
; SendKey(AppWind, 'e');
; SendKey(AppWind, 's');
; SendKey(AppWind, 't');
end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
; if AppWind <> 0 then SendKey(AppWind, Key);
end;
end.
///////////////////////////////////////////////////////////////////////
Ah,这个嘛......正好在《DELPHI新闻组学习笔记》上看到一篇:
How to send [Alt]+[Down]?--------------发出一个Alt+Down 组合键
Re:
Use the keybd_event API function to fake keyboard events. Note that each
key down event needs a matching key up or you mess up the key state array.
; keybd_event( VK_MENU, MapVirtualKey( VK_MENU, 0 ), 0 , 0 ); ; ; // Alt down
; keybd_event( VK_DOWN, MapVirtualKey( VK_DOWN, 0 ), 0 , 0 ); ; ; // down arrow key down
; keybd_event( VK_DOWN, MapVirtualKey( VK_DOWN, 0 ), KEYEVENTF_KEYUP , 0 ); ;// down arrow key up
; keybd_event( VK_MENU, MapVirtualKey( VK_MENU, 0 ), KEYEVENTF_KEYUP , 0 ); ;// Alt key up
经本人试验,确实可行,另加补充:
Ctrl: VK_CONTROL
SHIFT:VK_SHIFT
TAB: ;VK_TAB
'A': ;byte('A') ; ; ; ; ; ; ; ;(98-6-8 22:28)
/////////////////////////////////////////////////////////////
(*
Converts a string of characters and key names to keyboard events and
passes them to Windows.
Example syntax:
SendKeys('abc123{left}{left}{left}def{end}456{left 6}ghi{end}789', True);
*)
Function SendKeys(SendKeysString : PChar; Wait : Boolean) : Boolean;
type
; WBytes = array[0..pred(SizeOf(Word))] of Byte;
; TSendKey = record
; ; Name : ShortString;
; ; VKey : Byte;
; end;
const
; {Array of keys that SendKeys recognizes.
; If you add to this list, you must be sure to keep it sorted alphabetically
; by Name because a binary search routine is used to scan it.}
; MaxSendKeyRecs = 41;
; SendKeyRecs : array[1..MaxSendKeyRecs] of TSendKey =
; (
; ;(Name:'BKSP'; ; ; ; ; ; ;VKey:VK_BACK),
; ;(Name:'BS'; ; ; ; ; ; ; ;VKey:VK_BACK),
; ;(Name:'BACKSPACE'; ; ; ; VKey:VK_BACK),
; ;(Name:'BREAK'; ; ; ; ; ; VKey:VK_CANCEL),
; ;(Name:'CAPSLOCK'; ; ; ; ;VKey:VK_CAPITAL),
; ;(Name:'CLEAR'; ; ; ; ; ; VKey:VK_CLEAR),
; ;(Name:'DEL'; ; ; ; ; ; ; VKey:VK_DELETE),
; ;(Name:'DELETE'; ; ; ; ; ;VKey:VK_DELETE),
; ;(Name:'DOWN'; ; ; ; ; ; ;VKey:VK_DOWN),
; ;(Name:'END'; ; ; ; ; ; ; VKey:VK_END),
; ;(Name:'ENTER'; ; ; ; ; ; VKey:VK_RETURN),
; ;(Name:'ESC'; ; ; ; ; ; ; VKey:VK_ESCAPE),
; ;(Name:'ESCAPE'; ; ; ; ; ;VKey:VK_ESCAPE),
; ;(Name:'F1'; ; ; ; ; ; ; ;VKey:VK_F1),
; ;(Name:'F10'; ; ; ; ; ; ; VKey:VK_F10),
; ;(Name:'F11'; ; ; ; ; ; ; VKey:VK_F11),
; ;(Name:'F12'; ; ; ; ; ; ; VKey:VK_F12),
; ;(Name:'F13'; ; ; ; ; ; ; VKey:VK_F13),
; ;(Name:'F14'; ; ; ; ; ; ; VKey:VK_F14),
; ;(Name:'F15'; ; ; ; ; ; ; VKey:VK_F15),
; ;(Name:'F16'; ; ; ; ; ; ; VKey:VK_F16),
; ;(Name:'F2'; ; ; ; ; ; ; ;VKey:VK_F2),
; ;(Name:'F3'; ; ; ; ; ; ; ;VKey:VK_F3),
; ;(Name:'F4'; ; ; ; ; ; ; ;VKey:VK_F4),
; ;(Name:'F5'; ; ; ; ; ; ; ;VKey:VK_F5),
; ;(Name:'F6'; ; ; ; ; ; ; ;VKey:VK_F6),
; ;(Name:'F7'; ; ; ; ; ; ; ;VKey:VK_F7),
; ;(Name:'F8'; ; ; ; ; ; ; ;VKey:VK_F8),
; ;(Name:'F9'; ; ; ; ; ; ; ;VKey:VK_F9),
; ;(Name:'HELP'; ; ; ; ; ; ;VKey:VK_HELP),
; ;(Name:'HOME'; ; ; ; ; ; ;VKey:VK_HOME),
; ;(Name:'INS'; ; ; ; ; ; ; VKey:VK_INSERT),
; ;(Name:'LEFT'; ; ; ; ; ; ;VKey:VK_LEFT),
; ;(Name:'NUMLOCK'; ; ; ; ; VKey:VK_NUMLOCK),
; ;(Name:'PGDN'; ; ; ; ; ; ;VKey:VK_NEXT),
; ;(Name:'PGUP'; ; ; ; ; ; ;VKey:VK_PRIOR),
; ;(Name:'PRTSC'; ; ; ; ; ; VKey:VK_PRINT),
; ;(Name:'RIGHT'; ; ; ; ; ; VKey:VK_RIGHT),
; ;(Name:'SCROLLLOCK'; ; ; ;VKey:VK_SCROLL),
; ;(Name:'TAB'; ; ; ; ; ; ; VKey:VK_TAB),
; ;(Name:'UP'; ; ; ; ; ; ; ;VKey:VK_UP)
; );
; {Extra VK constants missing from Delphi's Windows API interface}
; VK_NULL=0;
; VK_SemiColon=186;
; VK_Equal=187;
; VK_Comma=188;
; VK_Minus=189;
; VK_Period=190;
; VK_Slash=191;
; VK_BackQuote=192;
; VK_LeftBracket=219;
; VK_BackSlash=220;
; VK_RightBracket=221;
; VK_Quote=222;
; VK_Last=VK_Quote;
; ExtendedVKeys : set of byte =
; [VK_Up,
; ;VK_Down,
; ;VK_Left,
; ;VK_Right,
; ;VK_Home,
; ;VK_End,
; ;VK_Prior, ;{PgUp}
; ;VK_Next, ; {PgDn}
; ;VK_Insert,
; ;VK_Delete];
const
; INVALIDKEY = $FFFF {Unsigned -1};
; VKKEYSCANSHIFTON = $01;
; VKKEYSCANCTRLON = $02;
; VKKEYSCANALTON = $04;
; UNITNAME = 'SendKeys';
var
; UsingParens, ShiftDown, ControlDown, AltDown, FoundClose : Boolean;
; PosSpace : Byte;
; I, L : Integer;
; NumTimes, MKey : Word;
; KeyString : String[20];
procedure DisplayMessage(Message : PChar);
begin
; MessageBox(0,Message,UNITNAME,0);
end;
function BitSet(BitTable, BitMask : Byte) : Boolean;
begin
; Result:=ByteBool(BitTable and BitMask);
end;
procedure SetBit(var BitTable : Byte; BitMask : Byte);
begin
; BitTable:=BitTable or Bitmask;
end;
Procedure KeyboardEvent(VKey, ScanCode : Byte; Flags : Longint);
var
; KeyboardMsg : TMsg;
begin
; keybd_event(VKey, ScanCode, Flags,0);
; If (Wait) then While (PeekMessage(KeyboardMsg,0,WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) do begin
; ; TranslateMessage(KeyboardMsg);
; ; DispatchMessage(KeyboardMsg);
; end;
end;
Procedure SendKeyDown(VKey: Byte; NumTimes : Word; GenUpMsg : Boolean);
var
; Cnt : Word;
; ScanCode : Byte;
; NumState : Boolean;
; KeyBoardState : TKeyboardState;
begin
; If (VKey=VK_NUMLOCK) then begin
; ; NumState:=ByteBool(GetKeyState(VK_NUMLOCK) and 1);
; ; GetKeyBoardState(KeyBoardState);
; ; If NumState then KeyBoardState[VK_NUMLOCK]:=(KeyBoardState[VK_NUMLOCK] and not 1)
; ; else KeyBoardState[VK_NUMLOCK]:=(KeyBoardState[VK_NUMLOCK] or 1);
; ; SetKeyBoardState(KeyBoardState);
; ; exit;
; end;
; ScanCode:=Lo(MapVirtualKey(VKey,0));
; For Cnt:=1 to NumTimes do
; ; If (VKey in ExtendedVKeys)then begin
; ; ; KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY);
; ; ; If (GenUpMsg) then
; ; ; ; KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP)
; ; end else begin
; ; ; KeyboardEvent(VKey, ScanCode, 0);
; ; ; If (GenUpMsg) then KeyboardEvent(VKey, ScanCode, KEYEVENTF_KEYUP);
; ; end;
end;
Procedure SendKeyUp(VKey: Byte);
var
; ScanCode : Byte;
begin
; ScanCode:=Lo(MapVirtualKey(VKey,0));
; If (VKey in ExtendedVKeys)then
; ; KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY and KEYEVENTF_KEYUP)
; else KeyboardEvent(VKey, ScanCode, KEYEVENTF_KEYUP);
end;
Procedure SendKey(MKey: Word; NumTimes : Word; GenDownMsg : Boolean);
begin
; If (BitSet(Hi(MKey),VKKEYSCANSHIFTON)) then SendKeyDown(VK_SHIFT,1,False);
; If (BitSet(Hi(MKey),VKKEYSCANCTRLON)) then SendKeyDown(VK_CONTROL,1,False);
; If (BitSet(Hi(MKey),VKKEYSCANALTON)) then SendKeyDown(VK_MENU,1,False);
; SendKeyDown(Lo(MKey), NumTimes, GenDownMsg);
; If (BitSet(Hi(MKey),VKKEYSCANSHIFTON)) then SendKeyUp(VK_SHIFT);
; If (BitSet(Hi(MKey),VKKEYSCANCTRLON)) then SendKeyUp(VK_CONTROL);
; If (BitSet(Hi(MKey),VKKEYSCANALTON)) then SendKeyUp(VK_MENU);
end;
{Implements a simple binary search to locate special key name strings}
Function StringToVKey(KeyString : ShortString) : Word;
var
; Found, Collided : Boolean;
; Bottom, Top, Middle : Byte;
begin
; Result:=INVALIDKEY;
; Bottom:=1;
; Top:=MaxSendKeyRecs;
; Found:=false;
; Middle:=(Bottom+Top) div 2;
; Repeat
; ; Collided:=((Bottom=Middle) or (Top=Middle));
; ; If (KeyString=SendKeyRecs[Middle].Name) then begin
; ; ; ;Found:=True;
; ; ; ;Result:=SendKeyRecs[Middle].VKey;
; ; end else begin
; ; ; ;If (KeyString>SendKeyRecs[Middle].Name) then Bottom:=Middle
; ; ; ;else Top:=Middle;
; ; ; ;Middle:=(Succ(Bottom+Top)) div 2;
; ; end;
; Until (Found or Collided);
; If (Result=INVALIDKEY) then DisplayMessage('Invalid Key Name');
end;
procedure PopUpShiftKeys;
begin
; If (not UsingParens) then begin
; ; If ShiftDown then SendKeyUp(VK_SHIFT);
; ; If ControlDown then SendKeyUp(VK_CONTROL);
; ; If AltDown then SendKeyUp(VK_MENU);
; ; ShiftDown:=false;
; ; ControlDown:=false;
; ; AltDown:=false;
; end;
end;
begin
; AllocationSize:=MaxInt;
; Result:=false;
; UsingParens:=false;
; ShiftDown:=false;
; ControlDown:=false;
; AltDown:=false;
; I:=0;
; L:=StrLen(SendKeysString);
; If (L>AllocationSize) then L:=AllocationSize;
; If (L=0) then Exit;
; While (IINVALIDKEY) then begin
; ; ; ; ; ; ; ;SendKey(MKey,1,True);
; ; ; ; ; ; ; ;PopUpShiftKeys;
; ; ; ; ; ; ;end else DisplayMessage('Invalid KeyName');
; ; ; ; ; ; ;Inc(I);
; ; ; ; ; end;
; ; end;
; end;
; Result:=true;
; PopUpShiftKeys;
end;