加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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中的变量和成员函数.
我想将一个成员函数作为回调函数(Event Handler).
我希望你明白我想要解决的问题.请帮我.

解决方法

您在此示例中显示的主要想法是正确的.

您可以创建一些静态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);
    }
};

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读