Setting WndProc to a class memeber...

Discussion about everything. New games, 3d math, development tips...
Post Reply
RustyNail
Posts: 168
Joined: Fri Jun 02, 2006 1:49 pm
Contact:

Setting WndProc to a class memeber...

Post by RustyNail »

Is it possible?
Supposing I have a windProc() member function...
Can I get a Windows Window to call it, without making it static?
Or if not (which I seem to have just understand is impossible), how would I get a function to modify some objects? Would I have to have a few global variables that store pointers to objects that need to be modified? (Hopefully it is possible without global pointers...) :-/
I have recently discovered that both the Flu and my Algebra teacher have exact the same effect on my health: it quickly degrades.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Can I get a Windows Window to call it, without making it static?
Not directly. A member function has an implicit this pointer, but the WndProc callback signature does not. This will cause problems. To be correct, you have to provide a function with the correct signature and linkage, so you must use a global function at some point. That function can delegate to your object instance. That is closer to what you want, but not perfect.
Or if not, how would I get a function to modify some objects? Would I have to have a few global variables that store pointers to objects that need to be modified?
You can use global or a static member. If you organize your code correctly it isn't so bad. Assuming you only need one window procedure, the following would work.

Code: Select all

class MyClass
{
public:
  MyClass ()
  {
    if (!MyClass::Self)
      MyClass::Self = this;
  }

  ~MyClass ()
  {
    if (MyClass::Self == this)
      MyClass::Self = 0;
  }

  static LRESULT WindowProc (HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  {
    if (MyClass::Self)
      return MyClass::Self->_WindowProc (hWnd, uMessage, wParam, lParam);
    
    return DefWindowProc (hWnd, uMessage, wParam, lParam);
  }

private:
  LRESULT _WindowProc (HWND, UINT, WPARAM, LPARAM);

  // copy and assignment are disallowed
  MyClass (const MyClass&);
  MyClass& operator=(const MyClass&);

private:
  static MyClass* Self;
};

/* static */
MyClass* MyClass::Self = 0;

/* static */ LRESULT
MyClass::_WindowProc (HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
  // you must implement this
}

// this isn't absolutely necessary, but it is correct C++. the reason is that the window
// procedure is supposed to have C linkage, but the static class member function isn't
// is going to use C++ linkage. MSVC doesn't complain, but it isn't legal.
LRESULT CALLBACK MyWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
  return MyClass::WindowProc(hWnd, uMessage, wParam, lParam);
}
You should create a MyClass before you tell windows about MyWindowProc, and that object should live as long as windows is calling MyWindowProc.

The above can be extended a bit to make it more generic, I'm just showing the general idea.

Travis
RustyNail
Posts: 168
Joined: Fri Jun 02, 2006 1:49 pm
Contact:

Post by RustyNail »

That's probably what i'm gonna do.
Thanks! 8)
If only WIN32 could be as smart as X... ><
I have recently discovered that both the Flu and my Algebra teacher have exact the same effect on my health: it quickly degrades.
Post Reply