0
\$\begingroup\$

In the window procedure message processing function, I have come across a couple of things where I just have no idea what to do apart from declare a class globally so that my window procedure can see it.

Imagine I have a Game class that is created in the window loop function and has a handle to the window passed through into it:

class Game
{
    game( HWND hWnd );
    void Go();
    void ReCalculateViewportOffsets();
}

...// windows stuff and handle to window created
Game theGame( hWnd );
...// windows loop starts
theGame.Go();

Half-way through my game, someone changes the resolution so I need to fire a redraw with new offsets to center my viewport... I would like to call that from my WM_RESIZE handler, but theGame has been declared as a local in my main function rather than a global. Probably a good thing? but how on earth can I get hold of theGame in my windows procedure function without declaring it globally:

case "WM_RESIZE":
    //...
    theGame.ReCalculateViewportOffsets( newWidth, newHeight );
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

There is no need to declare the game instance as a global, fortunately.

Windows allows you to store extra "user data" alongside each window instance you create, and you can subsequently access that data any time you have a handle to that window (which you do in your window procedure).

The functions you'll want to use are SetWindowLongPtr and GetWindowLongPtr. These functions retrieve a pointer-sized chunk of data associated with the window -- you'll probably want to use them with the GWLP_USERDATA constant to access the specific pointer-sized chunk of memory reserved by the window system for your use.

If you need to store more than a pointer-sized chunk of data, you can request extra storage bytes during the creation of your window's window class by filling out the cbWndExtra parameter in the class definition structure when you call RegisterClassEx. However, it sounds like GWLP_USERDATA will be sufficient for your needs.

So, in summary:

  • Create your HWND.
  • Use SetWindowLongPtr with GWLP_USERDATA to store a pointer to your Game.
  • User GetWindowLongerPtr to recover that pointer later.

It's also possible to pass a pointer-sized chunk of data to the window when you create it via CreateWindowEx. That pointer-sized chunk of data will be passed to the window procedure via the WM_CREATE message (and that will happen before CreateWindowEx returns), so you can use that to store data with the window as well.

\$\endgroup\$
1
  • \$\begingroup\$ Ah, thank you wise one. I shall try this when I get home from work. That god damn no good son of a class will be accessed by my proc this evening or i'm going to be having stern talks with my nipples. I will no doubt come crawling back to this thread for on-going pestering. Thanks. \$\endgroup\$
    – Jimmyt1988
    Commented May 2, 2013 at 15:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .