首页
社区
课程
招聘
[求助]请教一个利用WINIO记录键盘的问题
发表于: 2008-5-22 16:44 6377

[求助]请教一个利用WINIO记录键盘的问题

2008-5-22 16:44
6377
本意是想利用WINIO记录和模拟键盘的输入,但在记录的时候连鼠标的输入都记下了。。请问怎样才可以只记录键盘的输入?readKey()这个函数是用来记录的
function readKey():Integer;
var
    valKey : Byte;
begin  
asm
    //应该在这里加上判断,只是完全不会汇编所以请各位指点一下,不胜感激
    in al, $60
    mov valKey,al
    @loop:   
end;
SetKey(0);
Result := valKey;
end;

以下是全部代码,都是网上例子来    :)
unit temp;

interface

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

type
  TForm3 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
VK_LBUTTON = $1;
VK_RBUTTON = $2;
VK_CANCEL = $3;
VK_MBUTTON = $4;
VK_BACK = $8;
VK_TAB = $9;
VK_CLEAR = $C;
VK_RETURN = $D;
VK_SHIFT = $10;
VK_CONTROL = $11;
VK_MENU = $12;
VK_PAUSE = $13;
VK_CAPITAL = $14;
VK_ESCAPE = $1B;
VK_SPACE = $20;
VK_PRIOR = $21;
VK_NEXT = $22;
VK_END = $23;
VK_HOME = $24;
VK_LEFT = $25;
VK_UP = $26;
VK_RIGHT = $27;
VK_DOWN = $28;
VK_Select = $29;
VK_PRINT = $2A;
VK_EXECUTE = $2B;
VK_SNAPSHOT = $2C;
VK_Insert = $2D;
VK_Delete = $2E;
VK_HELP = $2F;
VK_0 = $30;
VK_1 = $31;
VK_2 = $32;
VK_3 = $33;
VK_4 = $34;
VK_5 = $35;
VK_6 = $36;
VK_7 = $37;
VK_8 = $38;
VK_9 = $39;
VK_A = $41;
VK_B = $42;
VK_C = $43;
VK_D = $44;
VK_E = $45;
VK_F = $46;
VK_G = $47;
VK_H = $48;
VK_I = $49;
VK_J = $4A;
VK_K = $4B;
VK_L = $4C;
VK_M = $4D;
VK_N = $4E;
VK_O = $4F;
VK_P = $50;
VK_Q = $51;
VK_R = $52;
VK_S = $53;
VK_T = $54;
VK_U = $55;
VK_V = $56;
VK_W = $57;
VK_X = $58;
VK_Y = $59;
VK_Z = $5A;
VK_STARTKEY = $5B;
VK_CONTEXTKEY = $5D;
VK_NUMPAD0 = $60;
VK_NUMPAD1 = $61;
VK_NUMPAD2 = $62;
VK_NUMPAD3 = $63;
VK_NUMPAD4 = $64;
VK_NUMPAD5 = $65;
VK_NUMPAD6 = $66;
VK_NUMPAD7 = $67;
VK_NUMPAD8 = $68;
VK_NUMPAD9 = $69;
VK_MULTIPLY = $6A;
VK_ADD = $6B;
VK_SEPARATOR = $6C;
VK_SUBTRACT = $6D;
VK_DECIMAL = $6E;
VK_DIVIDE = $6F;
VK_F1 = $70;
VK_F2 = $71;
VK_F3 = $72;
VK_F4 = $73;
VK_F5 = $74;
VK_F6 = $75;
VK_F7 = $76;
VK_F8 = $77;
VK_F9 = $78;
VK_F10 = $79;
VK_F11 = $7A;
VK_F12 = $7B;
VK_F13 = $7C;
VK_F14 = $7D;
VK_F15 = $7E;
VK_F16 = $7F;
VK_F17 = $80;
VK_F18 = $81;
VK_F19 = $82;
VK_F20 = $83;
VK_F21 = $84;
VK_F22 = $85;
VK_F23 = $86;
VK_F24 = $87;
VK_NUMLOCK = $90;
VK_OEM_SCROLL = $91;
VK_OEM_1 = $BA;
VK_OEM_PLUS = $BB;
VK_OEM_COMMA = $BC;
VK_OEM_MINUS = $BD;
VK_OEM_PERIOD = $BE;
VK_OEM_2 = $BF;
VK_OEM_3 = $C0;
VK_OEM_4 = $DB;
VK_OEM_5 = $DC;
VK_OEM_6 = $DD;
VK_OEM_7 = $DE;
VK_OEM_8 = $DF;
VK_ICO_F17 = $E0;
VK_ICO_F18 = $E1;
VK_OEM102 = $E2;
VK_ICO_HELP = $E3;
VK_ICO_00 = $E4;
VK_ICO_CLEAR = $E6;
VK_OEM_RESET = $E9;
VK_OEM_JUMP = $EA;
VK_OEM_PA1 = $EB;
VK_OEM_PA2 = $EC;
VK_OEM_PA3 = $ED;
VK_OEM_WSCTRL = $EE;
VK_OEM_CUSEL = $EF;
VK_OEM_ATTN = $F0;
VK_OEM_FINNISH = $F1;
VK_OEM_COPY = $F2;
VK_OEM_AUTO = $F3;
VK_OEM_ENLW = $F4;
VK_OEM_BACKTAB = $F5;
VK_ATTN = $F6;
VK_CRSEL = $F7;
VK_EXSEL = $F8;
VK_EREOF = $F9;
VK_PLAY = $FA;
VK_ZOOM = $FB;
VK_NONAME = $FC;
VK_PA1 = $FD;
VK_OEM_CLEAR = $FE;

