非静态类方法有一个隐藏的this
范围。这就是阻止该方法用作 WndProc(或任何其他 API 回调)的原因。您必须将类方法声明为static
删除那个this
范围。但正如您已经注意到的,您无法从静态方法访问非静态成员。您需要一个指向该对象的指针才能访问它们。
在 WndProc 回调的特定情况下,您可以将对象指针存储在 HWND 本身中(使用SetWindowLongPtr(GWLP_USERDATA)
or SetProp()
),那么你的静态方法就可以从hWnd
参数(使用GetWindowLongPtr(GWLP_USERDATA)
or GetProp()
)并根据需要使用该对象指针访问非静态成员。
例如:
private:
HWND m_Wnd;
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK Client::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Client *pThis;
if (msg == WM_NCCREATE)
{
pThis = static_cast<Client*>(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams);
SetLastError(0);
if (!SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pThis)))
{
if (GetLastError() != 0)
return FALSE;
}
}
else
{
pThis = reinterpret_cast<Client*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
}
if (pThis)
{
// use pThis->member as needed...
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
m_Wnd = CreateWindowEx(..., this);