Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Quadratic

global vars, how to avoid them when WndProc can't find them as non-globals?

This topic is 5279 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

I apologize for another global var thread, but i was unable to find an answer using the search feature. I am currently working on my own little 3D modeling tool using C++. Right now I've got three windows for the various views, each with a grid and the ability to zoom/pan the view. I have created a class for these views, with drawGrid(), zoomIn(), zoomOut() and more functions. In this class I store some variables, like position, zoomlevel etc. I want my grid to be redrawn when the window gets a WM_PAINT message, and I want the view to zoom in when some key is pressed. So I process e.g. the WM_PAINT and WM_KEYDOWN messages and call the appropriate functions on my instance of the view class. The "problem" is that I have to make my instances of the view class global, so that WndProc will find them. Globals are bad however, and I want to get rid of as many of them as possible, so what do I do ? I have no idea how I could go about makeing these classes non-global. Will I just have to live with them ? How do YOU solve these kind of problems ? thanks a lot for all help ! [edited by - Quadratic on March 5, 2004 3:14:40 PM]

Share this post


Link to post
Share on other sites
Advertisement
Declare WndProc as a friend to your class and use SetWindowLong(). I think you have to set some field in the window class telling it that you want to have at least 1 element in the window's user data area. Then store a pointer to the class that owns the window using SetWindowLong(), and each time WndProc is called retrieve it using GetWindowLong() and forward the message to the class using the returned value, cast to a pointer to your class type.

This is a little clunky to describe, but relatively neat in practice and means you can use the same window procedure for multiple windows at once.

[edit: oh, I missed the important bit: when you call CreateWindow() you give it a value which is passed to the window proc as the LPARAM of the WM_CREATE message. Pass the address of your object, cast to LPARAM, and then in the WM_CREATE handler cast it back and store it. At least, that's how I've done it in the past]

[edited by - fractoid on March 5, 2004 12:59:41 AM]

Share this post


Link to post
Share on other sites
From my window class:

// In CWindow::Create()...

m_hWnd = CreateWindowEx(0,WINDOW_CLASS_NAME,"Druink IM",WS_OVERLAPPEDWINDOW,x,y,w,h,NULL,NULL,hInstance,this);
if(!m_hWnd)
{
UnregisterClass(WINDOW_CLASS_NAME,hInstance);
m_strError = "Failed to create main window";
return false;
}

// In the static window proc

LRESULT CALLBACK CWindow::StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CWindow* pParent;

pParent = (CWindow*)GetWindowLong(hWnd,GWL_USERDATA);
if(uMsg == WM_CREATE)
{
pParent = (CWindow*)(((CREATESTRUCT*)lParam)->lpCreateParams);
SetWindowLong(hWnd,GWL_USERDATA,(LONG)pParent);
return pParent->WndProc(uMsg,wParam,lParam);
}
else if(!pParent)
return DefWindowProc(hWnd,uMsg,wParam,lParam);
assert(pParent->m_hWnd == hWnd);
return pParent->WndProc(uMsg,wParam,lParam);
}

// And then for the non-static wndproc:

LRESULT CWindow::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
}

That way you don't need any globals or friend classes.

[edited by - Evil Steve on March 6, 2004 9:05:29 AM]

Share this post


Link to post
Share on other sites
Evil Steve: Microsoft says that you should use Get/SetWindowLongPtr(), for compatibility with 64-bit programs. And because Microsoft says so.
I thought that you were supposed to SetWindowLong() in response to WM_NCCREATE, not WM_CREATE. Unless it doesn''t make a difference..?

Quadratic, if you''re going to use Evil Steve''s code, make sure you allocate sizeof(CWindow*) bytes in your WNDCLASSEX structure, or else the "this" pointer that you pass to CreateWindowEx() doesn''t have any place to go.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!