Pelles C forum

C language => Windows questions => Topic started by: Stefan Pendl on September 05, 2007, 05:04:57 PM

Title: Creating keyboard hook for 32-bit and 64-bit apps on x64
Post by: Stefan Pendl on September 05, 2007, 05:04:57 PM
Hello,
I use a tool that maps the comma of the German keypad to a period.

On x64 I need one version for 32-bit apps and one version for 64-bit apps, but if both are running, only one will work.
It seems that one keyboard hook corrupts the other.

I would like to check if the window having focus is a 32-bit app (WOW64).
Is the correct way to use the following functions in the listed order?
Title: Re: Creating keyboard hook for 32-bit and 64-bit apps on x64
Post by: TimoVJL on September 05, 2007, 06:26:35 PM
Not for hooking but if register based remapping is enought:
http://support.microsoft.com/kb/Q216893  (http://support.microsoft.com/kb/Q216893)
Title: Re: Creating keyboard hook for 32-bit and 64-bit apps on x64
Post by: Stefan Pendl on September 06, 2007, 05:54:47 PM
Remapping is not an option.

BTW, is there anything I have to set in addition to the standard DLL settings under the project properties, when I use this DLL to create a system wide hook?
Title: Re: Creating keyboard hook for 32-bit and 64-bit apps on x64
Post by: Stefan Pendl on February 18, 2008, 05:07:47 PM
Using the latest release beta, I was able to create a working 32-bit and 64-bit version of this global hook dll.
I am still facing the problem that only the last started hook will take effect, if both, 32-bit and 64-bit, hooks are active.
If only one of the global hooks is active, all is working as expected.

Does anyone see what might be wrong ???

I can't post the whole projects, since I do not have the permission of the owner.
I hope I do not violate his ownership by posting the two pieces.

32-bit hook procedure
Code: [Select]
#define _WIN32_WINNT 0x0501

#include <windows.h>

HHOOK hPunktHook;

typedef BOOL(WINAPI * LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);

LRESULT __declspec(dllexport)
CALLBACK PunktHook(int nCode, WPARAM wParam, LPARAM lParam);
void __declspec(dllexport) DLLInit(HINSTANCE hDLL, BOOL install);

BOOL APIENTRY DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
//...
}

/* Return success */
return TRUE;
}

LRESULT CALLBACK PunktHook(int nCode, WPARAM wParam, LPARAM lParam)
{
LRESULT RetVal;
HWND hwnd;
LPARAM scancode;
DWORD ProcID;
HANDLE hProc;
BOOL bWOW64Proc = FALSE;
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");

if (nCode == HC_ACTION)
{
if (wParam == VK_DECIMAL)
{
// Map comma to point

hwnd = GetFocus();
if (hwnd == NULL)
hwnd = GetForegroundWindow();

/* on 32-bit Windows no 64-bit check needed */
if ( fnIsWow64Process==NULL )
{
bWOW64Proc = TRUE;
}
else
{
/* is process WOW64 */
GetWindowThreadProcessId(hwnd, &ProcID);
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcID);
fnIsWow64Process(hProc, &bWOW64Proc);
CloseHandle(hProc);
}

if (bWOW64Proc == TRUE)
{
// send period instead of comma

RetVal = 1;
return RetVal;
}
}
}

RetVal = CallNextHookEx(hPunktHook, nCode, wParam, lParam);
return RetVal;
}

64-bit hook procedure
Code: [Select]
#define _WIN32_WINNT 0x0501

#include <windows.h>

HHOOK hPunktHook;

LRESULT __declspec(dllexport)
CALLBACK PunktHookX(int nCode, WPARAM wParam, LPARAM lParam);
void __declspec(dllexport) DLLInitX(HINSTANCE hDLL, BOOL install);

BOOL APIENTRY DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
//...
}

/* Return success */
return TRUE;
}

LRESULT CALLBACK PunktHookX(int nCode, WPARAM wParam, LPARAM lParam)
{
LRESULT RetVal;
HWND hwnd;
LPARAM scancode;
DWORD ProcID;
HANDLE hProc;
BOOL bWOW64Proc = TRUE;

if (nCode == HC_ACTION)
{
if (wParam == VK_DECIMAL)
{
// Map comma to period

hwnd = GetFocus();
if (hwnd == NULL)
hwnd = GetForegroundWindow();

/* check if 64-bit process */
GetWindowThreadProcessId(hwnd, &ProcID);
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcID);
IsWow64Process(hProc, &bWOW64Proc);
CloseHandle(hProc);

if (bWOW64Proc == FALSE)
{
// send period instead of comma

RetVal = 1;
return RetVal;
}
}
}

RetVal = CallNextHookEx(hPunktHook, nCode, wParam, lParam);
return RetVal;
}