【发布时间】:2012-03-21 22:43:05
【问题描述】:
在 Delphi XE 应用程序中,我试图设置一个全局挂钩来监视焦点更改。钩子是在 dll 中创建的:
focusHook := SetWindowsHookEx( WH_CBT, @FocusHookProc, HInstance, 0 );
// dwThreadId (the last argument) set to 0 should create a global hook
在同一个 dll 中,我有将消息发布到主机应用程序窗口的钩子程序:
function FocusHookProc( code : integer; wParam: WPARAM; lParam: LPARAM ) : LResult; stdcall;
begin
if ( code < 0 ) then
begin
result := CallNextHookEx( focusHook, code, wParam, lParam );
exit;
end;
result := 0;
if ( code = HCBT_SETFOCUS ) then
begin
if ( hostHWND <> INVALID_HANDLE_VALUE ) then
PostMessage( hostHWND, cFOCUSMSGID, wParam, lParam );
end;
end;
这可行,但主机只接收有关应用程序本身焦点更改的通知。主窗体上有一个备忘录和几个 TButton,在它们之间切换焦点会产生预期的消息。但是,从不报告应用程序本身之外的任何焦点更改。
我想这与将 DLL 的多个实例注入其他进程有关。有一个类似的问题,已接受回复here,但它是针对 C 的,我不太明白如何在 Delphi dll 中做同样的事情(例如设置共享内存的 pragma 语句)。
(这主要是一个概念证明,但我仍然想让它工作。我需要知道在我的应用程序通过点击激活之前哪个窗口处于活动状态,alt+tab,激活热键等问题是,如果使用鼠标或 alt+tab,GetForegroundWindow 总是返回我自己的应用程序的窗口句柄,不管我多早放,比如通过钩子应用程序的主消息队列。所以钩子看起来像唯一可行的解决方案,虽然我不太喜欢这个想法。)
【问题讨论】:
标签: delphi winapi hook setwindowshookex