Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   Win32 Hooks (http://www.chiefdelphi.com/forums/showthread.php?t=77059)

slavik262 24-04-2009 17:43

Win32 Hooks
 
2 Attachment(s)
For educational purposes/fun I've been messing around with some Windows work. I'm working with hooks (a keyboard hook to be specific), and I want it to work on a global level. According to this MSDN article the hook procedure has to be in a seperate dll. I've done this, and then called SetWindowsHookEx() as instructed here. idHook is set to WH_KEYBOARD, lpfn is set to the pointer to the hook procedure (loaded from the dll using LoadLibrary() and GetProcAddress() ), hMod is the handle to the dll, and dwThreadId is set to 0 (as is required to make the hook global according to the site). However, when I run it (and I've confirmed this using breakpoints), the hook only catches keyboard messages to the window that launched it. It works only on the thread level, and not globally. Any help would be greatly appreciated, as I don't know where I've went wrong. Everything else works perfectly. Attached is the code.

Jared Russell 24-04-2009 17:47

Re: Win32 Hooks
 
It's been a couple years since I've even looked at Win32 code, so I'm not sure how much help I can be, but...

Any reason why you are torturing yourself and not using .NET? Or at least MFC?

slavik262 24-04-2009 21:43

Re: Win32 Hooks
 
Quote:

Originally Posted by Jared341 (Post 854739)
It's been a couple years since I've even looked at Win32 code, so I'm not sure how much help I can be, but...

Any reason why you are torturing yourself and not using .NET? Or at least MFC?

I started in .NET and did a lot with it back in the day. I did some freeware apps online and a lot of people complained about the .NET framework. I wanted to learn native a) for the fun of it, and b) so I could build faster programs.

RyanCahoon 24-04-2009 22:34

Re: Win32 Hooks
 
1 Attachment(s)
I've only done a little with low level hooks, and mostly in C# (see attached). The most blatant thing I noticed when comparing my code to yours is I'm using WH_KEYBOARD_LL and you're using WH_KEYBOARD. Does the behavior change if you use WH_KEYBOARD_LL? (I assume you're not using Win95 or something so you might as well use WH_KEYBOARD_LL)

--Ryan

slavik262 24-04-2009 23:55

Re: Win32 Hooks
 
I'm running Vista. Anyways, WH_KEYBOARD_LL apparently catches messages when "a new keyboard input event is about to be posted into a thread input queue" and WH_KEYBOARD catches messages "whenever an application calls the GetMessage or PeekMessage function and there is a keyboard message (WM_KEYUP or WM_KEYDOWN) to be processed". For my purposes, I thought WH_KEYBOARD would be fine. And according to the MSDN explanation of SetWindowsHookEx(), WH_KEYBOARD should be able to run globally.

EDIT: Using WH_KEYBOARD_LL, the hook works globally. However I cannot do what I wanted to (which is change the keystroke en-route to programs). WH_KEYBOARD_LL passes a pointer to a struct containing they key data (such as key code, etc.) as it's lParam, but i have found that changing the data in the struct does not affect the output (even If I change the keycode the key remains the same). Can't I change the data in the message using the hook?

RyanCahoon 27-04-2009 05:27

Re: Win32 Hooks
 
Quote:

Originally Posted by slavik262 (Post 854864)
WH_KEYBOARD_LL passes a pointer to a struct containing they key data (such as key code, etc.) as it's lParam, but i have found that changing the data in the struct does not affect the output (even If I change the keycode the key remains the same). Can't I change the data in the message using the hook?

You should be able to do this by modifying the vkCode in the lParam struct before calling CallNextHookEx. This function passes on the key on to the next handler in the hook chain, so passing a modified lParam will mean that all handlers that were registered before your (including the default windows handler) will see the modified value. At least that's how it works in theory.

Let me know if that works.

--Ryan

P.S. I'm not sure why WH_KEYBOARD_LL works and WH_KEYBOARD doesn't. I think I remember running into the same issue with mine. Maybe posting to the MSDN forums would shed a bit more light on the subject.

slavik262 29-04-2009 19:26

Re: Win32 Hooks
 
Quote:

Originally Posted by RyanCahoon (Post 855325)
You should be able to do this by modifying the vkCode in the lParam struct before calling CallNextHookEx. This function passes on the key on to the next handler in the hook chain, so passing a modified lParam will mean that all handlers that were registered before your (including the default windows handler) will see the modified value. At least that's how it works in theory.

This was the first thing I tried (with no success). However with the help of some other forums, I have a working solution. After detecting a desired input, I use SendInput() combined with INPUT structures to send my desired inputs. I then return a negative value instead of passing the message along the hook chain. The only thing is that I had to come up with a way so the same inputs being sent using SendInput() weren't processed by the hook, creating a recursive loop. I did this by setting a flag in the extra info of the input, and neglecting any input that came into the hook using that flag.


All times are GMT -5. The time now is 01:09.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi