从子类附加WNDPROC函数

时间:2012-03-14 17:43:30

标签: c++ winapi

将窗口过程附加到窗口时遇到问题。

我有一个名为BaseWindow的基类,它使用GWPL_USERDATA来调用子类的HandleMessage()虚拟函数。

但是,如果我尝试在不创建自定义Window类的情况下更改窗口过程,则会从子过程向long提供类型错误。

以下是代码:

static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    BaseWindow *pThis = NULL;

    if (uMsg == WM_NCCREATE)
    {
        CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;
        pThis = (BaseWindow*)pCreate->lpCreateParams;
        SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);

        pThis->m_hwnd = hwnd;
    }
    else
    {
        pThis = (BaseWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
    }
    if (pThis)
    {
        return pThis->HandleMessage(uMsg, wParam, lParam);
    }
    else
    {
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
}

virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {return 0;};


PlayList Class : BaseWindow

SetWindowLong(m_hwnd, GWL_WNDPROC,(long)  HandleMessage); //Error

LRESULT PlayList::HandleMessage(UINT message,WPARAM wParam,LPARAM lParam) //Need to     attach this window procedure
{}

如果子过程是静态的,它可以工作,但是我在该过程中使用非静态成员。

我想继承一个公共控件,同时使用这个基类(因为很多代码都是冗余的),是否可能?

这里是基类的完整代码:http://pastebin.com/ME8ks7XK

2 个答案:

答案 0 :(得分:0)

来自MSDN:

  

应用程序通过使用SetWindowLong函数对窗口实例进行子类化。应用程序将GWL_WNDPROC标志,窗口的句柄传递给子类,子类过程的地址传递给SetWindowLong。子类过程可以驻留在应用程序的可执行文件或DLL中。

所以,你应该这样写:
SetWindowLong(m_hwnd, GWL_WNDPROC,(long) & HandleMessage);

但这不会再次编译!原因:所有非静态成员函数都有隐藏的this参数(指向所有者类的指针)。因此,HandleMessage不符合WindowProc声明。

答案 1 :(得分:0)

编译器不喜欢你的HandleMessage声明,它不是静态的。它也缺少CALLBACK,不好。

不确定为什么要这样做,WindowProc()函数的重点是将消息转发到虚拟HandleMessage()方法。最好在SetWindowLong()调用中使用WindowProc而不是HandleMesssage。或者直接在CreateWindowEx()调用中指定它。