• Advertisement

Archived

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

Problems storing this in GWL_USERDATA

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

Ok, I wrote a class CWindow and Im having no problems getting the this* to the static WndProc, what im having problems with is it wont let me store it using (I try to store it when processing the WM_NCCREATE message):
    
SetWindowLong(hwnd, GWL_USERDATA,(LONG)((LPCREATESTRUCT)lParam)->lpCreateParams);
			
    
Is there something I should set in the WNDCLASSEX struct? or when I call CreateWindowEx? And yes im already passing this in as the lpParam. When ever I try to retrieve it using:
  
 cWnd = (CWindow*)GetWindowLong(hWnd, GWL_USERDATA) 
  
to get my this pointer it just gives me a null value. If you need to see some code I can Post the basics for the class. "Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music." - Kristian Wilson, Nintendo, Inc, 1989 Edited by - xds4lx on February 24, 2002 11:27:19 PM

Share this post


Link to post
Share on other sites
Advertisement
when you do your creation of the window you set userdata, not in the message loop since you wont know for which object the window belongs to without doing some lookups. instead you should do the following in your window create funtion:

  
// PSUDEO code

// ...

hwnd = CreateWindow();
SetWindowLong(hwnd, GWL_USERDATA, (LONG)this);
// ...



you do the get as you have been within your message loop as needed. if that dont work, then you have something seriously wrong with your code. since i have used similar methods myself.

Share this post


Link to post
Share on other sites
I tried doing that also but it still doesnt work. Im going to pose the code here b/c this is really frustrating. Ive looked at NeHe's basecode and I seem to be doing everything the same, but it doesnt work.

    
//From CBWindow.h


class CBWindow{
public:

CBWindow(HINSTANCE hInstance, char* pszWindowName, int cXpos, int cYpos, int cXsize,
int cYsize);
//Pre:

//Post:


bool Create();
//Pre:

//Post:


virtual ~CBWindow();
//Pre:

//Post:


void Message(char* pszMessage, char* pszTitle, UINT uStyle = 0);
//Pre:

//Post:


void SetWindowName(char* pszName);
//Pre:

//Post:


protected:

WNDCLASSEX wndClass;
HINSTANCE hInst;
HWND hWnd;

char* pszCName;
char* pszWName;

bool bInitFail;

int cXPos;
int cYPos;
int cXSize;
int cYSize;

virtual LRESULT WndProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);
//Pre:

//Post:


private:

bool RegisterWnd();
//Pre:

//Post:


bool BuildWin();
//Pre:

//Post:


static LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
//Pre:

//Post:

};

//From CBWindow.cpp

/* ******************************** Constructors *************************************** */
CBWindow::CBWindow(HINSTANCE hInstance, char* pszWindowName, int cXpos, int cYpos,
int cXsize, int cYsize)
: hInst(hInstance), pszCName("CBWindow"), pszWName(pszWindowName), cXPos(cXpos), cYPos(cYpos),
cXSize(cXsize), cYSize(cYsize), bInitFail(false)
{
}

CBWindow::~CBWindow()
{ UnregisterClass(pszCName,hInst);
}

/* ************************************************************************************** */

/* ******************************* Public Methods ************************************** */
bool CBWindow::Create()
{ if(!RegisterWnd())
{ bInitFail = true;
}

if(!bInitFail && !BuildWin())
{ bInitFail = true;
}
else
{ ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
bInitFail = false;
}
return(!bInitFail);
}

void CBWindow::Message(char* pszMessage, char* pszTitle, UINT uStyle)
{ MessageBox(NULL,pszMessage,pszTitle, MB_OK | uStyle);
}

void CBWindow::SetWindowName(char* pszName)
{ SetWindowText(hWnd,pszName);
pszWName = pszName;
}


/* ************************************************************************************** */

/* ***************************** Protected Methods ************************************** */
LRESULT CBWindow::WndProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{ default:
{ return(DefWindowProc(hwnd,Msg,wParam,lParam));
}
} // end of switch(Msg)
return(0);
}

