>这样说好了,,我写了一支 A 程式,A 程式执行时若按 F1 则 run a1.exe
> 按 F2 则 run a2.exe
>
>现在我的 A 程式成被摆到背景去了..不管 User 怎麽按 F1/F2
>我写的 A.exe 就是没法子知道....因为我没有控制权了,,
>我猜要拦 Windows95 的 Keyboard Event,类似萤幕保护程式的作法
>..只是不知要怎麽作...
您的问题看来只好挂上 WH_KEYBOARD 这型的 HOOK 才行了, 我试了一
下, 可以用, 目前设定成每次按下 Ctrl+B, 记事本就会被启动. 有时
间的话, 说不定又可以包装一个元件出来, 提供一些诸如OnXXXKeyHit
之类的事件出来....
Delphi 真是太可爱了, 用它来实作 HOOK 竟然如此简单.
大家可以按下列步骤试试看:
1. 将以下的文字剪贴存成 HKTest.DPR
--- Cut Here ---
library HKTest;
uses
HKProc in 'HKProc.pas';
exports
EnableHotKeyHook,
DisableHotKeyHook;
begin
hNextHookProc := 0;
procSaveExit := ExitProc;
ExitProc := @HotKeyHookExit;
end.
--- Cut Here ---
2. 将以下的文字剪贴存成 HKProc.PAS
(Note: HKTest.DPR 与 HKProc.PAS 建议储存在同一个目录)
--- Cut Here ---
unit HKProc;
interface
uses
Windows, Messages;
var
hNextHookProc: HHook;
procSaveExit: Pointer;
function KeyboardHookHandler(iCode: Integer;
wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall; export;
function EnableHotKeyHook: BOOL; export;
function DisableHotKeyHook: BOOL; export;
procedure HotKeyHookExit; far;
implementation
function KeyboardHookHandler(iCode: Integer;
wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall; export;
const
_KeyPressMask = $80000000;
begin
Result := 0;
If iCode < 0 Then
begin
Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);
Exit;
end;
// 侦测 Ctrl + B 组合键
if ((lParam and _KeyPressMask) = 0) and
(GetKeyState(vk_Control) < 0) and (wParam = Ord('B')) then
begin
Result := 1;
WinExec('Notepad.exe', sw_Normal); // 记事本
end;
end;
function EnableHotKeyHook: BOOL; export;
begin
Result := False;
if hNextHookProc <> 0 then Exit;
// 挂上 WH_KEYBOARD 这型的 HOOK, 同时, 传回值必须保留下
// 来, 免得 HOOK 呼叫链结断掉
hNextHookProc := SetWindowsHookEx(WH_KEYBOARD,
KeyboardHookHandler,
HInstance,
0);
Result := hNextHookProc <> 0;
end;
function DisableHotKeyHook: BOOL; export;
begin
if hNextHookProc <> 0 then
begin
UnhookWindowshookEx(hNextHookProc); // 解除 Keyboard Hook
hNextHookProc := 0;
MessageBeep(0);
MessageBeep(0);
end;
Result := hNextHookProc = 0;
end;
procedure HotKeyHookExit;
begin
// 如果忘了解除 HOOK, 自动代理解除的动作
if hNextHookProc <> 0 then DisableHotKeyHook;
ExitProc := procSaveExit;
end;
end.
--- Cut Here ---
3. 启动 Delphi 2.0
4. 开启 HKTest.DPR, 然後 Project | Build All 以产生 HKTest.DLL
5. File | New Application 开启一个新的专案
6. 将此专案 unit1 与 project1 存档, 请注意: 请存到与 HKTest.DLL
相同的目录中.
7. 在 Form1 上安置二个 TButton, 并撰写 OnClick 程式, 同时,
在 implementation 节中宣告 EnableHotKeyHook() 与
DisableHotKeyHook(), 修改後的程式应类似:
...
...
implementation
{$R *.DFM}
function EnableHotKeyHook: BOOL; external 'HKTEST.DLL';
function DisableHotKeyHook: BOOL; external 'HKTEST.DLL';
procedure TForm1.Button1Click(Sender: TObject);
begin
if EnableHotKeyHook then
ShowMessage('HotKey Testing...');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if DisableHotKeyHook then
ShowMessage('HotKey Testing..., DONE!!');
end;
end.
8. 专案再存档一次, 执行.
OK! 执行後, 滑鼠点一下 Button1, 然後, 不管 form1 在不在前景, 极小化
也可以, 按下 Ctrl + B 这个组合键, 记事本就启动了.
regards,
Wolfgang Chien
X-Sender: wolfgang@ms2.hinet.net
Date: Sat, 19 Oct 1996 02:48:32 +0800
To: delphichat@ibmsrv.cc.nthu.edu.tw
From: Wolfgang Chien <wolfgang@ms2.hinet.net>
Subject: Re: [Delphi][Form] 如何拦截 Windows95 的按键 ?
Sender: owner-delphichat@ibmsrv.cc.nthu.edu.tw
Reply-To: delphichat@ibmsrv.cc.nthu.edu.tw
earthian <earthian@ms2.hinet.net> wrote:
>> 您的问题看来只好挂上 WH_KEYBOARD 这型的 HOOK 才行了, 我试了一
>> 下, 可以用, 目前设定成每次按下 Ctrl+B, 记事本就会被启动. 有时
>> 间的话, 说不定又可以包装一个元件出来, 提供一些诸如OnXXXKeyHit
>> 之类的事件出来....
>> Delphi 真是太可爱了, 用它来实作 HOOK 竟然如此简单.
>> 大家可以按下列步骤试试看:
>> 1. 将以下的文字剪贴存成 HKTest.DPR
>> --- Cut Here ---
>> library HKTest;
>> :
>> <Code...Skiped..>
>试了一下..
>如果把 DLL 的程式码一并放到 Project1 里面, 合并成一个 .exe 时,
>当 Focus 不是 Project1 时, 就无法栏到 Hot key...为甚麽呢??
HOOK可分成 task scope 与 system scope 两种, Windows 系统会先呼
叫 task scope 的函式, 然後才呼叫 system scope 的函式; 但如果当
时挂上 task scope hook 的程式不在前景, 则其所属的 task scope
hook 当然没有作用. (不然怎麽叫 task scope 嘛!
)
以您的情形, 如果不是实作成 DLL, 而是将之移入 .exe 的Project中,
那它就从 system scope 变成 task scope 的 hook, 当程式在背景时,
Windows 当然就不理会这个 hook 函式了.
换句话说, system scope 的 HOOK 必须实作成 DLL. 而且, 某些类型
的 HOOK 还必须要求只能以 system scope 的方式挂上去, 像是
WH_JOURNALPLAYBACK, 就是其中一个. 进一步的资讯, 您可以参考Win
SDK Reference. 市面上讲 Windows 程式设计比较深入的我认为应该要
涵盖这个题目.
>
>另外..
>如何 Hook 到 Mouse 同时按下 Left & Right Button..
>或者其中任意两键同时按..
>
上次我举的是 WH_KEYBOARD 这型的例子, 如果要过滤 Mouse Message,
那您可以考虑 WH_MOUSE 或 WH_HARDWARE 型.