Archived

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

xDS4Lx

Passing this to WndProc

Recommended Posts

Ok, first before im flammed about this being answered before, ive searched the board and tried what I found and its not working for me. I tried using the SetWindowLong and GetWindowLong functions using GWL_USERDATA but it didnt seem to work. Can anyone give me an example of this that works.

Share this post


Link to post
Share on other sites
Ok, i found this other method using Global Atoms and Properties works, but... when i test to see if the pointer is null it says it is. But I can call the methods of my class, is this because your not supposed to test if this is null?

Share this post


Link to post
Share on other sites
You have to call SetWindowLong(GWL_USERDATA, (long)this) in response to the WM_NCCREATE message in the window procedure. Which means you have to pass this to CreateWindow[Ex] as the lpParam parameter and then extract it as the lpCreateParams member of an LPCREATESTRUCT, obtained by casting the lParam value of the message handler.

Whew!

It''s not as complex as it sounds; I''ve submitted an article on the subject which should appear in 6 - 8 weeks (because of how backed up the queue is).

hwnd = CreateWindowEx(..., (void *)this);
...
LRESULT CALLBACK MsgHandler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch(msg)
{
case WM_NCCREATE:
{
MyClass *cls = (MyClass *) ((LPCREATESTRUCT)lparam)->lpCreateParams;
// do whatever you need to
}
return 0;
}
}


[ 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
I found a souloution that works but I have a few questions, The souloution was to add a global atom for my class, then after creating the window set the properties with a call to SetProp, then in WndProc I can extract the value by calling GetProp. This works fine and all but is this the best way of passing the this pointer to WndProC? Also I know I have to call RemoveProp also but MSDN says to call it before processing WM_DESTROY, but the example I found calls it in the class's destructor, is that ok? or should I put that into the WM_DESTROY message? heres the code:

      
CConvWindow::CConvWindow(const HINSTANCE& hInstance, const UINT& style, const HBRUSH& hBackground,
const HICON& hIconSmall, const HICON& hIconLarge, const HCURSOR& Cursor)
{....
aAtom = AddGlobalAtom(hWnd,"CConvWindowAtom");
.....
}

void CConvWindow::CreateWin(const HINSTANCE& hInstance)
{ if(!bInitFail)
{hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,"CBWindow","CBWindow Window",WS_OVERLAPPED | WS_SYSMENU,50, 50, 300,200, NULL, NULL, hInstance,NULL);
}
if(!hWnd)
{ bInitFail = true;
Message("Error Creating Window","ERROR IN APLICATION INITIALIZATION");
}

//SetWindowLong(hWnd,GWL_USERDATA,(long)this);

SetProp(hWnd,"CConvWindowAtom",(HANDLE)this);

ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
}
LRESULT CALLBACK CConvWindow::WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{ static CConvWindow* cWnd; // Used to hold pointer to this* since WndProc must be called

// using _stdcall and not _thiscall


switch(Msg)
{ case WM_CREATE:
{ cWnd = (CConvWindow*)GetProp(hWnd,"CConvWindowAtom");
break;
}
case WM_CLOSE:
{ DestroyWindow(hWnd);
break;
}
case WM_DESTROY:
{ PostQuitMessage(0);
break;
}
default:
{ return(DefWindowProc(hWnd,Msg,wParam,lParam));
}
} // end of switch(Msg)

return(0);
}

CConvWindow::~CConvWindow()
{ UnregisterClass("CConvWindow",hInst); // Are These ok?

RemoveProp(hWnd,"CConvWindowAtom");
}



Edited by - xds4lx on February 20, 2002 12:08:38 PM

Edited by - xds4lx on February 20, 2002 1:03:48 PM

Share this post


Link to post
Share on other sites
Why can''t you use what Oluseyi has suggested? Per-window data is the ideal place to store this pointer.

Sorry I''ve never used global atoms. I use per-window data for my this pointer, or better yet, MFC .

Share this post


Link to post
Share on other sites
IndirectX, ive tried his method also and its what im using at the moment, but im wondering what the differences are between the two. And which one is the proper way to do it.


Edited by - xds4lx on February 22, 2002 3:06:03 AM

Share this post


Link to post
Share on other sites