Я пытаюсь связать нестатический член класса с стандартной функцией WNDPROC
. Я знаю, что могу просто сделать это, поставив член класса статическим. Но, как ученик C++ 11 STL, я очень заинтересован в этом, используя инструменты под заголовком <functional>
.Как «std :: bind» нестатический член класса для функции обратного вызова Win32 `WNDPROC`?
Мой код выглядит следующим образом.
class MainWindow
{
public:
void Create()
{
WNDCLASSEXW WindowClass;
WindowClass.cbSize = sizeof(WNDCLASSEX);
WindowClass.style = m_ClassStyles;
WindowClass.lpfnWndProc = std::function<LRESULT(HWND, UINT, WPARAM, LPARAM)>
( std::bind(&MainWindow::WindowProc,
*this,
std::placeholders::_1,
std::placeholders::_2,
std::placeholders::_3,
std::placeholders::_4));
WindowClass.cbClsExtra = 0;
WindowClass.cbWndExtra = 0;
WindowClass.hInstance = m_hInstance;
WindowClass.hIcon = LoadIconW(m_hInstance, MAKEINTRESOURCEW(IDI_WINDOW));
WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WindowClass.hbrBackground = (HBRUSH) COLOR_WINDOW;
WindowClass.lpszMenuName = MAKEINTRESOURCEW(IDR_MENU);
WindowClass.lpszClassName = m_ClassName.c_str();
WindowClass.hIconSm = LoadIconW(m_hInstance, MAKEINTRESOURCEW(IDI_WINDOW_SMALL));
RegisterClassExW(&WindowClass);
m_hWnd = CreateWindowEx(/*_In_ DWORD*/ ExtendedStyles,
/*_In_opt_ LPCTSTR*/ m_ClassName.c_str(),
/*_In_opt_ LPCTSTR*/ m_WindowTitle.c_str(),
/*_In_ DWORD*/ m_Styles,
/*_In_ int*/ m_x,
/*_In_ int*/ m_y,
/*_In_ int*/ m_Width,
/*_In_ int*/ m_Height,
/*_In_opt_ HWND*/ HWND_DESKTOP,
/*_In_opt_ HMENU*/ NULL,
/*_In_opt_ HINSTANCE*/ WindowClass.hInstance,
/*_In_opt_ LPVOID*/ NULL);
}
private:
LRESULT CALLBACK WindowProc(_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam)
{
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
};
Когда я запускаю его как есть, он выдает сообщение об ошибке:
Error: no suitable conversion function from "std::function<LRESULT(HWND, UINT, WPARAM, LPARAM)>" to "WNDPROC".
Вместо вызова SetWindowLongPtr() после CreateWindowEx() вы можете передать указатель экземпляра самому CreateWindowEx(), а затем вызвать SetWindowLongPtr() в обработчике сообщений WM_NCCREATE. –
@Remy Спасибо, что указали альтернативную реализацию. Я обновил ответ, чтобы включить ваше предложение. – IInspectable
Если вы используете 'GWLP_USERDATA' с' SetWindowLongPtr() ', вам вообще не нужно устанавливать' cbWndExtra' окна. –