Click here to Skip to main content
15,881,413 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello, I am working on my end-of-college project and I need to make a DLL to hook and remap some keyboard keys before they are send to the focused program. Example: my program runs in back and when I press A in notepad to write B.

I hope someone can help me :D
Thank you very much, Daniel!
Posted
Updated 16-May-10 12:49pm
v2

Try have a look to this page and the related resources, from the MSDN library:

http://msdn.microsoft.com/en-us/library/ms644990(VS.85).aspx[^]

I think that what you need as first step is a low-level keyboard hook (see WH_KEYBOARD_LL) to process keys before that they are dispatched to the active application.

Note that from the installed hook procedure you have only two choices:


    • avoid further processing on the sent key

    • call the next installed hook (this means that your application does nothing on the sent key, and if no more hooks are installed the sent key is dispatched to the active application)



Then to remap some keyboard keys what you should do is something like the following:


    • install your hook procedure

    • from your hook procedure identify the keyboard keys that shouldn't be remapped and let them be processed by calling CallNextHookEx

    • avoid processing of keyboard keys that should be remapped and send a WM_CHAR message with the remapped key code to the active application

 
Share this answer
 
Comments
doanwon 10-Jun-10 0:31am    
I tried the hook procedure and post a message to the hook handler. But the KBDLLHOOKSTRUCT that is supposed to be passed via LPARAM cannot be accessed. How would I get to this struct in your hook handler? The LPARAM is supposed to contain the struct info but I sizeof(l) = 4 so there is not much info. Casting l to a defined struct did not work. Would appreciate answer. Thanks.
Sauro Viti 10-Jun-10 2:17am    
Via LPARAM is passed not the struct, but a pointer to the struct
doanwon 10-Jun-10 7:42am    
No, I casted lparam to KBDLLSTRUCT pointer inside the hook handler but it returned garbage. However, casting the lparam inside the dll did work and I was able to access the vkCode to pass as the lparam or wParam (ULONG both). However, I cannot stop the program from processing the input key instead of letting my hook handler do perform this task. I tried PeekMessage to remove the message from queue but the program crashes--perhaps the message has not been placed onto queue.

I am using the Keyexe and Keydll program. The Keydll is compiled under VS2008 and Keyexe under VC++6 because I've added some stuff and was not able to compile under 2008--perhaps this is the problem. I am resorting use WH_CALLWNDPROC but I dont have a clue how to check what's in the struct (lparam). Everything I've tried crashed. With all due respect, Sauro, you are just reading the library and explaining to us--you have not tried to run the program. But I appreciate any recommendation.
Sauro Viti 10-Jun-10 9:42am    
// This install the hook procedure (I suppose you are calling it from an MFC exe application)
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, &LowLevelKeyboardProc, theApp.m_hInstance, 0);

// This is my hook procedure (it uses the KBDLLHOOKSTRUCT and it works properly...)
LRESULT CALLBACK LowLevelKeyboardProc(INT iCode, WPARAM wParam, LPARAM lParam)
{
if (iCode == HC_ACTION) {
KBDLLHOOKSTRUCT* pkbhs = (KBDLLHOOKSTRUCT *)lParam;
BOOL bCtrl = GetAsyncKeyState(VK_CONTROL) >> (8 * sizeof(SHORT) - 1);
BOOL bShift = GetAsyncKeyState(VK_SHIFT) >> (8 * sizeof(SHORT) - 1);

if (pkbhs->vkCode == VK_ESCAPE && pkbhs->flags & LLKHF_ALTDOWN) return 1;
else if (pkbhs->vkCode == VK_TAB && pkbhs->flags & LLKHF_ALTDOWN) return 1;
else if (pkbhs->vkCode == VK_ESCAPE && bCtrl) return 1;
else if (pkbhs->vkCode == VK_LWIN) return 1;
else if (pkbhs->vkCode == VK_RWIN) return 1;
else if (pkbhs->vkCode>=VK_BROWSER_BACK && pkbhs->vkCode<=VK_LAUNCH_APP2) return 1;
}

return CallNextHookEx(hHook, iCode, wParam, lParam);
}
doanwon 10-Jun-10 12:27pm    
Thanks for taking the time. This is similar to what I have been trying, but the foreground app still processed all the incomming keystrokes. I added:
else if (pkbhs->vkCode == 41) return 1; //A
else if (pkbhs->vkCode == 31) return 1; //1
and WordPad still printed those chars out.

VC++6 did not recognize the WH_KEYBOARD_LL flag. But the above code is all in the DLL, which was compiled by VS2008 so it should not have mattered. Someone should report this to MS. I will have to resort to PeekMessage--even this does not work will KEYBOARD_LL.

Thanks again for your time.
Hello everybody I have too same problem. I'm going to finish my bachelor work and i have to track the registry key work then used to use same logic in Process of OS.

Please somebody help me to get this type of code for my project. I have a few time. To think and finish it. You will be thankful for this job. Actually it's being difficult to find all of change in process of OS. But i have to get it and compare the result with timeinterval result.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900