Hello,
I'm trying to store extra data on a window.
I have search the entire forum, with the GWL_USERDATA keyword, and found like 7 topics about that.
But still some windows crashes, and I dont know why.
I'm trying to subclass a window and store its old pointer with SetWindowLong and GWL_USERDATA, it works fine with some windows, but some crashes.
what could be the problem ?
please I need your help!



WinProc proc hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
invoke GetWindowLong, hwnd, GWL_USERDATA
invoke CallWindowProc, eax, hwnd, uMsg, wParam, lParam
ret
WinProc endp

invoke GetWindowLong, hwnd, GWL_WNDPROC
invoke SetWindowLong, hwnd, GWL_USERDATA, eax
invoke SetWindowLong, hwnd, GWL_WNDPROC, ADDR WinProc


once again it works with some windows :(
Thank you very much
Posted on 2003-03-01 16:23:01 by Jnrz
Well, that's no wonder, since the old procedure might use it. You should store it in your program. Or, if you have more than one use of this hook, let it point to your data structure where you save the data that the other function is going to use. Put it in GWL_USERDATA whenever you call that other function, and update it afterwards, then put your data pointer back in.
Posted on 2003-03-01 17:58:50 by Sephiroth3
Use SetWindowLong with an index in the nIndex parameter instead of one of the pre-defined values. When you register the window class specify 4 bytes of cbClsExtra memory. Then when you use the SetWindowLong you can do this

invoke GetWindowLong, hwnd, GWL_WNDPROC
invoke SetWindowLong, hwnd, 0, eax
invoke SetWindowLong, hwnd, GWL_WNDPROC, ADDR WinProc

This will avoid any problems you might encounter using GWL_USERDATA and also allows you to store multiple procedures by registering the class with sufficient extra memory

Remember that the GetWindowLong and SetWindowLong functions use negative numbers to specify a predefined window parameter 0 to Number of extra bytes for user data. This would be the safer way to store data that you want to follow the window. Note that this does not work if you are using dialogs and not windows.

Donkey
Posted on 2003-03-01 20:34:34 by donkey
Hello people
Thanks for replying :)

Donkey:
It's not my window, that is why I cant specify 4 bytes of cbClsExtra memory.
but you know what :)
putting 0 on the nIndex parameter worked.



WinProc proc hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
invoke GetWindowLong, hwnd, 0
invoke CallWindowProc, eax, hwnd, uMsg, wParam, lParam
ret
WinProc endp

invoke GetWindowLong, hwnd, GWL_WNDPROC
invoke SetWindowLong, hwnd, 0, eax
invoke SetWindowLong, hwnd, GWL_WNDPROC, ADDR WinProc


Thank you :)
Posted on 2003-03-01 22:45:14 by Jnrz
Your Welcome. I wouldn't count on stability if this isn't your window. The cbClsExtra element of a class structure is defaulted to zero when the class is registered. If you can actually use it you may be writing to a different element of the class structure that just seems to have no effect or the original software would have had to expressly allocated that memory in order to use it. I think that hInstance is the next element in a window class so I doubt that you are overwriting that. That would probably mean that the programmer allocated that memory for a reason and may use it when some combination of events occur. Test your software thoroughly and keep your fingers crossed. The best way is like Sephiroth3 said, to store the old window proc in your program if you have no control over the creation of the window.

Donkey
Posted on 2003-03-02 00:05:46 by donkey
you should also test the result of GetWindowLong, maybe there are cases, where you have not yet written the userdata
(e.g. during WM_NCCREATE or something before WM_CREATE) and get null as data.
Posted on 2003-03-03 04:00:03 by beaster

It's not my window, that is why I cant specify 4 bytes of cbClsExtra memory.
Then you're better off using window properties. That's the third way to attach window specific information. With properties, you won't mess with someone else's use of GWL_USERDATA or cbClsExtra memory. Unlike the other two methods, properties are accessed by name (not position). Look up GetProp and SetProp.
Posted on 2003-03-04 10:51:21 by tenkey