Click to See Complete Forum and Search --> : I have a real problem with hooks


snakekain
March 4th, 2005, 06:37 AM
Hi all,
i'm trying to monitor the system for hotkeys like powerstrip it monitors for hotkeys to increase or decrease gamma or whatever while any thing is active the first thing i thought about was hooks so i wrote my hook procedure in a dll setup the hook like this

///code in exe
gkbhookdll = LoadLibrary("kbhook.dll");//load dll
gkeyboardhook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)GetProcAddress(gkbhookdll,"KeyProc"),gkbhookdll,0);

i specified 0 for last parameter to be system wide every thing was ok

///code in dll
LRESULT CALLBACK KeyProc(int nCode,WPARAM wParam,LPARAM lParam)
{
MessageBox(NULL,"called hook","called hook",MB_OK);
return CallNextHookEx(0,nCode,wParam,lParam);
}

now strange problem is that when i activate another window then the hook doesn't work even if i reactivated my window, any one knows what's happening.
does CallNextHookEx returns something that Unhooks my hook?
Thanks for advance and if any one knows a better way for monitoring system for specific hotkeys please tell me, thanks every body again.
and if some body knows how to format parameters returned from the hook with CHotKeyCtrl.GetHotKey is welcome because of the parameter holding wModifiers.
The hook can only give you the code of one button and tell you if alt is pressed. Thanks for the third time.

javitobcn
March 4th, 2005, 06:41 AM
Hello,

How are you? I don't know the reason of your problem. Sorry! I'm a beginner of hook systems!

I work under Windows CE, and I want to ask you, if you know sites web, where I could find examples about hook functions. Ask everybody!

Thanks,

javitobcn

snakekain
March 4th, 2005, 06:46 AM
http://msdn.microsoft.com/library/en-us/dnwui/html/msdn_hooks32.asp

NoHero
March 4th, 2005, 07:36 AM
now strange problem is that when i activate another window then the hook doesn't work even if i reactivated my window, any one knows what's happening.
does CallNextHookEx returns something that Unhooks my hook?
Thanks for advance and if any one knows a better way for monitoring system for specific hotkeys please tell me, thanks every body again.
and if some body knows how to format parameters returned from the hook with CHotKeyCtrl.GetHotKey is welcome because of the parameter holding wModifiers.
The hook can only give you the code of one button and tell you if alt is pressed. Thanks for the third time.

A better way? Well ... I would use RegisterHotkey (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/registerhotkey.asp).

Calling CallNextHookEx is optional, but it is highly recommended; otherwise, other applications that have installed hooks will not receive hook notifications and may behave incorrectly as a result. You should call CallNextHookEx unless you absolutely need to prevent the notification from being seen by other applications.

Well maybe there is a program that doesn't want you to receive hook's.

Martin O
March 4th, 2005, 09:00 AM
Maybe you need to replace this:
LRESULT CALLBACK KeyProc(int nCode,WPARAM wParam,LPARAM lParam)

with this:
__declspec(dllexport) LRESULT CALLBACK KeyProc(int nCode,WPARAM wParam,LPARAM lParam)

But this would be if its not working at all. But you say that the hook works until you switch to another app? You do see the 'called hook' message box at first? If thats so then the __declspec probably isnt the solution.

NoHero
March 4th, 2005, 09:06 AM
Maybe you need to replace this:
LRESULT CALLBACK KeyProc(int nCode,WPARAM wParam,LPARAM lParam)

with this:
__declspec(dllexport) LRESULT CALLBACK KeyProc(int nCode,WPARAM wParam,LPARAM lParam)

But this would be if its not working at all. But you say that the hook works until you switch to another app? You do see the 'called hook' message box at first? If thats so then the __declspec probably isnt the solution.

No, if he uses a definition file (.def extension) he doesn't need the __declspec() export method:


LIBRARY MyHookDll

EXPORTS

KeyProc @1


This will do the same. And I recommend this method if you use LoadLibrary() and GetProcAddress().

Martin O
March 4th, 2005, 09:10 AM
Sorry I was just comparing with my hook code & that was the only difference I saw but now that I think about it that shouldnt matter (your not exporting the hook procedure so you dont need it).

Anyway heres my KeyboardHook dll project. It's pretty simple, use

StarHook(GetCurrentProcessId(), hWindowHandle);
// Tell the hook procedure to send keyboard messages from different processes to this process' hWindowHandle

then call SetHook(true);

and call EndHook() at the end of the program.

NoHero
March 4th, 2005, 09:28 AM
Well, he can also take a look at the following articles:

http://www.codeguru.com/Cpp/W-P/system/keyboard/article.php/c5699/
http://www.codeguru.com/Cpp/W-P/system/misc/article.php/c5685/

snakekain
March 6th, 2005, 09:10 AM
Thank you guys for all those replys, of course i exported the function using the def file, when i read the tutorial from http://www.codeguru.com/Cpp/W-P/system/keyboard/article.php/c5699/ it setup the hook from the dll but i did it from the exe. I looked at RegisterHotKey (thanks to god then to NoHero) which is a more convenient way it worked very well but a small problem exist however that if i set the hot key to Q for example switching to another task pressing Q doesn't work for the current window as if i'm not pressing it but the message box appears at my window that means all apps will not be aple to work properly any help will be appreciated, thanks again for advance.

NoHero
March 6th, 2005, 09:18 AM
Sorry, I do not understand your problem. Would you mind to explain it again, more in detail?

