📄 keyboard.htm
字号:
<!-- This document was created with HomeSite v2.0 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<TITLE>UDDF - Keyboard</TITLE>
<META NAME="Description" CONTENT="Keyboard section of the Delphi Developers FAQ" >
<META NAME="KeyWords" CONTENT="" >
</HEAD>
<BODY bgcolor="#FFFFFF">
<CENTER>
<IMG SRC="../images/uddf.jpg"> </CENTER>
<HR SIZE="6" color="#00FF00">
<CENTER><FONT SIZE="7" FACE="Arial Black" COLOR="RED">Keyboard</FONT></CENTER>
<P><H1><A NAME="keyboard0">Beeping when <ENTER> is pressed</P></A></H1>
<P><I>From: "Paul Motyer" <paulm@linuxserver.pccity.com.au></I></P>
<HR><PRE>procedure TForm1.EditKeyPress(Sender: TObject; var Key:Char);
begin
if Key = Chr(VK_RETURN) then
begin
Perform(WM_NEXTDLGCTL,0,0);
key:= #0;
end;
end;
</PRE><HR>
<P><H1><A NAME="keyboard1">Disable alt-tab and ctrl+esc keys</P></A></H1>
<P><I>From: m.weber@public.ndh.com (Meik Weber)</I></P>
<HR><PRE>procedure TurnSysKeysOff;
var
OldVal : LongInt;
begin
SystemParametersInfo (97, Word (True), @OldVal, 0)
end;
procedure TurnSysKeysBackOn;
var
OldVal : LongInt;
begin
SystemParametersInfo (97, Word (False), @OldVal, 0)
end;
</PRE><HR>
<P><H1><A NAME="keyboard2">How to detect arrow keys?</P></A></H1>
<P><I>From: Mark Pritchard <pritchma@ozemail.com.au></I></P>
<P>Use the KeyDown or KeyUp events, and test for VK_LEFT, VK_RIGHT etc.</P>
<P><H1><A NAME="keyboard3">Hooking keyboard</P></A></H1>
<P><I>From: ilcrwfrd@aracnet.com (Iman L. Crawford)</I></P>
<P>I've seen several posts on how to hook the key board. Here's some old code I've dug up (can't remember where It came from).</P>
<HR><PRE>library Sendkey;
{This code taken with permission from "Delphi Developer's Guide"
by Xavier Pacheco and Steve Teixeira.}
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, KeyDefs;
type
{ Error codes }
TSendKeyError = (sk_None, sk_FailSetHook, sk_InvalidToken, sk_UnknownError);
{ exceptions }
ESendKeyError = class(Exception);
ESetHookError = class(ESendKeyError);
EInvalidToken = class(ESendKeyError);
{ a TList descendant that know how to dispose of its contents }
TMessageList = class(TList)
public
destructor Destroy; override;
end;
destructor TMessageList.Destroy;
var
i: longint;
begin
{ deallocate all the message records before discarding the list }
for i := 0 to Count - 1 do
Dispose(PEventMsg(Items[i]));
inherited Destroy;
end;
var
{ variables global to the DLL }
MsgCount: word;
MessageBuffer: TEventMsg;
HookHandle: hHook;
Playing: Boolean;
MessageList: TMessageList;
AltPressed, ControlPressed, ShiftPressed: Boolean;
NextSpecialKey: TKeyString;
function MakeWord(L, H: Byte): Word;
{ macro creates a word from low and high bytes }
inline(
$5A/ { pop dx }
$58/ { pop ax }
$8A/$E2); { mov ah, dl }
procedure StopPlayback;
{ Unhook the hook, and clean up }
begin
{ if Hook is currently active, then unplug it }
if Playing then
UnhookWindowsHookEx(HookHandle);
MessageList.Free;
Playing := False;
end;
function Play(Code: integer; wParam: word; lParam: Longint): Longint; export;
{ This is the JournalPlayback callback function. It is called by Windows }
{ when Windows polls for hardware events. The code parameter indicates what }
{ to do. }
begin
case Code of
hc_Skip: begin
{ hc_Skip means to pull the next message out of our list. If we }
{ are at the end of the list, it's okay to unhook the JournalPlayback }
{ hook from here. }
{ increment message counter }
inc(MsgCount);
{ check to see if all messages have been played }
if MsgCount >= MessageList.Count then
StopPlayback
else
{ copy next message from list into buffer }
MessageBuffer := TEventMsg(MessageList.Items[MsgCount]^);
Result := 0;
end;
hc_GetNext: begin
{ hc_GetNext means to fill the wParam and lParam with the proper }
{ values so that the message can be played back. DO NOT unhook }
{ hook from within here. Return value indicates how much time until }
{ Windows should playback message. We'll return 0 so that it's }
{ processed right away. }
{ move message in buffer to message queue }
PEventMsg(lParam)^ := MessageBuffer;
Result := 0 { process immediately }
end
else
{ if Code isn't hc_Skip or hc_GetNext, then call next hook in chain }
Result := CallNextHookEx(HookHandle, Code, wParam, lParam);
end;
end;
procedure StartPlayback;
{ Initializes globals and sets the hook }
begin
{ grab first message from list and place in buffer in case we }
{ get a hc_GetNext before and hc_Skip }
MessageBuffer := TEventMsg(MessageList.Items[0]^);
{ initialize message count and play indicator }
MsgCount := 0;
{ initialize Alt, Control, and Shift key flags }
AltPressed := False;
ControlPressed := False;
ShiftPressed := False;
{ set the hook! }
HookHandle := SetWindowsHookEx(wh_JournalPlayback, Play, hInstance, 0);
if HookHandle = 0 then
raise ESetHookError.Create('Couldn''t set hook')
else
Playing := True;
end;
procedure MakeMessage(vKey: byte; M: word);
{ procedure builds a TEventMsg record that emulates a keystroke and }
{ adds it to message list }
var
E: PEventMsg;
begin
New(E); { allocate a message record
}
with E^ do begin
Message := M; { set message field }
{ high byte of ParamL is the vk code, low byte is the scan code }
ParamL := MakeWord(vKey, MapVirtualKey(vKey, 0));
ParamH := 1; { repeat count is 1 }
Time := GetTickCount; { set time }
end;
MessageList.Add(E);
end;
procedure KeyDown(vKey: byte);
{ Generates KeyDownMessage }
begin
{ don't generate a "sys" key if the control key is pressed (Windows quirk) }
if (AltPressed and (not ControlPressed) and (vKey in [Ord('A')..Ord('Z')])) or
(vKey = vk_Menu) then
MakeMessage(vKey, wm_SysKeyDown)
else
MakeMessage(vKey, wm_KeyDown);
end;
procedure KeyUp(vKey: byte);
{ Generates KeyUp message }
begin
{ don't generate a "sys" key if the control key is pressed (Windows quirk) }
if AltPressed and (not ControlPressed) and (vKey in [Ord('A')..Ord('Z')]) then
MakeMessage(vKey, wm_SysKeyUp)
else
MakeMessage(vKey, wm_KeyUp);
end;
procedure SimKeyPresses(VKeyCode: Word);
{ This function simulates keypresses for the given key, taking into }
{ account the current state of Alt, Control, and Shift keys }
begin
{ press Alt key if flag has been set }
if AltPressed then
KeyDown(vk_Menu);
{ press Control key if flag has been set }
if ControlPressed then
KeyDown(vk_Control);
{ if shift is pressed, or shifted key and control is not pressed... }
if (((Hi(VKeyCode) and 1) <> 0) and (not ControlPressed)) or ShiftPressed then
KeyDown(vk_Shift); { ...press shift }
KeyDown(Lo(VKeyCode)); { press key down }
KeyUp(Lo(VKeyCode)); { release key }
{ if shift is pressed, or shifted key and control is not pressed... }
if (((Hi(VKeyCode) and 1) <> 0) and (not ControlPressed)) or ShiftPressed then
KeyUp(vk_Shift); { ...release shift }
{ if shift flag is set, reset flag }
if ShiftPressed then begin
ShiftPressed := False;
end;
{ Release Control key if flag has been set, reset flag }
if ControlPressed then begin
KeyUp(vk_Control);
ControlPressed := False;
end;
{ Release Alt key if flag has been set, reset flag }
if AltPressed then begin
KeyUp(vk_Menu);
AltPressed := False;
end;
end;
procedure ProcessKey(S: String);
{ This function parses each character in the string to create the message list }
var
KeyCode: word;
Key: byte;
index: integer;
Token: TKeyString;
begin
index := 1;
repeat
case S[index] of
KeyGroupOpen : begin
{ It's the beginning of a special token! }
Token := '';
inc(index);
while S[index] <> KeyGroupClose do begin
{ add to Token until the end token symbol is encountered }
Token := Token + S[index];
inc(index);
{ check to make sure the token's not too long }
if (Length(Token) = 7) and (S[index] <> KeyGroupClose) then
raise EInvalidToken.Create('No closing brace');
end;
{ look for token in array, Key parameter will }
{ contain vk code if successful }
if not FindKeyInArray(Token, Key) then
raise EInvalidToken.Create('Invalid token');
{ simulate keypress sequence }
SimKeyPresses(MakeWord(Key, 0));
end;
AltKey : begin
{ set Alt flag }
AltPressed := True;
end;
ControlKey : begin
{ set Control flag }
ControlPressed := True;
end;
ShiftKey : begin
{ set Shift flag }
ShiftPressed := True;
end;
else begin
{ A normal character was pressed }
{ convert character into a word where the high byte contains }
{ the shift state and the low byte contains the vk code }
KeyCode := vkKeyScan(MakeWord(Byte(S[index]), 0));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -