我有一个代码:
int hwnd = IUser32.INSTANCE.FindWindowA(null, "Test");
PointerByReference pid = new PointerByReference();
int threadID = IUser32.INSTANCE.GetWindowThreadProcessId(hwnd, pid);
ForegroundIdleProc proc = new ForegroundIdleProc() {
@Override
public int callback(int code, int wParam, LPARAM lParam) {
/* Handle callback */
/*Make sure you define this function first.*/
return IUser32.INSTANCE.CallNextHookEx(hhk, code, wParam, lParam);
}
};
HOOK hhk = IUser32.INSTANCE.SetWindowsHookExA(IUser32.WH_FOREGROUNDIDLE, proc, null, threadID);
threadId返回正确的线程ID,但SetWindowsHookEx返回null。 我使用GetLastError来了解消息。错误代码:1428 - ERROR_HOOK_NEEDS_HMOD - 无法在没有模块句柄的情况下设置非本地挂钩。
感谢您的帮助。
答案 0 :(得分:2)
根据MSDN关于SetWindowsHookEx
的第3个参数(从1开始计算),在您的情况下为NULL
DLL的句柄,包含指向的钩子过程 lpfn参数。如果是,则必须将hMod参数设置为NULL dwThreadId参数指定当前进程创建的线程 如果钩子程序在与之关联的代码内 当前的过程。
在你的情况下,你的挂钩设置过程(java one)没有创建与'test'窗口关联的应用程序/进程,因此你不能将NULL传递给这个参数,所以你必须提供一个句柄到一些包含钩子程序回调的DLL :(这意味着你应该在本机DLL 中实现这个回调逻辑,加载它(通过JNA使用LoadLibrary)并将返回的句柄传递给{ {1}}