Thread overview
Mr. Bright: static WndProc
Sep 27, 2003
Albin Pucnik
Sep 27, 2003
Hauke Duden
Sep 27, 2003
Albin Pucnik
Sep 27, 2003
Mike Wynn
Sep 27, 2003
Andy Friesen
Sep 28, 2003
Albin Pucnik
Sep 28, 2003
Hauke Duden
Sep 28, 2003
Mike Wynn
Sep 29, 2003
Albin Pucnik
Sep 30, 2003
Mike Wynn
September 27, 2003
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

September 27, 2003
> 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;
};


September 27, 2003
Compiler complains on line:
 SetWindowLong(hWnd,GWL_USERDATA,cast(LONG) this);.
It says :
 cannot cast from CWindow to int.

Albin

September 27, 2003
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)

September 27, 2003
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

September 28, 2003
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

September 28, 2003
> 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


September 28, 2003
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)

September 29, 2003
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



September 30, 2003
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.