Возникли проблемы при попытке реализовать обработчик событий для Windows API-оболочки

Друзья, я пытаюсь реализовать оболочку Windows API и хочу захватывать события дочернего окна из родительского окна, поэтому я сделал простой обработчик событий. Я использовал указатели функций для хранения функций обратного вызова. Я сделал это со статическими функциями. Смотрите код ниже.

class Widget;
typedef void (*EventProc)(MSG* EventArgs);
class Widget
{
public:
/// Constructors destructor and methods for Registering and Creating Windows
static LRESULT CALLBACK MainProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
MSG struct_msg;
struct_msg.hWnd=hWnd;
struct_msg.message=msg;
struct_msg.wParam=wParam;
struct_msg.lParam=lParam;

Widget* wid=(Widget*)GetWidgetPointerFromHWND(hWnd);

switch(msg)
{
case WM_CREATE:
if(Created!=NULL)
(*(wid->Created))(&struct_msg);break;
case WM_DESTROY:
if(Destroyed!=NULL)
(*(wid->Destroyed))(&struct_msg);break;
default:
return DefWindowProc(hWnd,msg,wParam,lParam);
}
return 0;
}
EventProc Created;
EventProc Destroyed;

};

class CustomControl: public Widget
{
/// Constructor destructor and other methods

};

class Window: public Widget
{
public:

static void ChildCreated(Widget* Sender,Widget* Self,MSG* EventArgs)
{
MessageBox(0,0,0,0);
}

Window()
{
control1=new CustomControl(100,100,200,200); //left,top,width,height
this->AddChild(control1);
control1->Created = ChildCreated;
}
private:
CustomControl control1;
};

Это работает, но поскольку статические функции не имеют этих указателей, я не смог получить доступ к переменным и функциям-членам в Окно класса.
Я хочу сделать функцию-член в качестве функции обратного вызова (обработчик событий).
Я надеюсь, вы понимаете, что я пытаюсь решить. Пожалуйста, помогите мне.

4

Решение

Ваша основная идея, которую вы показали в этом примере, верна.

Вы делаете некоторые static WndProc функция и отображение, которое отображает HWND на ваши занятия.

При создании нового экземпляра виджета вы добавляете его в отображение. При уничтожении вы удаляете его из картографии.

В вашей функции WndProc вы берете экземпляр вашего класса из отображения и вызываете виртуальную функцию обработчика событий этого экземпляра:

class WidgetBase
{
public:
WidgetBase()
{
_handle = CreateWindow(/*...*/, &WidgetBase::MainProc, /*...*/);
_widgets.insert(std::make_pair(handle, this);
}
virtual ~WidgetsBase()
{
_widgets.remove(handle);
}
protected:
HWND _handle;
virtual LRESULT handleEvents(UINT msg,WPARAM wParam,LPARAM lParam)
{
return DefWindowProc(_handle, hWnd,msg,wParam,lParam);
}
private:
static std::map<HWND, WidgetBase*> _widgets;

static WidgetBase* GetWidgetPointerFromHWND(HWND handle)
{
// some error handling should be put there
return _widgets[handle];
}

static LRESULT CALLBACK MainProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
WidgetBase* wid=GetWidgetPointerFromHWND(hWnd);
if (wid) {
return wid->handleEvents(msg, wParam, lParam);
}
else {
return DefWindowProc(hWnd,msg,wParam,lParam);
}
}
};
std::map<HWND, WidgetBase*> WidgetBase::_widgets;

Тогда в вашем производном классе вам нужно только переопределить handleEvents функция:

class Derived: public WidgetBase
{
protected:
virtual LRESULT handleEvents(UINT msg,WPARAM wParam,LPARAM lParam)
{
// This is your event handler, that is memeber function
//...
return WidgetBase::handleEvents(msg, wParam, lParam);
}
};
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector