例如,当你在Windows中的屏幕上创建一个窗口时,你创建一个回调函数来接收来自windows的消息
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
你能使这个功能成为一个类的成员函数吗?如果是这样,我该怎么办?我希望回调函数成为类的成员的原因是访问某些变量,同时仍然包含变量。例如,我保存窗口的宽度和高度,所以如果它们在哪里被更改,我可以直接在回调函数中更改它们。
如果没有,你对我如何解决这个问题有什么建议,给回调函数访问封装变量吗?
答案 0 :(得分:3)
就像评论提示的那样,可以使用static
成员函数和SetWindowLongPtr
的组合来实现您的目标。
这是一个示例类声明,它将静态WindowProc
定义为成员函数。
class MyClass
{
public:
void MainThreadProc ();
private:
static LRESULT CALLBACK WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT _WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};
MainThreadProc方法将创建窗口。请务必将this
传递给CreateWindowEx
,因为这样您就可以访问您的班级成员了。
void MyClass::MainThreadProc()
{
MSG msg;
HINSTANCE hinstance = GetModuleHandle (NULL);
WNDCLASSEX wcx = {0};
HWND hwnd = NULL;
wcx.cbSize = sizeof wcx;
wcx.hInstance = hinstance;
wcx.hCursor = LoadCursor (NULL, IDC_NO);
wcx.style = CS_HREDRAW | CS_VREDRAW;
wcx.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wcx.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wcx.lpfnWndProc = WindowProc;
wcx.lpszClassName = L"MyWindowClass";
RegisterClassEx (&wcx);
hwnd = CreateWindowEx ( WS_EX_APPWINDOW,
L"MyWindowClass",
L"MyWindow",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hinstance,
this);
ShowWindow (hwnd, SW_SHOWDEFAULT);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
在WindowProc
中,您将使用this
存储SetWindowLongPtr
对象以供将来使用。
LRESULT MyClass::WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (WM_NCCREATE == uMsg)
{
SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) ((CREATESTRUCT*) lParam)->lpCreateParams);
return TRUE;
}
return ((MyClass*) GetWindowLongPtr (hwnd, GWLP_USERDATA))->_WindowProc (hwnd, uMsg, wParam, lParam);
}
为了完整起见,这里是处理窗口消息的最终成员函数,此时您将可以访问所有类成员。
LRESULT MyClass::_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage (S_OK);
break;
default:
return DefWindowProc (hwnd, uMsg, wParam, lParam);
}
return 0;
}