Holy cow, I wrote a book!
The window manager provides a pointer-sized chunk of storage
you can access via
the GWLP_USERDATA constant.
You pass it to
the GetWindowLongPtr function
the SetWindowLongPtr function
to read and write that value.
Most of the time, all you need to attach to a window is a single
pointer value anyway, so the free memory in
GWLP_USERDATA is all you need.
Note that this value, like the other window extra bytes
the messages in the WM_USER range,
belongs to the window class and not to the
code that creates the window.