怎样检测键盘输入的键?(100分)

  • 主题发起人 主题发起人 cabbagebird
  • 开始时间 开始时间
C

cabbagebird

Unregistered / Unconfirmed
GUEST, unregistred user!
比如说如何检测输入回车。够简单吧。
但是我要所有键的,一般的键我知道。谢谢~~~
 
在windows单元。

{ Virtual Keys, Standard Set }
{$EXTERNALSYM VK_LBUTTON}
VK_LBUTTON = 1;
{$EXTERNALSYM VK_RBUTTON}
VK_RBUTTON = 2;
{$EXTERNALSYM VK_CANCEL}
VK_CANCEL = 3;
{$EXTERNALSYM VK_MBUTTON}
VK_MBUTTON = 4; { NOT contiguous with L & RBUTTON }
{$EXTERNALSYM VK_BACK}
VK_BACK = 8;
{$EXTERNALSYM VK_TAB}
VK_TAB = 9;
{$EXTERNALSYM VK_CLEAR}
VK_CLEAR = 12;
{$EXTERNALSYM VK_RETURN}
VK_RETURN = 13;
{$EXTERNALSYM VK_SHIFT}
VK_SHIFT = $10;
{$EXTERNALSYM VK_CONTROL}
VK_CONTROL = 17;
{$EXTERNALSYM VK_MENU}
VK_MENU = 18;
{$EXTERNALSYM VK_PAUSE}
VK_PAUSE = 19;
{$EXTERNALSYM VK_CAPITAL}
VK_CAPITAL = 20;
{$EXTERNALSYM VK_KANA }
VK_KANA = 21;
{$EXTERNALSYM VK_HANGUL }
VK_HANGUL = 21;
{$EXTERNALSYM VK_JUNJA }
VK_JUNJA = 23;
{$EXTERNALSYM VK_FINAL }
VK_FINAL = 24;
{$EXTERNALSYM VK_HANJA }
VK_HANJA = 25;
{$EXTERNALSYM VK_KANJI }
VK_KANJI = 25;
{$EXTERNALSYM VK_CONVERT }
VK_CONVERT = 28;
{$EXTERNALSYM VK_NONCONVERT }
VK_NONCONVERT = 29;
{$EXTERNALSYM VK_ACCEPT }
VK_ACCEPT = 30;
{$EXTERNALSYM VK_MODECHANGE }
VK_MODECHANGE = 31;
{$EXTERNALSYM VK_ESCAPE}
VK_ESCAPE = 27;
{$EXTERNALSYM VK_SPACE}
VK_SPACE = $20;
{$EXTERNALSYM VK_PRIOR}
VK_PRIOR = 33;
{$EXTERNALSYM VK_NEXT}
VK_NEXT = 34;
{$EXTERNALSYM VK_END}
VK_END = 35;
{$EXTERNALSYM VK_HOME}
VK_HOME = 36;
{$EXTERNALSYM VK_LEFT}
VK_LEFT = 37;
{$EXTERNALSYM VK_UP}
VK_UP = 38;
{$EXTERNALSYM VK_RIGHT}
VK_RIGHT = 39;
{$EXTERNALSYM VK_DOWN}
VK_DOWN = 40;
{$EXTERNALSYM VK_SELECT}
VK_SELECT = 41;
{$EXTERNALSYM VK_PRINT}
VK_PRINT = 42;
{$EXTERNALSYM VK_EXECUTE}
VK_EXECUTE = 43;
{$EXTERNALSYM VK_SNAPSHOT}
VK_SNAPSHOT = 44;
{$EXTERNALSYM VK_INSERT}
VK_INSERT = 45;
{$EXTERNALSYM VK_DELETE}
VK_DELETE = 46;
{$EXTERNALSYM VK_HELP}
VK_HELP = 47;
{ VK_0 thru VK_9 are the same as ASCII '0' thru '9' ($30 - $39) }
{ VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' ($41 - $5A) }
{$EXTERNALSYM VK_LWIN}
VK_LWIN = 91;
{$EXTERNALSYM VK_RWIN}
VK_RWIN = 92;
{$EXTERNALSYM VK_APPS}
VK_APPS = 93;
{$EXTERNALSYM VK_NUMPAD0}
VK_NUMPAD0 = 96;
{$EXTERNALSYM VK_NUMPAD1}
VK_NUMPAD1 = 97;
{$EXTERNALSYM VK_NUMPAD2}
VK_NUMPAD2 = 98;
{$EXTERNALSYM VK_NUMPAD3}
VK_NUMPAD3 = 99;
{$EXTERNALSYM VK_NUMPAD4}
VK_NUMPAD4 = 100;
{$EXTERNALSYM VK_NUMPAD5}
VK_NUMPAD5 = 101;
{$EXTERNALSYM VK_NUMPAD6}
VK_NUMPAD6 = 102;
{$EXTERNALSYM VK_NUMPAD7}
VK_NUMPAD7 = 103;
{$EXTERNALSYM VK_NUMPAD8}
VK_NUMPAD8 = 104;
{$EXTERNALSYM VK_NUMPAD9}
VK_NUMPAD9 = 105;
{$EXTERNALSYM VK_MULTIPLY}
VK_MULTIPLY = 106;
{$EXTERNALSYM VK_ADD}
VK_ADD = 107;
{$EXTERNALSYM VK_SEPARATOR}
VK_SEPARATOR = 108;
{$EXTERNALSYM VK_SUBTRACT}
VK_SUBTRACT = 109;
{$EXTERNALSYM VK_DECIMAL}
VK_DECIMAL = 110;
{$EXTERNALSYM VK_DIVIDE}
VK_DIVIDE = 111;
{$EXTERNALSYM VK_F1}
VK_F1 = 112;
{$EXTERNALSYM VK_F2}
VK_F2 = 113;
{$EXTERNALSYM VK_F3}
VK_F3 = 114;
{$EXTERNALSYM VK_F4}
VK_F4 = 115;
{$EXTERNALSYM VK_F5}
VK_F5 = 116;
{$EXTERNALSYM VK_F6}
VK_F6 = 117;
{$EXTERNALSYM VK_F7}
VK_F7 = 118;
{$EXTERNALSYM VK_F8}
VK_F8 = 119;
{$EXTERNALSYM VK_F9}
VK_F9 = 120;
{$EXTERNALSYM VK_F10}
VK_F10 = 121;
{$EXTERNALSYM VK_F11}
VK_F11 = 122;
{$EXTERNALSYM VK_F12}
VK_F12 = 123;
{$EXTERNALSYM VK_F13}
VK_F13 = 124;
{$EXTERNALSYM VK_F14}
VK_F14 = 125;
{$EXTERNALSYM VK_F15}
VK_F15 = 126;
{$EXTERNALSYM VK_F16}
VK_F16 = 127;
{$EXTERNALSYM VK_F17}
VK_F17 = 128;
{$EXTERNALSYM VK_F18}
VK_F18 = 129;
{$EXTERNALSYM VK_F19}
VK_F19 = 130;
{$EXTERNALSYM VK_F20}
VK_F20 = 131;
{$EXTERNALSYM VK_F21}
VK_F21 = 132;
{$EXTERNALSYM VK_F22}
VK_F22 = 133;
{$EXTERNALSYM VK_F23}
VK_F23 = 134;
{$EXTERNALSYM VK_F24}
VK_F24 = 135;
{$EXTERNALSYM VK_NUMLOCK}
VK_NUMLOCK = 144;
{$EXTERNALSYM VK_SCROLL}
VK_SCROLL = 145;
{ VK_L & VK_R - left and right Alt, Ctrl and Shift virtual keys.
Used only as parameters to GetAsyncKeyState() and GetKeyState().
No other API or message will distinguish left and right keys in this way. }
{$EXTERNALSYM VK_LSHIFT}
VK_LSHIFT = 160;
{$EXTERNALSYM VK_RSHIFT}
VK_RSHIFT = 161;
{$EXTERNALSYM VK_LCONTROL}
VK_LCONTROL = 162;
{$EXTERNALSYM VK_RCONTROL}
VK_RCONTROL = 163;
{$EXTERNALSYM VK_LMENU}
VK_LMENU = 164;
{$EXTERNALSYM VK_RMENU}
VK_RMENU = 165;
{$EXTERNALSYM VK_PROCESSKEY}
VK_PROCESSKEY = 229;
{$EXTERNALSYM VK_ATTN}
VK_ATTN = 246;
{$EXTERNALSYM VK_CRSEL}
VK_CRSEL = 247;
{$EXTERNALSYM VK_EXSEL}
VK_EXSEL = 248;
{$EXTERNALSYM VK_EREOF}
VK_EREOF = 249;
{$EXTERNALSYM VK_PLAY}
VK_PLAY = 250;
{$EXTERNALSYM VK_ZOOM}
VK_ZOOM = 251;
{$EXTERNALSYM VK_NONAME}
VK_NONAME = 252;
{$EXTERNALSYM VK_PA1}
VK_PA1 = 253;
{$EXTERNALSYM VK_OEM_CLEAR}
VK_OEM_CLEAR = 254;
 
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
showmessage(key);
end;
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
showmessage(inttostr(key))
end;
 
看你是要在本程序上使用还是全局的咯?
要是在自己的程序上使用,上面说的方法就可以,要是全局的话建个DLL,做HOOK咯。
 
其实问题是这样的。我用一个DBGrid,希望可以捕捉到用户按上下键输入。
但是好像检测不到上下键。希望能给给例子。
 
这个资料你看看吧
summernightrain(夏夜雨) 
MapVirtualKey是个API函数。关于它的用法可以在 API函数的帮助中查到,我想就不用多说了。
我只是想解释一下,我为什么要这样做的原因好了。

是这样的,我要做一个监视键盘的程序(就是木马中常用的那种功能),我找到了一个自称为不用Hook方法就可以实现拦截键盘的控件,我研究了半天。因为它用来拦截键盘有问题,有顺序错误(这还得了,作为一个木马出这样的错误,不是成了废物??当然我编的不是一个木马了!!呵呵),而且其中一处汇编调用导致了还不用在Win2000使用。所以我决定自己做了。
我开始用DLL,SetWindowsHookEx(WH_KEYBOARD.....)结果不好 ,还要带一个动态连接库,真麻烦,上面的控件(叫KeySpy)就可以不用DLL。后来我发现SetWindowsHookEx(WH_KEYBOARD.....)这个函数不用放在DLL中也可以工作,于是高兴坏了。马上动手,等我编好以后,又发现了一个致命问题焦点不再自己身上的时候就得不到,还不如在窗体中用OnKeyDown呢!!浪费时间!!!(关于这个问题我没有仔细研究,如果那位大侠知道的话,请赐教,就是不用DLL的SetWindowsHookEx(WH_KEYBOARD....也能做键盘监视吗?),
后来我又研究了一个例子,决定利用这例子的原理写一个控件(主要原理代码付后),也是用的SetWindowsHookEx,不过变成了这样的调用SetWindowsHookex(WH_JOURNALRECORD, KeyBoardHook, Hinstance, 0);就是WH_JOURNALRECORD这种类型的钩子,是用来监视系统事件的,而function KeyBoardHook(iCode: Integer; wParam: wParam;
lParam: lParam): LRESULT; stdcall;中 lParam就是事件结构的指针了,哈哈。得到时间结构的指针不久可以判断了吗?
于是就有:
pMsg := pEventMsg(lParam); //pEventMsg是一个自定义的事件结构
if ((pMsg.Message = WM_KEYDOWN) or (pMsg.Message = WM_SYSKEYDOWN)) then
PostMessage(OwnerHandle, WM_KEYSPY, pMsg.paramL, pMsg.paramH)

问题似乎解决了,我长出了一个口气,上面的pMsg.ParamL就是VirtualKey Code虚拟键码,就等于OnKeyDown中的Key那个参数。
得到虚拟键码就好办了,然后我为了监视工作跟加一目了然,当然是把这个键码转换成字符串,比如键码91就得到WIN这个字符串(这个 WIN 让我吃尽苦头,后面会详细解释原因的),27就得到ESC....等等。工作太繁琐,那以前的那个KeySpy来看,哈哈,它定义了长的常量数组,都写好了,照搬过来。成了,这里我说明一下,先开始不知道那段汇编是干吗的,于是照搬。
这段汇编
{asm
in al, 60h
mov Key, al
end; }
实际上是KeySpy用来监视键盘的核心,它用一个Timer去查询当前键盘中的扫描码,就是当前被按下的那些键,而我呢?弄巧成拙了,把它当成将虚拟键码转换成扫描码的过程,当然也可以这么用,因为当时这个键确实被按下了。后来我把KeySpy中的这段汇编给去掉了,改成我的MapVirtualKey函数,看它的定义--MapVirtualKey(虚拟键码,标志):扫描码; 一看就知道返回值是以虚拟键码为前提的。KeySpy一被这样改就变成了DoNothing控件。而我的控件可不是用这原理哦,嘿嘿,因为我在调用MapVirtualKey之前已经得到正确的虚拟键码了!!

关于Win的烦恼篇:
(抱歉,有点灌水嫌疑,请正在看的朋友耐心点),用了SetWindowsHookex(WH_JOURNALRECORD, KeyBoardHook, Hinstance, 0);和MapVirtualKey蛮以为可以高枕无忧乐,98和2000都可以用,哈哈!!完事咯!!我马上编了一个例子来测试它,它工作的非常好。突然,我莫名其妙的按下了WIN键,再按其它的键,发现它已经失效了,就是只要我按下了WIN,这个钩子就不起作用了。我开始查错。。。。调试。。。查错。。。。。(叮叮光光,修理它),还是不行,不论怎样避免都不行,看来是机制问题。没办法查帮助,现在看来帮助真是个好东西啊,打开帮助看WH_JOURNALRECORD这种HOOK的说明,下面引用引起这问题的一段帮助中的原文说明:
If the user presses CTRL+ESC or CTRL+ALT+DEL during journal playback, the system stops the playback, unhooks the journal playback procedure, and posts a WM_CANCELJOURNAL message to the journaling application.
看明白了吧?只要用户按了CTRL+ESC or CTRL+ALT+DEL ,所有的journal playback 都会被UnHook掉,CTRL+ESC =WIN键,气死我了!!!
哎,没办法,看来我在这条路上是死定了。。。。。(后记:这个问题也已经被我解决,不过方法吗,不值得提倡和推广,所以就不拿出来丢丑了)


付的源码:
(请在这方面有经验的朋友一定要无私的奉献一下,共同进步嘛!!)
{*************************************************************}
{ TExKeySpy Component for Delphi 5.0 }
{ Version: 1.0 }
{ Author: Xuxing }
{ ? }
{ E-Mail: www@juzorn.com.cn;ukyo521xu@sina.com }
{ Created: August, 22, 2001 }
{ Modified: August, 22, 2001 }
{ Legal: Copyright (c) 1999 by Xuxing from Wuhan China }
{*************************************************************}
unit ExKeySpy;

interface

uses
{$IFDEF WIN32}Windows, {$ELSE}WinTypes, WinProcs, {$ENDIF}
SysUtils, Controls, Classes, Messages, Forms, Dialogs;
const
WM_KEYSPY = WM_USER + 20;
LowButtonName: array[1..88] of PChar = ('--Esc', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '-', '=', '--BkSp', '--Tab', 'q', 'w', 'e', 'r', 't',
'y', 'u', 'i', 'o', 'p', '[', ']', '--Enter', '--Ctrl', 'a',
's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '''', '`',
'--LShift Down', '/', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',',
'.', '/', '--RShift Down', '--Gray*', '--Alt', '--Space',
'--CapsLock', '--F1', '--F2', '--F3', '--F4', '--F5',
'--F6', '--F7', '--F8', '--F9', '--F10',
'--NumLock', '--ScrollLock', '--Home', '--Up',
'--PgUp', '--Gray-', '--Left', '5', '--Right',
'--Gray+', '--End', '--Down', '--PgDown', '--Ins',
'--Del', '--LShift Up', '--RShift Up',
'--Unknown', '--F11', '--F12');

HiButtonName: array[1..88] of PChar = ('--Esc', '!', '@', '#', '$', '%', '^', '&', '*', '(',
')', '_', '+', '--BkSp', '--Tab', 'Q', 'W', 'E', 'R', 'T',
'Y', 'U', 'I', 'O', 'P', '{', '}', '--Enter', '--Ctrl', 'A',
'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',
'--LShift Down', '¦', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<',
'>', '?', '--RShift Down', '--Gray*', '--Alt', '--Space',
'--CapsLock', '--F1', '--F2', '--F3', '--F4', '--F5',
'--F6', '--F7', '--F8', '--F9', '--F10',
'--NumLock', '--ScrollLock', '--HomeX', '--Up',
'--PgUp', '--Gray-', '--Left', '5', '--Right',
'--Gray+', '--End', '--Down', '--PgDown', '--Ins',
'--Del', '--LShift Up', '--RShift Up',
'--Unknown', '--F11', '--F12');
type
TEventMsg = packed record
Message: UINT;
paramL: UINT;
paramH: UINT;
time: DWORD;
hwnd: HWND;
end;
pEventMsg = ^TEventMsg;
type
TOnGetKey = procedure(Sender: TObject; Key: Byte; KeyStr: string) of object;
TExKeySpy = class(TComponent)
private
FEnabled: Boolean;
FOwnerWin: THandle;
FOnGetKey: TOnGetKey;
FForm: TForm;
FOldFormMethod: TWndMethod;
procedure WM_GETKEY(var Message: TMessage);
procedure Win_Proc(var Message: TMessage);
procedure SetEnabled(Value: Boolean);
{ Private declarations }
protected
{ Protected declarations }
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Active: Boolean read FEnabled write SetEnabled;
{ Public declarations }
published
property OnGetKey: TOnGetKey read FOnGetKey write FOnGetKey;
{ Published declarations }
end;
var
hNextHookProc: hHook;
OwnerHandle: Thandle;
Count: Cardinal;
procedure Register;

implementation

procedure Register;
begin
RegisterComponents('WalkSlowly', [TExKeySpy]);
end;

{ TExKeySpy }

constructor TExKeySpy.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEnabled := False;
FOwnerWin := 0;
FForm := TForm(AOwner);
if FForm <> nil then
begin
FOldFormMethod := FForm.WindowProc;
OwnerHandle := FForm.Handle;
FForm.WindowProc := Win_Proc;
end;
end;

destructor TExKeySpy.Destroy;
begin
inherited Destroy;
if FEnabled then
begin
UnHookWindowsHookEx(hNextHookProc);
hNextHookProc := 0;
end;
end;

function KeyBoardHook(iCode: Integer; wParam: wParam;
lParam: lParam): LRESULT; stdcall;
const _KeyPressMask = $80000000;
var
pMsg: PEventMsg;
recOK: Integer;
begin
recOK := 1;
Result := 0;

if iCode < 0 then
Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam)
else
if iCode = HC_SYSMODALON then
recOK := 0
else
if iCode = HC_SYSMODALOFF then
recOK := 1
else
if ((recOK > 0) and (iCode = HC_ACTION)) then
begin
pMsg := pEventMsg(lParam);
if ((pMsg.Message = WM_KEYDOWN) or (pMsg.Message = WM_SYSKEYDOWN)) then
PostMessage(OwnerHandle, WM_KEYSPY, pMsg.paramL, pMsg.paramH)

end;
end;

procedure DisableKeyHook;
begin
UnHookWindowsHookEx(hNextHookProc);
hNextHookProc := 0;
end;

function EnableKeyHook: Boolean;
begin
Result := False;
if hNextHookProc <> 0 then Exit;
hNextHookProc := SetWindowsHookex(WH_JOURNALRECORD, KeyBoardHook, Hinstance, 0);
Result := hNextHookProc <> 0;
end;

procedure TExKeySpy.SetEnabled(Value: Boolean);
begin
if Value <> FEnabled then
begin
FEnabled := Value;
if FEnabled then
EnableKeyHook
else
DisableKeyHook;
end;
end;

procedure TExKeySpy.Win_Proc(var Message: TMessage);
begin
if (csDesigning in ComponentState) then
FOldFormMethod(Message)
else
case Message.Msg of
WM_KEYSPY: WM_GETKEY(Message);
else
FOldFormMethod(Message);
end;
end;

procedure TExKeySpy.WM_GETKEY(var Message: TMessage);
var
Key, OldKey: Byte;
KeyStr: string;
Point: TPoint;
begin
GetCursorPos(Point);

Key := Message.WParam;
OldKey := Key;

{asm
in al, 60h
mov Key, al //这就是那一段让人头疼了一段时间的汇编
end; }


Key := MapVirtualKey(Key, 0);

if Key = 91 then //处理WIN健
begin
//省略若干字
end;

if Key = 170 then
Key := 84;
if Key = 182 then
Key := 85;
if Key = 250 then
Key := 186;

if Key <= 88 then
begin
if GetKeyState(VK_Shift) < 0 then
KeyStr := StrPas(HiButtonName[Key])
else
KeyStr := StrPas(LowButtonName[Key]);
if (GetKeyState(vk_Capital) = 1) and (Length(KeyStr) = 1) then
KeyStr := UpperCase(KeyStr);
end
else
begin
if (Key - 128 > 0) and (Key - 128 < 88) then
begin
if GetKeyState(VK_Shift) < 0 then
KeyStr := StrPas(HiButtonName[Key - 128])
else
KeyStr := StrPas(LowButtonName[Key - 128]);
if (GetKeyState(vk_Capital) = 1) and (Length(KeyStr) = 1) then
KeyStr := UpperCase(KeyStr);
end;
end;

if (GetKeyState(VK_NUMLOCK) = 1) and (OldKey >= 96) and (OldKey <= 105) then
KeyStr := Inttostr(OldKey - 96);

FOnGetKey(Self, Key, KeyStr);
end;

end.
 
只需要把 chengangsir 代码中的 Edit1KeyDown 改成 DBGrid1KeyDown 就 ok 了赛

别的自己判断就是了
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
EventArr:array[0..1000]of EVENTMSG;
EventLog:Integer;
PlayLog:Integer;
hHook,hPlay:Integer;
bDelay:Bool;

implementation

{$R *.DFM}
Function PlayProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall;
begin
Result:=0;
if iCode < 0 then
Result := CallNextHookEx(hPlay,iCode,wParam,lParam)
else if iCode = HC_SYSMODALON then
// canPlay:=0
else if iCode = HC_SYSMODALOFF then
// canPlay:=1
else if (iCode=HC_GETNEXT) then begin
if bDelay then begin
bDelay:=False;
Result:=50;
end;
pEventMSG(lParam)^:=EventArr[PlayLog];
end
else if (iCode = HC_SKIP)then begin
bDelay := True;
PlayLog:=PlayLog+1;
end;
if PlayLog>=EventLog then begin
UNHookWindowsHookEx(hPlay);
end;
end;

function HookProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall;
begin
// recOK:=1;
Result:=0;
if iCode < 0 then
Result := CallNextHookEx(hHook,iCode,wParam,lParam)
else if iCode = HC_SYSMODALON then
// recOK:=0
else if iCode = HC_SYSMODALOFF then
// recOK:=1
else if (iCode = HC_ACTION) then begin
EventArr[EventLog]:=pEventMSG(lParam)^;
EventLog:=EventLog+1;

if EventLog>=1000 then begin
UnHookWindowsHookEx(hHook);
end;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Button2.Enabled:=False;
Button3.Enabled:=False;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
EventLog:=0;
hHook:=SetwindowsHookEx(WH_JOURNALRECORD,HookProc,HInstance,0);
Button2.Enabled:=True;
Button1.Enabled:=False;
Button3.Enabled:=False;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
PlayLog:=0;
hPlay:=SetwindowsHookEx(WH_JOURNALPLAYBACK,PlayProc,
HInstance,0);
end;

//MapVirtualKey
procedure TForm1.Button2Click(Sender: TObject);
begin
UnHookWindowsHookEx(hHook);
hHook:=0;
Button1.Enabled:=True;
Button2.Enabled:=False;
Button3.Enabled:=True;
end;

end.
 
谢谢个位,你们的方法我会试试的,然后送分。
 

Similar threads

回复
0
查看
827
不得闲
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部