c – 尝试为Windows API包装器实现事件处理程序时遇到问题
发布时间:2020-12-16 07:02:12 所属栏目:百科 来源:网络整理
导读:朋友们,我正在尝试实现 Windows API的包装,我想从父窗口捕获子窗口事件,所以我做了一个简单的事件处理程序.我使用函数指针来存储回调函数.我用静态函数做了.请参阅下面的代码. class Widget;typedef void (*EventProc)(MSG* EventArgs);class Widget{public:
朋友们,我正在尝试实现
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); } Window() { control1=new CustomControl(100,100,200,200); //left,top,width,height this->AddChild(control1); control1->Created = ChildCreated; } private: CustomControl control1; }; 这是有效的,但由于静态函数没有这个指针,我无法访问类Window中的变量和成员函数. 解决方法
您在此示例中显示的主要想法是正确的.
您可以创建一些静态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,LPARAM lParam) { return DefWindowProc(_handle,hWnd,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,LPARAM lParam) { WidgetBase* wid=GetWidgetPointerFromHWND(hWnd); if (wid) { return wid->handleEvents(msg,lParam); } else { return DefWindowProc(hWnd,lParam); } } }; std::map<HWND,WidgetBase*> WidgetBase::_widgets; 然后在派生类中,您只需要覆盖handleEvents函数: class Derived: public WidgetBase { protected: virtual LRESULT handleEvents(UINT msg,LPARAM lParam) { // This is your event handler,that is memeber function //... return WidgetBase::handleEvents(msg,lParam); } }; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |