Bypass WM_* Messages ?

Started by
5 comments, last by Impz0r 17 years, 8 months ago
Heya, as the topic sys, i'm looking for a method, to bypass WM_* Messages of a specific window. That means, i've a known window handle and want to listen to a specific WM_* message (in my case WM_CHAR). I allready looked into window hooks, the problem with them is, i can't pass a user data (a pointer to my input driver instance) to the SetWindowsHookEx() function and therefore i can't reroute a hooked message to a class instance. Well my description may sound a litle weird, so heres what i'm trying to achieve: I've a window, which residents within an application, and i've a input driver, which residents within a dll, and i want the input driver to process the applications WM_CHAR messages. Is there another way to achieve this ? Thanks in advance. Impz0r
Stay Evil & Ugly!
Advertisement
Maybe something here will help: Keyboard Input.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
You can't pass a value in SetWindowsHookEx(), but you can create a global lookup table where you map HWND to object pointer. If you create it in TLS, you don't even need to use a lock to find the object when you dispatch.
enum Bool { True, False, FileNotFound };
Assuming the DLL the driver resides in has access to the application's HWND,
you should be able to do this through window subclassing.

The basic idea is to replace the window's message handler with a custom handler
inside of your DLL to process the WM_CHAR message. You can find out more about subclassing here.

[EDIT] You can also associate a pointer to the input driver with the window by using the SetWindowLong function. [/EDIT]
Thanks guys for your replys, especially to d_emmanuel!

Subclass is exactely what i was looking for. One question tho, does subclassing only work within dlls? Because i'm building the input driver for debuggin purpose as a static lib and later if all is working correctly as a dll.

About the SetWindowLong() function. I allready use those to add the application instance ptr to the window the input driver should listen to ... i guess this won't work?

[EDIT]
Ok, i've looked into the SetWindowLong() function and i'm not quite sure how to add an additional pointer to the window internal data (user data). For the application window i use SetWindowLong(GWLP_USERDATA, instance ptr). The question is, what should i use for the input driver? SetWindowLong(GWLP_USER, input driver ptr) ?


Thanks in advance.

Impz0r

[Edited by - Impz0r on August 13, 2006 7:57:00 PM]
Stay Evil & Ugly!
Subclassing can be used in either DLLs or static LIBs.

A HWND can only have a single DWORD of user data associated with it so you won't be able to directly store both the application and input driver pointers using SetWindowLong. There's a couple of ways of working around this though including:

(1) Implement your input driver as a singleton (I'm assuming you only create a single instance) so that you can have global access to it from within your DLL.

(2) Store the instance of the input driver inside of the application. This way you can access it via the application pointer.

Depending on how your system is implemented you may actually want to consider using some hybrid of the two approaches.

Hope this helps.
Thanks d_emmanuel for your help!

I've got it to work, but with another approach. I register the application window with an extra memory size of 16 byte by setting the "cbWndExtra" member of the WNDCLASSEX struct to the needed size. And later, within my input driver i'm using this:

WNDPROC pOrginalWinProc = reinterpret_cast<WNDPROC> (::SetWindowLongPtr (hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR> (MyWinProc))); ::SetWindowLongPtr (hWnd, DWLP_USER, reinterpret_cast<LONG_PTR> (this)); ::SetWindowLongPtr (hWnd, DWLP_USER + 4, reinterpret_cast<LONG_PTR> (pOrginalWinProc));


This actually works, but i'm not quite sure if this is a "valid" way to do it ... hopefully ;)



Impz0r
Stay Evil & Ugly!

This topic is closed to new replies.

Advertisement