При программировании GUI некоторым функциям бывает необходимо указывать адрес callback-функции. А у меня программа на С++ состоит из классов. Хотелось бы эту callback включить, например, в класс интерфейса. Как это можно сделать? Если ещё не понятно, вот пример: Есть класс интерфейса. При создании окна необходимо члену структуры WNDCLASS присвоить адрес оконной процедуры, она вызывается через STDCALL, а методы класса вызываются по-другому. Поэтому нельзя передать в WNDCLASS адрес метода. Как тогда структурировать программу? (Хочу все callback собрать в кучу, желательно в классе интерфейса)
Не совсем уверен, что правильно понял. оконую процедуру делаешь static, this ложишь в lpParam при создании окна, потом вытаскиваешь его и можно вызывать виртуальные и thiscall функции: Код (Text): #ifndef IMAGE_BASE #define IMAGE_BASE 0x400000 #endif class window { public: window(const char * name, const int width, const int height, const int x = CW_USEDEFAULT, const int y = CW_USEDEFAULT) : name(name), width(width),height(height), x(x), y( y) {} void create(int extended_style, int style, HWND parent); static int message_loop() { MSG msg; while(!0) if( PeekMessageA(&msg, 0, 0, 0, PM_REMOVE) ) { if( msg.message == WM_QUIT ) return(msg.wParam); TranslateMessage(&msg); DispatchMessageA(&msg); } else { Sleep(2); } } protected: HWND handle; int x, y, width, height; const char * name; virtual void window_procedure(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { // code goes here if( msg == WM_DESTROY ) PostQuitMessage(0); } static LRESULT __stdcall dispatcher(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if( msg == WM_NCCREATE ) { ((window*)((CREATESTRUCTA*)lParam)->lpCreateParams)->handle = hWnd; SetWindowLongA(hWnd, GWL_USERDATA, (long)((CREATESTRUCTA*)lParam)->lpCreateParams); } else if(window * This = (window*)GetWindowLongA(hWnd,GWL_USERDATA)) This->window_procedure(hWnd, msg, wParam, lParam); return DefWindowProcA(hWnd,msg,wParam,lParam); } static const char class_name[]; }; //==================================================================== =====// const char window::class_name[] = "foo"; void window:: create(int extended_style, int style, HWND parent) { WNDCLASSEX wnd_class; wnd_class.cbSize = sizeof(wnd_class); wnd_class.style = 0; wnd_class.lpfnWndProc = window::dispatcher; wnd_class.cbClsExtra = 0; wnd_class.cbWndExtra = 0; wnd_class.hInstance = (HINSTANCE)IMAGE_BASE; wnd_class.hIconSm = wnd_class.hIcon = LoadIconA(NULL, IDI_WINLOGO); wnd_class.hCursor = LoadCursorA(NULL, IDC_ARROW); wnd_class.hbrBackground = NULL; wnd_class.lpszMenuName = NULL; wnd_class.lpszClassName = class_name; RegisterClassExA(&wnd_class); CreateWindowExA(extended_style, class_name, name, style, x, y, width, height, parent, NULL, (HINSTANCE)IMAGE_BASE, this); }