Sto tentando di associare un membro di classe non statico a una funzione standard WNDPROC
. So che posso farlo semplicemente rendendo statico il membro della classe. Ma, come studente di STL di C++ 11, sono molto interessato a farlo usando gli strumenti sotto l'intestazione <functional>
.Come faccio `std :: bind` un membro di classe non statico a una funzione di callback Win32` WNDPROC`?
Il mio codice è come segue.
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);
}
};
Quando eseguo così com'è, dà il messaggio di errore:
Error: no suitable conversion function from "std::function<LRESULT(HWND, UINT, WPARAM, LPARAM)>" to "WNDPROC".
Invece di chiamare SetWindowLongPtr() dopo CreateWindowEx(), è possibile passare il puntatore di istanza a CreateWindowEx() per sé e quindi chiamare SetWindowLongPtr() nel gestore di messaggi WM_NCCREATE. –
@Remy Grazie per aver segnalato un'implementazione alternativa. Ho aggiornato la risposta per includere il tuo suggerimento. – IInspectable
Se si utilizza 'GWLP_USERDATA' con' SetWindowLongPtr() ', non è necessario impostare' cbWndExtra' della finestra. –