/* ******************************* Private Methods ************************************** */
bool CBWindow::RegisterWnd()
{ ZeroMemory(&wndClass, sizeof(WNDCLASSEX));

wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.hCursor = (HCURSOR)LoadCursor(NULL,IDC_ARROW);
wndClass.hIconSm = (HICON)LoadIcon(NULL,IDI_APPLICATION);
wndClass.hIcon = (HICON)LoadIcon(NULL,IDI_APPLICATION);
wndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
wndClass.hInstance = hInst;
wndClass.lpszMenuName = NULL;
wndClass.lpfnWndProc = &(this->WindowProc);
wndClass.style = CS_OWNDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
//wndClass.cbClsExtra = 0;
//wndClass.cbWndExtra = 0;
wndClass.lpszClassName = pszCName;

if(!RegisterClassEx(&wndClass))
{ MessageBox(NULL,"Error Registering Window Class","ERROR IN APPLICATION STARTUP",MB_OK);
return(false);
}
return(true);
}

bool CBWindow::BuildWin()
{ if(!bInitFail)
{ hWnd = CreateWindowEx(WS_EX_APPWINDOW,
pszCName,
pszWName,
WS_OVERLAPPEDWINDOW | WS_SYSMENU | WS_VISIBLE,
cXPos, // X Position
cYPos, // Y Position
cXSize, // X Size
cYSize, // Y Size
NULL, // Handle to Parent
NULL, // Handle to Menu
hInst, // Application Instance
(void*)this);
}
if(!hWnd)
{ MessageBox(NULL,"Error Creating Window","ERROR IN APPLICATION STARTUP",MB_OK);
return(false);
}
return(true);
}

LRESULT CALLBACK CBWindow::WindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{ CBWindow* cWnd ;//= (CBWindow*)GetWindowLong(hwnd, GWL_USERDATA);

switch(Msg)
{ case WM_NCCREATE:
{ LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;

cWnd = (CBWindow*)lpcs->lpCreateParams;
SetWindowLong(hwnd, GWL_USERDATA,(LONG)cWnd);
return(TRUE);
}
case WM_CLOSE:
{ DestroyWindow(hwnd);
break;
}
case WM_DESTROY:
{ PostQuitMessage(0);
break;
}
default:
{ cWnd = (CBWindow*)GetWindowLong(hwnd, GWL_USERDATA);
if(cWnd)
return(cWnd->WndProc(hwnd,Msg,wParam,lParam));
else
return(DefWindowProc(hwnd,Msg,wParam,lParam));
}
} // end of switch(Msg)
return(0);
}/* ******************************** Constructors *************************************** */
CBWindow::CBWindow(HINSTANCE hInstance, char* pszWindowName, int cXpos, int cYpos,
int cXsize, int cYsize)
: hInst(hInstance), pszCName("CBWindow"), pszWName(pszWindowName), cXPos(cXpos), cYPos(cYpos),
cXSize(cXsize), cYSize(cYsize), bInitFail(false)
{
}

CBWindow::~CBWindow()
{ UnregisterClass(pszCName,hInst);
}

/* ************************************************************************************** */

/* ******************************* Public Methods ************************************** */
bool CBWindow::Create()
{ if(!RegisterWnd())
{ bInitFail = true;
}

if(!bInitFail && !BuildWin())
{ bInitFail = true;
}
else
{ ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
bInitFail = false;
}
return(!bInitFail);
}

void CBWindow::Message(char* pszMessage, char* pszTitle, UINT uStyle)
{ MessageBox(NULL,pszMessage,pszTitle, MB_OK | uStyle);
}

void CBWindow::SetWindowName(char* pszName)
{ SetWindowText(hWnd,pszName);
pszWName = pszName;
}


/* ************************************************************************************** */

/* ***************************** Protected Methods ************************************** */
LRESULT CBWindow::WndProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{ default:
{ return(DefWindowProc(hwnd,Msg,wParam,lParam));
}
} // end of switch(Msg)
return(0);
}

/* ******************************* Private Methods ************************************** */

