键盘hook,可以记录到键盘按键,但是如何屏蔽掉打到edit中的字母?(30分)

  • 主题发起人 主题发起人 我爱PASCAL
  • 开始时间 开始时间

我爱PASCAL

Unregistered / Unconfirmed
GUEST, unregistred user!
你的意思是说,让 edit 里打不进字母?
 
不一定是edit,有可能是notepad,word,excel,任何程序中可以输入的地方,
我想让他输入的字母变成另外的再输入,所以要屏蔽掉默认的。
 
先去判断鼠标所在的控件的类名.如果是edit.它的类名就是EDIT或RICHEDIT..最后不让HOOK返回.
 
我初学hook,这是改自别人的代码:
请帮看一下改哪:

unit TestHookKey_Unit;

interface

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

const
WM_HOOKKEY= WM_USER + $1000;
HookDLL = 'Key.dll';
type
THookProcedure=procedure; stdcall;
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
FileMapHandle : THandle;
PMem : ^Integer;
HandleDLL : THandle;
HookOn,
HookOff : THookProcedure;
procedure HookKey(var message: TMessage); message WM_HOOKKEY;

public
{ Public declarations }
end;
var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.ReadOnly:=TRUE;
Memo1.Clear;
HandleDLL:=LoadLibrary( PChar(ExtractFilePath(Application.Exename)+
HookDll) );
if HandleDLL = 0 then raise Exception.Create('未发现键盘钩子DLL');
@HookOn :=GetProcAddress(HandleDLL, 'HookOn');
@HookOff:=GetProcAddress(HandleDLL, 'HookOff');
IF not assigned(HookOn) or
not assigned(HookOff) then
raise Exception.Create('在给定的 DLL中'+#13+
'未发现所需的函数');

FileMapHandle:=CreateFileMapping( $FFFFFFFF,
nil,
PAGE_READWRITE,
0,
SizeOf(Integer),
'TestHook');

if FileMapHandle=0 then
raise Exception.Create( '创建内存映射文件时出错');
PMem:=MapViewOfFile(FileMapHandle,FILE_MAP_WRITE,0,0,0);
PMem^:=Handle;
HookOn;
end;
procedure TForm1.HookKey(var message: TMessage);
var
KeyName : array[0..100] of char;
Accion, Str : string;
f1, f2, f3: longint;
begin
GetKeyNameText(Message.LParam,@KeyName,100);
Str := String(KeyName);
if not(((Message.lParam shr 31) and 1) = 1) then if not(((Message.lParam shr 30) and 1) = 1) then
begin
Memo1.Lines.text := Memo1.Lines.text + Str;
// 得到当前焦点控减句柄发消息
f1:=GetForegroundWindow;
f2:=GetWindowThreadProcessId(f1,nil);
AttachThreadInput(GetCurrentThreadId,f2,true);
f3:=getfocus;
AttachThreadInput(GetCurrentThreadId,f3,false);
if f3 = 0 then Exit;
SendMessage(f3, $0286,(ord(Str[1]) shl 8) + ord(Str[2]) , 0);
end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
if Assigned(HookOff) then
HookOff;
if HandleDLL<>0 then
FreeLibrary(HandleDLL);
if FileMapHandle<>0 then
begin
UnmapViewOfFile(PMem);
CloseHandle(FileMapHandle);
end;

end;

end.
 
这是dll中的代码:
unit HookKey_Unit;

interface
uses windows,messages;
const
WM_HOOKKEY = WM_USER + $1000;
procedure HookOn; stdcall;
procedure HookOff; stdcall;
implementation
var
HookDeTeclado : HHook;
FileMapHandle : THandle;
PViewInteger : ^Integer;

function CallBackDelHook( Code : Integer;
wParam : WPARAM;
lParam : LPARAM
) : LRESULT; stdcall;

begin
if code=HC_ACTION then
begin
FileMapHandle:=OpenFileMapping(FILE_MAP_READ,False,'TestHook');
if FileMapHandle<>0 then
begin
PViewInteger:=MapViewOfFile(FileMapHandle,FILE_MAP_READ,0,0,0);
PostMessage(PViewInteger^,WM_HOOKKEY,wParam,lParam);
UnmapViewOfFile(PViewInteger);
CloseHandle(FileMapHandle);
end;
end;
Result := CallNextHookEx(HookDeTeclado, Code, wParam, lParam)
end;

procedure HookOn; stdcall;
begin
HookDeTeclado:=SetWindowsHookEx(WH_KEYBOARD, CallBackDelHook, HInstance , 0);
end;

procedure HookOff; stdcall;
begin
UnhookWindowsHookEx(HookDeTeclado);
end;


end.
麻烦看一下,谢谢
 
鄙人自费建了一个QQ群 ,号码:22037366 请大家申请加入,唯一的要求是不要谈论Delphi以外的东西,我们的目标是将Delphi进行到底
 
停下来,听课,并且收藏。。
 
没事干!来看看!
 
你的代码不看了,把原理说一下:

若ncode>=0 then
begin
if (lparam=按下)and (wparam=你的特定键值 )
then
begin
模拟按下;
模拟弹起;
result:=1;
end else if (lparam=弹起)and (wparam=你的特定键值 )
then result:=1
else result:=0;
end else//ncode<0
result:=calllNextHookEx(.....


注意:hook中的模拟信息会再次进入hook,故类似于用Z去模拟一个ctrl+Z 还需细致处理,不然会类似死循环。
 
谢谢楼上提供的讲解,但是本人初学hook,已懂得你说的大意了,谢谢!
 

Similar threads

回复
0
查看
999
不得闲
D
回复
0
查看
952
DelphiTeacher的专栏
D
D
回复
0
查看
889
DelphiTeacher的专栏
D
后退
顶部