回 帖 发 新 帖 刷新版面

主题:哪位高手能帮我看下这个代码?

我想用一个键盘钩子来记录按键信息,然后在按下对应的键的时候做出反应。。。。。但是很奇怪。。。。。。编译出来的程序一运行就会导致Explorer出现问题。。。。。哪个高手能帮忙看下。。。。。(PS:之前我用的是WH_KEYBOARD_LL做的钩子。。。代码原封没动。。。因为发现这个WH_KEYBOARD_LL是个低级钩子。。。很多地方不能起作用(比如没有管理员权限的时候)就改成了这个WH_KEYBOARD钩子)
unit mine;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, CoolTrayIcon, AAFont, AACtrls,Unit2, Menus;
const LSFW_LOCK=1;
      LSFW_UNLOCK=2;
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Timer1: TTimer;
    AALabel1: TAALabel;
    AALabel2: TAALabel;
    CoolTrayIcon1: TCoolTrayIcon;
    Timer2: TTimer;
    N1: TMenuItem;
    AALinkLabel1: TAALinkLabel;
    AALabel3: TAALabel;
    GroupBox1: TGroupBox;
    AALabel4: TAALabel;
    GroupBox2: TGroupBox;
    CheckBox1: TCheckBox;
    Edit3: TEdit;
    PopManue1: TPopupMenu;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure CoolTrayIcon1Click(Sender: TObject);
    procedure N1Click(Sender: TObject);
    procedure Edit2KeyPress(Sender: TObject; var Key: Char);
    procedure AALinkLabel1Click(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
  private
     ID:cardinal;
    { Private declarations }
  public
    { Public declarations }
  end;
  KBDLLHOOKSTRUCT=record
                       vkCode:DWORD;
                       scanCode:DWORD;
                       flags:DWORD;
                       time:DWORD;
                       dwExtraInfo:ulong;
                  end;
   LPKBDLLHOOKSTRUCT=^KBDLLHOOKSTRUCT;
var
  Form1: TForm1;
  OldHook:HHOOK;
  Hand:THandle;
  i_key:array of longint;
  i_total:longint;
  b_keyread:boolean;
implementation

{$R *.dfm}
var Running:boolean;
const
LLKHF_ALTDOWN=$20;
WH_KEYBOARD_LL= 13;
function KeyHook(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;
var
  keycost:LPKBDLLHOOKSTRUCT;
  myform:TForm1;
  i:longint;
begin
    Result:=1;
    myForm:=Form1;
    if (code < 0) then
     begin
      Result:= CallNextHookEx(OldHook,code, wParam, lParam);
      exit;
     end;
     if (wParam=VK_F9) then begin
     myform.Button1.Click;b_keyread:=false;
     end;
     if (b_keyread)and(wParam<>VK_F9)
     and(wParam<>VK_ESCAPE)and(wParam<>VK_F4) then
      begin
       setlength(i_key,i_total+1);
       i_key[i_total]:=wParam;
       i_total:=i_total+1;
       for i:=0 to length(i_key)-1 do
        myform.Edit3.Text:=myform.Edit3.Text+IntToStr(i_key[i])+' ';
      end;
     if (wParam=27) then
      begin
       myForm.Edit2.Text:='';
       myform.Edit2.Text:='VK_ESCAPE';
       setForegroundWindow(myform.Handle);
       Running:=false;
      end;
     if (wParam=VK_F4)and(not Running) then
      begin
       i_total:=0;
       setlength(i_key,0);
       myform.Edit3.Text:='';
       for i:=0 to length(i_key)-1 do
       myform.Edit3.Text:=myform.Edit3.Text+IntToStr(i_key[i])+' ';
      end;
    Result:=CallNextHookEx(OldHook, code, wParam, lParam);
end;
function mwrite(Parameter:Pointer):integer;
var myForm:TForm1;
    i:longint;
begin
    myForm:=Form1;
//    myform.Edit2.Enabled:=false;
    i:=-1;
    while true do
     begin
      if i_total=0 then
       begin
        setForegroundWindow(Form1.Handle);
//        myform.Edit2.Enabled:=true;
        EndThread(0);
        exit;
       end;
      for i:=0 to i_total do
      begin
      keybd_event(i_key[i],0,0,0);
      keybd_event(i_key[i],0,KEYEVENTF_KEYUP,0);
      sleep(50);
      if not Running then
       begin
//        myform.Edit2.Enabled:=true;
        EndThread(0);
        exit;
       end;
       end;
     end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
   setForegroundWindow(FindWindow(nil,PChar(Edit1.text)));
   ID:=1001;
   Running:=true;
   ID:=BeginThread(nil,0,mwrite,nil,1001,ID);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    b_keyread:=false;
    OldHook:=0;
    OldHook := SetWindowsHookEx(WH_KEYBOARD {WH_KEYBOARD_LL},
       KeyHook, HInstance, 0);
    if (Sender is TButton) then
       TButton(Sender).Enabled:=not (OldHook>0);
    i_total:=0;
    setlength(i_key,0);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
    if OldHook>0 then
     UnhookWindowsHookEx(OldHook);
end;

procedure TForm1.Timer2Timer(Sender: TObject);
var
  Handle:THandle;
  Caption:PAnsiChar;
  ClassName:PAnsiChar;
begin
  Handle := WindowFromPoint(Mouse.CursorPos);
  GetMem(Caption,255);
  GetMem(ClassName,255);
  GetWindowText(Handle,Caption,255);
  GetClassName(Handle,ClassName,255);
  if GetKeyState(VK_MBUTTON)<0 then
  begin
    Edit1.Text := Caption;
//    Edit2.Text := ClassName;
    Hand := Handle;
  end;

end;

procedure TForm1.Button2Click(Sender: TObject);
var i:longint;
begin

end;

procedure TForm1.CoolTrayIcon1Click(Sender: TObject);
begin
    Form1.Visible:=not Form1.Visible;
end;

procedure TForm1.N1Click(Sender: TObject);
begin
    Self.Close;
end;

procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
begin
    setlength(i_key,i_total+1);
//    i_key[i_total]:=key;
//    Edit2.Text:=Edit2.Text+i_key[i_total];
    i_total:=i_total+1;
end;

procedure TForm1.AALinkLabel1Click(Sender: TObject);
begin
    b_keyread:=not b_keyread;
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
    if CheckBox1.Checked then Edit1.ReadOnly:=false
    else Edit1.ReadOnly:=true;
end;

end.

回复列表 (共1个回复)

沙发

原因已找到,键盘钩子问题。。。。。。。只要改到动态链接库就搞定了,看来没有利害的人能帮忙,自己回复自己吧

我来回复

您尚未登录,请登录后再回复。点此登录或注册