snakekain
March 6th, 2005, 10:10 AM
Thanks nohero here's the problem i use
RegisterHotKey(m_hWnd,1,0,(int)'Q'); to setup the hot key at the start up of the program when i start the program the wm_hotkey message key is sent with the right parameters, if i leave my program open and activate notepad to write something in it if i pressed the hot key 'Q' in this example then nothing happen the notedpad doesn't write any thing may be that means it didn't recieve wm_keydown message that happens for every other window, thanks guys again.

NoHero
March 6th, 2005, 10:46 AM
Thanks nohero here's the problem i use
RegisterHotKey(m_hWnd,1,0,(int)'Q'); to setup the hot key at the start up of the program when i start the program the wm_hotkey message key is sent with the right parameters, if i leave my program open and activate notepad to write something in it if i pressed the hot key 'Q' in this example then nothing happen the notedpad doesn't write any thing may be that means it didn't recieve wm_keydown message that happens for every other window, thanks guys again.

Of course. This is normal behaviour of RegisterHotkey. Just read MSDN:

The RegisterHotKey function defines a system-wide hot key.

If you want the hotkey to only work in your application then you should use Accelerators. This works as followed:


Create a new accelerator resource in the resource editor.
Assign a hotkey to an ID of a button (for example)
Use LoadAccelerators (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardaccelerators/keyboardacceleratorreference/keyboardacceleratorfunctions/loadaccelerators.asp) before the main loop and ...
Use the returned handle in the main loop with TranslateAccelerator (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardaccelerators/keyboardacceleratorreference/keyboardacceleratorfunctions/translateaccelerator.asp) .


This should result in the following code:

[ prototype code ]


MSDN msg = {0};
int Ret = 0;
HACCEL hAccel = NULL;

// Load resource
hAccel = LoadAccelerators(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MYACCELTABLE));

// Assuming that hwnd is the handle to your window
while ( (bRet = GetMessage(&msg, hwnd, 0, 0)) != 0 )
{
if ( bRet == -1 )
{
// error
}
else
{
if ( !TranslateAccelerator(hwnd, hAccel, &msg) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}


If you have any further problems with it, you should post your entire project, so I can help you out directly at the kernel of the problem. If you have any further questions on this, feel free to ask.

snakekain
March 6th, 2005, 10:09 PM
Thank you for your reply, sorry for taking a lot of your time, i need a system-wide hotkey but i don't want it to prevent every other application from recieving the key because that will annoy the user, i want my app in the system tray recieving the hot key messages, while the user works with other apps uninterrupted.

In the example i gave the user will be bothered a lot finding that pressing Q will not write Q in the note pad or any other app while my app is working.

If that'll not work i guess working with system-wide hooks will do because it doesn't prevent other apps from recieving the messages except if i returned 1, and that means i'll have to find a work around to work with the hotkey format returned from CHotKeyCtrl. Thanks again alot, you really helped me out.

JohnCz
March 6th, 2005, 11:15 PM
gkbhookdll = LoadLibrary("kbhook.dll");//load dll
gkeyboardhook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)GetProcAddress(gkbhookdll,"KeyProc"),gkbhookdll,0);Where is your KeyProc?

Your hook works. Providing you start your hook using StartHook.
You are blocking all keystrokes for all windows but one: the one with handle you send when calling StartHook.

If you want to monitor keyboard it is easier by using WH_KEYBOARD_LL. This is always global hook even if procedure is in an exe module.

AS for CHotKeyCtrl you can pass its window handle and use it to translate keyboard input into a code and key value.

SuperKoko
March 7th, 2005, 04:56 AM
Hello.

To create a global hotkey that does not interfere with other applications, you can use DirectInput (it is not so complicated to use, and very powerful).

Or you can call at short-intervals, GetAsyncKeyState (under Windows 98, GetAsyncKeyState retrives asynchronously system-wide key strokes, but i don't know if it works under all windows because GetKeyState does not retrives system-wide key strokes).

NoHero
March 7th, 2005, 01:42 PM
Thank you for your reply, sorry for taking a lot of your time, i need a system-wide hotkey but i don't want it to prevent every other application from recieving the key because that will annoy the user, i want my app in the system tray recieving the hot key messages, while the user works with other apps uninterrupted.

In the example i gave the user will be bothered a lot finding that pressing Q will not write Q in the note pad or any other app while my app is working.

If that'll not work i guess working with system-wide hooks will do because it doesn't prevent other apps from recieving the messages except if i returned 1, and that means i'll have to find a work around to work with the hotkey format returned from CHotKeyCtrl. Thanks again alot, you really helped me out.

Well ... Another possible solution this: Use GetForegroundWindow() (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowfunctions/getforegroundwindow.asp) and send him the WM_KEYDOWN message explicity. After a some days of thinking I haven't found any other workaround for this. :blush: Though I haven't seen any application so far that uses a normal key (like 'Q') as an system wide hotkey. Because such hotkeys are commonly used in combinition with Ctrl, Alt or Shift.

snakekain
March 14th, 2005, 12:32 PM
Thanks very much every body especially NoHero, SuperKoko and JohnCz I finally built up my first product on line you can download it from here
http://www.geocities.com/snakekain/
I had a hyprid solution from you it's to Setup a keyboad_LL hook and check for (alt, ctrl or shift) being down using GetAsyncKeyState inside the hook procedure that way you can format it with the CHotKeyCtrl.GetHotKey, Thanks every body again.