将窗口过程附加到窗口时遇到问题。
我有一个名为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
答案 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()调用中指定它。