var
  Form3: TForm3;

implementation

{$R *.dfm}

function InitializeWinIo:Boolean;stdcall;external 'WinIo.dll' name'InitializeWinIo';
function InstallWinIoDriver(pszWinIoDriverPath:PString;IsDemandLoaded:boolean=false):Boolean;stdcall;external 'WinIo.dll' name 'InstallWinIoDriver';
function RemoveWinIoDriver:Boolean;stdcall;external 'WinIo.dll' name 'RemoveWinIoDriver';
function GetPortVal(PortAddr:Word;PortVal:PDWord;bSize:Byte):Boolean;stdcall;external 'WinIo.dll' name 'GetPortVal';
function SetPortVal(PortAddr:Word;PortVal:DWord;bSize:Byte):Boolean;stdcall;external 'WinIo.dll' name 'SetPortVal';
function GetPhysLong(PhysAddr:PByte;PhysVal:PDWord):Boolean;stdcall;external 'WinIo.dll' name 'GetPhysLong';
function SetPhysLong(PhysAddr:PByte;PhysVal:DWord):Boolean;stdcall;external 'WinIo.dll' name 'SetPhysLong';
function MapPhysToLin(PhysAddr:PByte;PhysSize:DWord;PhysMemHandle:PHandle):PByte;stdcall;external 'WinIo.dll' name 'MapPhysToLin';
function UnMapPhysicalMemory(PhysMemHandle:THandle;LinAddr:PByte):Boolean;stdcall;external 'WinIo.dll' name 'UnmapPhysicalMemory';
procedure ShutdownWinIo;stdcall;external 'WinIo.dll' name'ShutdownWinIo';

procedure KBCWait4IBE; //等待键盘缓冲区为空
var
  dwVal:DWord;
begin
  repeat
    GetPortVal($64,@dwVal,1);
  until (dwVal and $2)=0;
end;

procedure MyKeyDown(vKeyCoad:Integer);
var
  btScancode:DWord;
begin
  btScancode:=MapVirtualKey(vKeyCoad, 0);
  KBCWait4IBE;
  if SetPortVal($64, $D2, 2) then
  begin
        form3.Memo1.lines.add('down = a');
  end;
  KBCWait4IBE;
  SetPortVal($60, btScancode, 2);
end;

procedure MyKeyUp(vKeyCoad:Integer);
var
  btScancode:DWord;
begin
  btScancode:=MapVirtualKey(vKeyCoad, 0);
  KBCWait4IBE;

  if SetPortVal($64, $D2, 2) then
  begin

    form3.memo1.lines.add('up = b');
  end;
  KBCWait4IBE;
  SetPortVal($60, (btScancode or $80), 2);
end;

procedure SetKey(SCanCode: byte);
begin
asm
//无论向0x60,还是0x64写东西前都要等状态寄存器OBF变0
@Loop1:
in al, $64
and al, 10b
jnz @Loop1
//向$64端口写命令
// mov al, 0xD2//写键盘输出缓存命令
mov al, $D2//写鼠标输出缓存命令
out $64, al

//无论向0x60,还是0x64写东西前都要等状态寄存器OBF变0
@Loop2:
in al, $64
and al, 10b
jnz @Loop2
//向$60端口写参数
mov al, SCanCode
out $60, al
end;
end;

//自己写的
function readKey():Integer;
var
    valKey : Byte;
begin  
asm
    //应该在这里加上判断,只是完全不会汇编所以请各位指点一下,不胜感激
    in al, $60
    mov valKey,al
    @loop:   
end;
SetKey(0);
Result := valKey;
end;

procedure TForm3.Button1Click(Sender: TObject);
begin

    if not InitializeWinIo then begin
    Messagebox(handle,'初始化失败!','提示',MB_OK+MB_IconError)
  end;
  TButton(Sender).Enabled := False;
end;

procedure TForm3.Button2Click(Sender: TObject);
begin
    Timer1.Enabled := not Timer1.Enabled;
end;

procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    ShutdownWinIo;
end;

procedure TForm3.Timer1Timer(Sender: TObject);
var
  vkeyCode : Integer;
  keyData : Byte;
begin
    keyData := readKey();
    vkeyCode := MapVirtualKey(keyData,1);  
    if vkeyCode > 0 then
    begin
        Form3.Memo1.Lines.Add(Char(vkeyCode));
    end;
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
    Timer1.Enabled := False;
    Timer1.Interval := 60;
    Memo1.Lines.Clear;
end;

end.

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 231
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
问题太简单,高手门都耻于回答吧?
2008-5-23 10:10
0
雪    币: 33
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
楼主..WINIO 怎么 发送 鼠标消息的?
2008-5-25 02:36
0
雪    币: 231
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
mov al, $D2//写鼠标输出缓存命令
2008-5-27 11:30
0
游客
登录 | 注册 方可回帖
返回
//