Sign in to follow this  

SetWindowLong & DWLP_USER

This topic is 4135 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Heya, currently i'm programming an input driver, which residents within a dll and to bypass WM_*Input* messages, i subclass the application window. Therefore i have my very own WinProc function within the input driver. And because my input driver is implemented as a class i need to pass the "this ptr" to the WinProc function to reroute the relevant input data. And that's where i have some trouble getting it to work. The thing is, i can't use the "user data" of the application window, because i don't know if there is allready data stored or not. So i tried something like this to get along with it:
// Resize the extra window bytes, because we wanna store something there ...
::SetClassLongPtr (hWnd, GCL_CBWNDEXTRA, DWLP_USER+12);
long32 ulError = ::GetLastError (); // works fine, no error here

// Subclassing the application window
WNDPROC pOrginalWinProc = reinterpret_cast<WNDPROC> (::SetWindowLongPtr (hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR> (SubclassWinProc)));

::SetWindowLongPtr (hWnd, DWLP_USER, reinterpret_cast<LONG_PTR> (this));
::SetWindowLongPtr (hWnd, DWLP_USER+4, reinterpret_cast<LONG_PTR> (pOrginalWinProc));
ulError = ::GetLastError (); // got a 1413 error (meaning: invalid index)

But this isn't quite working right now ... any ideas how to solve this ? Thanks in advance. Impz0r

Share this post


Link to post
Share on other sites
Hi again,

the problem is that SetClassLongPtr doesn't actually allocate extra memory for the window structure, it only specifies how much should be available.
See the MSDN doc.

In order to allocate additional memory you need to specify the number of bytes in the cbWndExtra member of the WNDCLASS when you register your window class.

Share this post


Link to post
Share on other sites
It isn't clear to me whether or not you own the windows that you're trying to muck with. If you do then you should already know whether or not you've set things up already. If you only need to store a pointer or pointer-sized value then GWLP_USERDATA is the way to go, otherwise you need to set up the "window extra" data as emmanuel described.

If you don't own the window you can't touch either of those. An alternative would be to used SetProp with (say) a stringized GUID for the property name. Of course you could always just keep an external map of HWND's to your own structures as well.

Share this post


Link to post
Share on other sites
Thanks to both of you!

@d_emmanuel

I see, so i can't change the extra data size after the window is allready created. To bad. I guess i need to try something else, like Anon Mike posted.


@Anon Mike

Funny, i tried this approach just before and it works, but its not very "fast". I guess it has something to do with the string lookup. And of course, that i call ::GetProp(...) every time the subclassed WinProc is called. Maybe thats just plain wrong ...

Well, the thing is, i use the driver within my main application (game) and within my editor, but i use an external widget lib therefore and i have no idea if they store something to the user data or not, most likely tho. So i can't use the user data.

Ah and besides, what do you mean with this "external map of HWND's" ?


Impz0r

Share this post


Link to post
Share on other sites
Quote:
Original post by Impz0r
Ah and besides, what do you mean with this "external map of HWND's" ?



typedef std::map<HWND, WindowData*> WindowMap;
WindowMap map;
...
WindowMap::iterator i = map.find(hWnd);
if (i == map.end())
{
p = new WindowData(...);
i = map.insert(WindowMap::value_type(hWnd, p)).first;
}
WindowData * p = i->second;



Or something along those lines. The whole pair based interface to std::map is to wierd for me to remember off the top of my head so I probably have a few details wrong. The point is to keep your window/data mappings in your own data structure rather than trying to stick them on the window itself.

Share this post


Link to post
Share on other sites
Thanks Anon Mike for the explanation!

I see now what you're mean, it's probably a good idea. One thing tho, the map has to be a "global" variable otherwise i can't access it within the WinProc function. Or did i miss something ?


Impz0r

Share this post


Link to post
Share on other sites

This topic is 4135 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this