How to pass arguments to SetWindowsHookEx's callback? (if even possible)
Asked Answered
H

0

9

I'm using SetWindowsHookEx with WH_CALLWNDPROC to catch all WndProc messages - and it works fine. I was wondering if there is a way to store a parameter somewhere where the callback function can read and use it.

I assume that because the callback function is inside the "other" process, there's no connection to the process calling the SetWindowsHookEx, so just storing a value in a static variable wont do any good..

For example:

void Hook(DWORD dwThread, int randomNumber)
{
    MagicallyStore(randomNumber);
    SetWindowsHookEx(WH_CALLWNDPROC, hookProc, GetModuleHandle(L"WNDProcHooks"), dwThread);
    ...
    ...
}

LRESULT CALLBACK hookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    int randomNumber = MagicallyRestore();

    DoSomthing(randomNumber);

    return CallNextHookEx(0, nCode, wParam, lParam);
}

I already thought about having the "MagicallyStore" function write the parameter to a file and reading it once in the "MagicallyRestore" function - but there must be a better way..

Thanks in advance :)

Heraclitean answered 26/5, 2014 at 14:1 Comment(4)
You can use a static variable, and place it in a writable, shared section of your binary. This allows all modules to access the same object. A cleaner solution would be to use memory mapped files for IPC.Lefthander
@IInspectable: I know it's been answered a while back, but that upvoted comment is wrong. Don't use global variables. Otherwise if you have to install more than one of those hooks at the same time you'll get really nasty bugs. I know it's not as simple, but the correct way is to use Thread-Local-Storage. Call TlsAlloc() once per process to get TLS variable index, or if you have a DLL do it from DllMain with DLL_PROCESS_ATTACH. (In case of DLL, make sure to call TlsFree() from DLL_PROCESS_DETACH.) Then to set/get a value call TlsSetValue() and TlsGetValue() on that global TLS variable index.Derbyshire
@c00: Not sure, why you believe that thread local storage would be "the correct way" to share data across threads. Besides, using TLS is way easier than you make it appear, by using the thread_local keyword. But it's just not a solution here.Lefthander
@IInspectable: thread_local keyword is not available in older IDEs. Plus there are issues with it in DLLs with Visual Studio. But, if that is not the concern, then yes, it's a shorter version. What I showed is a lower-level API implementation of the same thing. As for your multi-threaded point, then your're right. I assumed that he is calling it on the same process because of dwThread. Otherwise, he needs an std::map with the keys as thread ID, secured by a mutex. Or, then yes, use a shared memory in a DLL.Derbyshire

© 2022 - 2024 — McMap. All rights reserved.