bool CBWindow::RegisterWnd()
{ ZeroMemory(&wndClass, sizeof(WNDCLASSEX));

wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.hCursor = (HCURSOR)LoadCursor(NULL,IDC_ARROW);
wndClass.hIconSm = (HICON)LoadIcon(NULL,IDI_APPLICATION);
wndClass.hIcon = (HICON)LoadIcon(NULL,IDI_APPLICATION);
wndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
wndClass.hInstance = hInst;
wndClass.lpszMenuName = NULL;
wndClass.lpfnWndProc = &(this->WindowProc);
wndClass.style = CS_OWNDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
//wndClass.cbClsExtra = 0;

//wndClass.cbWndExtra = 0;

wndClass.lpszClassName = pszCName;

if(!RegisterClassEx(&wndClass))
{ MessageBox(NULL,"Error Registering Window Class","ERROR IN APPLICATION STARTUP",MB_OK);
return(false);
}
return(true);
}

bool CBWindow::BuildWin()
{ if(!bInitFail)
{ hWnd = CreateWindowEx(WS_EX_APPWINDOW,
pszCName,
pszWName,
WS_OVERLAPPEDWINDOW | WS_SYSMENU | WS_VISIBLE,
cXPos, // X Position

cYPos, // Y Position

cXSize, // X Size

cYSize, // Y Size

NULL, // Handle to Parent

NULL, // Handle to Menu

hInst, // Application Instance

(void*)this);
}
if(!hWnd)
{ MessageBox(NULL,"Error Creating Window","ERROR IN APPLICATION STARTUP",MB_OK);
return(false);
}
return(true);
}

LRESULT CALLBACK CBWindow::WindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{ CBWindow* cWnd ;//= (CBWindow*)GetWindowLong(hwnd, GWL_USERDATA);


switch(Msg)
{ case WM_NCCREATE:
{ LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;

cWnd = (CBWindow*)lpcs->lpCreateParams;
SetWindowLong(hwnd, GWL_USERDATA,(LONG)cWnd);
return(TRUE);
}
case WM_CLOSE:
{ DestroyWindow(hwnd);
break;
}
case WM_DESTROY:
{ PostQuitMessage(0);
break;
}
default:
{ cWnd = (CBWindow*)GetWindowLong(hwnd, GWL_USERDATA);
if(cWnd)
return(cWnd->WndProc(hwnd,Msg,wParam,lParam));
else
return(DefWindowProc(hwnd,Msg,wParam,lParam));
}
} // end of switch(Msg)

return(0);
}


Sorry about the length




"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music."
- Kristian Wilson, Nintendo, Inc, 1989


Edited by - xds4lx on February 24, 2002 12:04:47 AM

Share this post


Link to post
Share on other sites
quote:
Original post by a person
instead you should do the following in your window create funtion:

// PSUDEO code
// ...
hwnd = CreateWindow();
SetWindowLong(hwnd, GWL_USERDATA, (LONG)this);
// ...

Several messages are sent to the window before CreateWindow returns. To implement object association as you have outlined would require special handling in the message handler for WM_NCCREATE, WM_CALCSIZE and WM_CREATE. Not an elegant design.

xDSL4Lx, how are you passing this to CreateWindowEx? The following method works for me and many others:

Window::Create()
{
m_hwnd = CreateWindowEx(.., this); // this is the last parameter
// other init
}
...
LRESULT CALLBACK Window::MsgRouter(HWND hwnd, UINT msg, ...)
{
Window *wnd = NULL;
switch(msg)
{
case WM_NCCREATE:
SetWindowLong(GWL_USERDATA, (long)((LPCREATESTRUCT)lParam)->lpCreateparams);
return 0;
//
default:
wnd = (Window *)GetWindowLong(GWL_USERDATA);
if(wnd)
return wnd->WndProc(...);
break;
}
return DefWindowProc(...);
}


[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
quote:
Original post by xDS4Lx
cWnd = (CBWindow*)lpcs->lpCreateParams;

You're casting wrong, for one thing. You should wrap the entire right hand side in parentheses, because it's the lpCreateParams that you're casting, not lpcs.

[Edit: ie, cWnd = (CBWindow *)(lpcs->lpCreateParams);]

You also don't need to cast this to void *.

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!


Edited by - Oluseyi on February 24, 2002 12:05:57 AM

Share this post


Link to post
Share on other sites
I dont know if this helps any but for some reason some function is causing an error, I find if I call GetLastError it returns 120, which acording to MSDN is: The Function Is Not Supported on this System. It returns this if i Call GetLast Error anywhere in my WndProc, how would I go about finding what is causing this?

Share this post


Link to post
Share on other sites

  • Advertisement