Having trouble trying to implement an event handler for the Windows API shell

Friends, I’m trying to implement the Windows API shell, and I want to capture event child windows from the parent window, so I made a simple event handler. I used function pointers to store callback functions. I did this with static functions. See code below.

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; }; 

This works, but since static functions do not have these pointers, I have not been able to access the variables and member functions in the Window class . I want to make a member function as a callback function (event handler). Hope you understand what I'm trying to solve. Please help me.

+4
source share
1 answer

Your basic idea that you showed in this example is correct.

You create a static function WndProc and a mapping that maps HWND to your classes.

When you create a new instance of the widget, you add it to the mapping. When destroyed, you delete it from the mapping.

In your WndProc function, you take an instance of your class from the mapping and call the event handler function of this instance:

 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; 

Then in your derived class you only need to override the handleEvents function:

 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
source

Source: https://habr.com/ru/post/1446798/


All Articles