I''ve never used DLL''s before and don''t really know what I''m doing, but anyway...
I downloaded some code for implementing a keyboard hook - I want to catch keypresses even when my app is not the active one.
Heres a bit of it:
#pragma data_seg("SharedBlock")
HHOOK hHook = NULL;
int nProcesses = 0;
int nKeyPresses = 0;
#pragma data_seg()
HINSTANCE g_hInstance = NULL;
_declspec(dllexport) LRESULT CALLBACK KBHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode < 0)
return CallNextHookEx(hHook, nCode, wParam, lParam);
if(lParam & (1 << 31))
nKeyPresses++;
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
The DLL also exported a function to return the number of keypresses. Now I want to change this so that an application defined function is called when the F2 key is pressed. I exported a function SetCallbackFunc(LPCallback pFunc) that the app could use to specify the function it wanted to be called on an F2 press through a function pointer, and changed the above bit of code to do so.
However, it doesnt work when my app isn''t active - it still reaches the code above, but calling the function pointer seems to do nothing. I assume this is some problem related to address spaces, but I dont know.
Anyone able to tell me what I need to do?
Thanks
Cameron
If you mean what is it that I actually want to capture the F2 press for, I need to start a thread which begins data logging from some special hardware, or stop the data logging if its in progress. If you''re asking what it does at the moment in my testing, I just pass the address of the following function as the callback:
void Action() { Beep(800, 500); }
The callback definitely isn''t being called, since if I put a call to Beep directly in the DLL code, it works as expected.
Why not just have the code directly in the dll then? Is there some reason you need to call it thru a function pointer?
You could also monitor for F2 in your dll and when you get it, send a user defined window message to your program (your dll will need to have a handle to your main window. You could either write a seperate function to do this or pass it thru your SetKBHook function). You can then catch that message in your event loop and do whatever you need to.
/*=========================================*/ /* Chem0sh */ /* Lead Software Engineer & Tech Support */ /* http://www.eFaces.biz */ /*=========================================*/
Because then the DLL code would need to know all about the libraries I''m using for the hardware, and it would get messy. The idea was to have the DLL as generic as possible - just providing the functionality for an app to set up a hook and have a callback when a particular key was pressed.
As for the windows message, I guess I could do that, but speed is reaally important here, so I''d rather not send it through the message system.
Any other ideas why the function pointer call might not work?
My guess is the problem is to do with the pointer getting passed to the DLL which may be in a different address space (?) and so it is unable to call the function. Seems strange that simply nothing happens though. This is the case though, since if the call to Beep near the top of the above code is uncommented, then I do get a beep, whether my app is active or not.
Which hook are you setting? Are you setting the hook on your own thread? If yes, then it''s possible that your thread just never get keyboard messages and hence the hook will never be called. If no, is your callback located in the .exe? If yes, then I''m surprised your program hasn''t crashed yet since the callback doesn''t exist in other program''s address space.
In any event, what prevents you from using RegisterHotKey instead of messing with keyboard hooks?
sark: the SetCallback code is already posted. From what I understand, data in the shared section has one instance across all attaching processes. So if I want any number of apps to load the DLL and register their own callback function for a keypress, I thought that the callback pointer should NOT be in the shared section?
IndirectX: It''s a system wide WH_KEYBOARD hook, and the callback is a function in an application program which is passed as a function pointer to the DLL. What you''re saying is what I suspected, but as I say it hasn''t crashed. Anyway, there must be some way for an app to pass function pointers to a DLL. How can this be done such that the dll can call the function without address space problems? As for RegisterHotKey, I don''t know how I completely overlooked it. I''ll try it, but I think it won''t work since I really need to synchronize with another program that reacts to a press of F2, and I assume that it probably registered it as a hotkey and so I won''t be able to according to the docs.
quote:Original post by kamrann I really need to synchronize with another program that reacts to a press of F2, and I assume that it probably registered it as a hotkey and so I won''t be able to according to the docs.
So if I understand you correctly, you need to catch F2 but let another program handle it as well?
I''m not sure if keyboard hook will work. Try WH_GETMESSAGE and see if WM_HOTKEY is posted to the target program, if your keyboard hook isn''t called.
Elaborating on the callback idea, I''d say it won''t work. If your hook is called from another program''s address space, the dll in which the hook resides is loaded into the target process, but your callback which is in exe doesn''t exist in target process! I would advise you to use an interprocess syncronization mechanism such as window messages (either PostMessage or SendMessage, but if you''re using SendMessage don''t get stuck for too long in your message handler), events on which your app waits (possibly a dedicated thread, or periodical checks with timeout of zero), or maybe something else. Only the dll in which the hook resides is present in other programs'' address space, so you won''t be able to *directly* execute the code residing in your exe from that dll.
As far as I can tell, the keyboard hook is working fine - it gets called as expected, whether my app is active or not. Its just the callback thats the problem.
As far as this goes, and your other suggestions (I did try using events briefly), I think I need to learn quite a bit more on dlls and IPC. However, I thought since my app (which contains the callback function) called LoadLibrary, it meant the dll was loaded into its address space? But its confusing since the hook procedure is called by the system isn''t it, so what address space would that be in?
Cameron
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
With your permission, GameDev.net uses analytics cookies to understand how people use the platform.
You can accept analytics or continue with necessary cookies only.
Learn more