【发布时间】:2010-07-01 09:11:36
【问题描述】:
我使用互联网上的源代码创建了一个 GLOBAL 键盘挂钩 DLL。最好的部分是它工作得很好,除了浏览器。
它会拾取浏览器中的每个键,但似乎当浏览器获得焦点时,它会丢失第一个被按下的键。在 IE 和 Firefox 中测试过,似乎两者都一样。
例如,如果我打开 IE 并开始输入 www。 ,我只回来了ww。如果浏览器窗口保持焦点,则不会丢失更多键。一旦浏览器失去焦点并重新获得焦点,第一个键就会再次丢失。
可能是因为只使用 WH_KEYDOWN 而不是 WH_KEYPRESS / WH_KEYUP ?有人能解释一下吗?
谢谢
PS:钩子函数本身如下:向 DLL 发送一个备忘录框和应用程序句柄,DLL 将发送消息和用户消息。
function KeyHookFunc(Code, VirtualKey, KeyStroke: Integer): LRESULT; stdcall;
var
KeyState1: TKeyBoardState;
AryChar: array[0..1] of Char;
Count: Integer;
begin
Result := 0;
if Code = HC_NOREMOVE then Exit;
Result := CallNextHookEx(hKeyHook, Code, VirtualKey, KeyStroke);
{I moved the CallNextHookEx up here but if you want to block
or change any keys then move it back down}
if Code < 0 then
Exit;
if Code = HC_ACTION then
begin
if ((KeyStroke and (1 shl 30)) <> 0) then
if not IsWindow(hMemo) then
begin
{I moved the OpenFileMapping up here so it would not be opened
unless the app the DLL is attatched to gets some Key messages}
hMemFile := OpenFileMapping(FILE_MAP_WRITE, False, 'NetParentMAP');//Global7v9k
PHookRec1 := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0);
if PHookRec1 <> nil then
begin
hMemo := PHookRec1.MemoHnd;
hApp := PHookRec1.AppHnd;
end;
end;
if ((KeyStroke AND (1 shl 31)) = 0) then //if ((KeyStroke and (1 shl 30)) <> 0) then
begin
GetKeyboardState(KeyState1);
Count := ToAscii(VirtualKey, KeyStroke, KeyState1, AryChar, 0);
if Count = 1 then
begin
SendMessage(hMemo, WM_CHAR, Ord(AryChar[0]), 0);
{I included 2 ways to get the Charaters, a Memo Hnadle and
a WM_USER+1678 message to the program}
PostMessage(hApp, WM_USER + 1678, Ord(AryChar[0]), 0);
end;
end;
end;
end;
【问题讨论】:
-
您的代码示例对尝试回答您的代码的人有很大帮助。
-
是的,我知道,问题是我将不得不提出整个项目,因为我不知道问题可能出在哪里。我可以说的是我使用以下设置挂钩: hKeyHook := SetWindowsHookEx(WH_KEYBOARD, KeyHookFunc, hInstance, 0);但我见过一个似乎使用 WH_KEYBOARD_LL 的 C# 项目,这会有所作为吗?
-
至少你可以告诉我们你在互联网上找到的来源。也许这段代码不正确......
标签: delphi keyboard-hook setwindowshookex