I have a code:
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);
The threadId returns a correct thread id but SetWindowsHookEx returns null. I used GetLastError to know the msg. Error code: 1428 - ERROR_HOOK_NEEDS_HMOD - Cannot set nonlocal hook without a module handle.
Thanks for help.
As per MSDN in regard the 3rd parameter of SetWindowsHookEx
(counting from 1) which in your case is NULL
A handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
In your case, your hooking setup process (the java one) didn't created the application/process associated w/ the 'test' window, hence you can't pass NULL to this parameter, so you must provide a handle to some DLL containing the hook procedure callback :( this means you should implement this callback logic in a native DLL, load it (thru JNA usage of LoadLibrary) and pass the returned handle to SetWindowsHookEx