www.digitalmars.com         C & C++   DMDScript  

D - Mr. Bright: static WndProc

reply Albin Pucnik <albin.pucnik guest.arnes.si> writes:
Mr. Bright

I'm trying to create a class, which wraps a child window in MS 
Windows.One of the class's members is windows procedure (WndProc)
for a child. In order to compile correctly, I have to include static 
modifier ( extern (Windows) static int WndProc(...) ),otherwise I get 
following error : cannot implicitly convert int delegate(HANDLE hWnd, 
uint uMsg,uint wParam,int lParam) to int(Windows*)(HANDLE,uint,uint,
int). Why WndProc needs to be defined as static?

Albin
Sep 27 2003
parent reply "Hauke Duden" <H.NS.Duden gmx.net> writes:
 I'm trying to create a class, which wraps a child window in MS
 Windows.One of the class's members is windows procedure (WndProc)
 for a child. In order to compile correctly, I have to include static
 modifier ( extern (Windows) static int WndProc(...) ),otherwise I get
 following error : cannot implicitly convert int delegate(HANDLE hWnd,
 uint uMsg,uint wParam,int lParam) to int(Windows*)(HANDLE,uint,uint,
 int). Why WndProc needs to be defined as static?
Windows doesn't support the delegate concept (which is basically the address of a member function combined with the object's this pointer, so that the member function can be invoked for a specific object). Window's window classes only store a straight function address without any this pointer. And since all methods that are not static need a this pointer to execute, you cannot use them as window procedures. The normal way to deal with this is to use a static function and store the object's this pointer in each window's "user data" field.The static function can then retrieve the this pointer from the user data and call a normal member function. Here's an example (never compiled this, so there may be mistakes): class CWindow { this() { RegisterClass ( ... ) // register window class with windowProc as the window procedure m_hWindow =CreateWindow(.... ) SetWindowLong(hWindow,GWL_USERDATA,(LONG)this); //store the this pointer in the window } //static windowProc extern(Windows) static LRESULT windowProc(HWND hWindow,UINT message,WPARAM wParam,LPARAM lParam) { CWindow thisObject = cast(CWindow) GetWindowLong(hWindow,GWL_USERDATA); if( thisObject !== null) return thisObject.messageHandler(hWindow,message,wParam,lParam); else return CallWndProc(DefWindowProc,hWindow,message,wParam,lParam); } //"real" non-static window proc LRESULT messageHandler(HWND hWindow,UINT message,WPARAM wParam,LPARAM lParam) { //handle message } protected: HWND m_hWindow; };
Sep 27 2003
next sibling parent reply Albin Pucnik <albin.pucnik guest.arnes.si> writes:
Compiler complains on line:
  SetWindowLong(hWnd,GWL_USERDATA,cast(LONG) this);.
It says :
  cannot cast from CWindow to int.

Albin
Sep 27 2003
next sibling parent Mike Wynn <mike l8night.co.uk> writes:
Albin Pucnik wrote:
 
 Compiler complains on line:
  SetWindowLong(hWnd,GWL_USERDATA,cast(LONG) this);.
 It says :
  cannot cast from CWindow to int.
 
 Albin
 
try SetWindowLong(hWnd,GWL_USERDATA,cast(LONG)cast(void*)this);. you might want to look at the win32 API calls GetProp and SetProp, these allow a value to be attached to a window (i.e. allows subclassing of an windows class that uses GWL_USERDATA)
Sep 27 2003
prev sibling parent Andy Friesen <andy ikagames.com> writes:
Albin Pucnik wrote:
 
 Compiler complains on line:
  SetWindowLong(hWnd,GWL_USERDATA,cast(LONG) this);.
 It says :
  cannot cast from CWindow to int.
 
 Albin
This is a bit silly, but you first have to cast to void*. void* p = cast(void*)this; SetWindowLong(hWnd, GWL_USERDATA, cast(LONG)p); -- andy
Sep 27 2003
prev sibling parent reply Albin Pucnik <albin.pucnik guest.arnes.si> writes:
Thank you guys. It does compile now, although it doesn't work.
It must be my fault, because I not used to program Windows
directly.

One more question. Now I have a static member ( WndProc ),
which calls a non-static member (messageHandler). Is this OK ?

Albin
Sep 27 2003
next sibling parent "Hauke Duden" <H.NS.Duden gmx.net> writes:
 One more question. Now I have a static member ( WndProc ),
 which calls a non-static member (messageHandler). Is this OK ?
Yes. The static member obtains an object reference (i.e. a "this" pointer) from the window, so it can safely call the nonstatic member on that object reference. Hauke
Sep 28 2003
prev sibling parent reply Mike Wynn <mike l8night.co.uk> writes:
Albin Pucnik wrote:
 
 Thank you guys. It does compile now, although it doesn't work.
 It must be my fault, because I not used to program Windows
 directly.
 
 One more question. Now I have a static member ( WndProc ),
 which calls a non-static member (messageHandler). Is this OK ?
 
 Albin
 
as long as you have to right object ! have a look at http://www.geocities.com/one_mad_alien/dcom_not_dcom.html there is the beginnings of a win32 class lib there, has all the mechanics for attaching a class to a HWND, and then getting messages routed to attached delegates or member functions. (I only wrote enough to write a few win32 apps) or look at http://www.opend.org/dig/ another (more complete win32 lib)
Sep 28 2003
parent reply Albin Pucnik <albin.pucnik guest.arnes.si> writes:
Thank you for the directions. I took a look at the code. It is very
general and hard to read ( for me, since I'm not a professional
programmer) and therefore doesn't help me much.
Would you be so kind to look at what I'm trying to do? It is few
lines of code, where I'm setting up a window with a child that
responds to a keystroke. I can't figure out, what I'm doing wrong.

Albin
Sep 29 2003
parent Mike Wynn <mike l8night.co.uk> writes:
Albin Pucnik wrote:
 Thank you for the directions. I took a look at the code. It is very
 general and hard to read ( for me, since I'm not a professional
 programmer) and therefore doesn't help me much.
 Would you be so kind to look at what I'm trying to do? It is few
 lines of code, where I'm setting up a window with a child that
 responds to a keystroke. I can't figure out, what I'm doing wrong.
 
 Albin
 
your child window need to get the input focus to get the key messages.
Sep 30 2003