怎么设计GUI的消息回调

一入程序深似海 2013-09-13 04:13:00
通常一个closure包含一个指向某类实例的指针,和一个该类的成员函数
struct closure
{
CUIXXX _Obj;
void* _Func;
};


在写GUI的时候,假如窗口A是CXXXWnd的一个实例,窗口A上有5个button和2个ComboBox
我现在点击窗口A上的某个button,需要这个button响应 CXXXWnd::OnButtonAPressed(button* btn);
这个时候,closure的_Obj保存的是实例A的地址,_Func保存的是CXXXWnd::OnButtonAPressed的地址,

当消息传递到button上的时候,在button类里面处理click消息,找到对应的closure,执行 _Obj->*_Func(this)
思路是这样的。

我现在点击ComboBox的下拉列表框中的某一项(假设是第3项),需要响应CXXXWnd::OnItemChanged(ComboBox* combo, int index);然后在ComboBox的消息处理中,找到对应的closure,也是需要执行_Obj->*_Func(this, 3);

现在的问题是:我怎么告诉closure的_Func,指向的函数有些是带参数,有些不带参数,有些带好几个参数。
...全文
348 20 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 19 楼 allenhiman 的回复:
[quote=引用 18 楼 CKnightx 的回复:] [quote=引用 16 楼 schlafenhamster 的回复:] 模拟printf
回调函数也用不定参数,这。。太山寨了吧。。[/quote] 你结构体里放函数指针本来就很奇怪了吧 根据你的环境,我相信有其它的解决办法。[/quote] 不放函数指针,那怎么记住成员函数的地址? 有一个办法,类似WPF,把所有的可能用到的参数都放进一个结构中,调用的时候,根据函数的参数来选择调用。
allenhiman 2013-09-16
  • 打赏
  • 举报
回复
引用 18 楼 CKnightx 的回复:
[quote=引用 16 楼 schlafenhamster 的回复:] 模拟printf
回调函数也用不定参数,这。。太山寨了吧。。[/quote] 你结构体里放函数指针本来就很奇怪了吧 根据你的环境,我相信有其它的解决办法。
  • 打赏
  • 举报
回复
引用 16 楼 schlafenhamster 的回复:
模拟printf
回调函数也用不定参数,这。。太山寨了吧。。
  • 打赏
  • 举报
回复
引用 15 楼 zhoujielunzhimi 的回复:
[quote=引用 13 楼 leeihcy 的回复:] [quote=引用 12 楼 zhoujielunzhimi 的回复:] [quote=引用 11 楼 leeihcy 的回复:] 我就是通过看bind1st,然后自己也写了一个类似的
你可以看看我的写法。我觉得会简单一点[/quote] 你直接使用函数指针的话,对于有参数有返回值的函数,如何拿到函数的返回值类型?如何传递参数类型?[/quote] 我使用 模板 的原因就是可以支持任何参数类型。 对于返回值,确实没办法。[/quote] 返回值也可以用模板来萃取。 http://www.cppblog.com/Streamlet/archive/2011/01/16/138615.aspx
schlafenhamster 2013-09-14
  • 打赏
  • 举报
回复
模拟printf
sumos 2013-09-14
  • 打赏
  • 举报
回复
引用 13 楼 leeihcy 的回复:
[quote=引用 12 楼 zhoujielunzhimi 的回复:] [quote=引用 11 楼 leeihcy 的回复:] 我就是通过看bind1st,然后自己也写了一个类似的
你可以看看我的写法。我觉得会简单一点[/quote] 你直接使用函数指针的话,对于有参数有返回值的函数,如何拿到函数的返回值类型?如何传递参数类型?[/quote] 我使用 模板 的原因就是可以支持任何参数类型。 对于返回值,确实没办法。
  • 打赏
  • 举报
回复
引用 13 楼 leeihcy 的回复:
[quote=引用 12 楼 zhoujielunzhimi 的回复:] [quote=引用 11 楼 leeihcy 的回复:] 我就是通过看bind1st,然后自己也写了一个类似的
你可以看看我的写法。我觉得会简单一点[/quote] 你直接使用函数指针的话,对于有参数有返回值的函数,如何拿到函数的返回值类型?如何传递参数类型?[/quote] 对于下响应控件事件的回调,我不需要返回值。我就是需要怎么把参数传进去的方法。 额。。。我发现必须对于各种不同参数的回调,都需要写一个解析参数的invoke,看了一下GACLib的消息,它类似于WPF的回调,把参数都封装到一个结构里面去了,不管回调函数有没有参数,都传递一个参数的封装结构。 说实话,我不太喜欢这种方式。加入对于一个不需要任何参数的回调,也传递一个这样的参数结构,这不是浪费么。
leeihcy 2013-09-14
  • 打赏
  • 举报
回复
引用 12 楼 zhoujielunzhimi 的回复:
[quote=引用 11 楼 leeihcy 的回复:] 我就是通过看bind1st,然后自己也写了一个类似的
你可以看看我的写法。我觉得会简单一点[/quote] 你直接使用函数指针的话,对于有参数有返回值的函数,如何拿到函数的返回值类型?如何传递参数类型?
sumos 2013-09-13
  • 打赏
  • 举报
回复
引用 11 楼 leeihcy 的回复:
我就是通过看bind1st,然后自己也写了一个类似的

    // 函数对象
    template<class T, typename Arg1, typename Return> 
    class mem_fun1
    {
    public:
        explicit mem_fun1(Return (T::*pfunc)(Arg1))
        {
            m_pfunc = pfunc;
        }
        Return operator()(T* pThis, Arg1 _1)
        {
            return (pThis->*m_pfunc)(_1);
        }

        Return (T::*m_pfunc)(Arg1);
    };

    // 函数包
    template<class T, typename Arg1, typename Return=long> 
    class mem_fun1_pkg : public fun_pkg
    {
    public:
        mem_fun1_pkg(mem_fun1<T, Arg1, Return>& mf, T* pThis, Arg1 arg1):m_memberfunction1(mf)
        {
            m_pThis = pThis;
            m_Arg1 = arg1;
        }
        Return operator()()
        {
            return m_memberfunction1(m_pThis, m_Arg1);
        }
    private:
        mem_fun1<T, Arg1, Return>   m_memberfunction1;
        T*    m_pThis;
        Arg1  m_Arg1;
    };
你可以看看我的写法。我觉得会简单一点
leeihcy 2013-09-13
  • 打赏
  • 举报
回复
我就是通过看bind1st,然后自己也写了一个类似的

    // 函数对象
    template<class T, typename Arg1, typename Return> 
    class mem_fun1
    {
    public:
        explicit mem_fun1(Return (T::*pfunc)(Arg1))
        {
            m_pfunc = pfunc;
        }
        Return operator()(T* pThis, Arg1 _1)
        {
            return (pThis->*m_pfunc)(_1);
        }

        Return (T::*m_pfunc)(Arg1);
    };

    // 函数包
    template<class T, typename Arg1, typename Return=long> 
    class mem_fun1_pkg : public fun_pkg
    {
    public:
        mem_fun1_pkg(mem_fun1<T, Arg1, Return>& mf, T* pThis, Arg1 arg1):m_memberfunction1(mf)
        {
            m_pThis = pThis;
            m_Arg1 = arg1;
        }
        Return operator()()
        {
            return m_memberfunction1(m_pThis, m_Arg1);
        }
    private:
        mem_fun1<T, Arg1, Return>   m_memberfunction1;
        T*    m_pThis;
        Arg1  m_Arg1;
    };
  • 打赏
  • 举报
回复
引用 8 楼 leeihcy 的回复:
你可以看看 stl 里的 bind1st bind2nd,看看它是怎么用模板解决这样的问题的。
其实boost::bind和boost::function可以实现。可是我这贱骨头就是想自己写一份,通过重复造轮子来学点东西 stl的bind1st和 bind2nd 在最新的C++标准库里面已经被废弃了。
leeihcy 2013-09-13
  • 打赏
  • 举报
回复
应该是按参数个数进行划分的。0个参数的要写一个模板,1个参数的写一个模板,2个参数的写一个模板,不用管参数类型。
leeihcy 2013-09-13
  • 打赏
  • 举报
回复
你可以看看 stl 里的 bind1st bind2nd,看看它是怎么用模板解决这样的问题的。
  • 打赏
  • 举报
回复
引用 6 楼 zhoujielunzhimi 的回复:
http://bbs.csdn.net/topics/390590608 我这边写了个Task类。可以扩展成支持N个参数。
对于每一个参数不同的回调,你都要写一份大部分相同,就参数处理部分不同的回调吗? 这样就不是我想像的那种了。 我的目的,是想通过Template<class TObj, class TFunc>这一个来实现所有的closure 现在的问题是,我怎么让这个来辨别出,这个函数,有几个参数,参数类型分别是什么。 我有类似你这样的想法,对处理不同参数的closure,但是我觉得软件总是没法考虑周全的,想通过一种方式,让程序自己去动态。 其实boost::bind和boost::function可以实现。可是我这贱骨头就是想自己写一份,通过重复造轮子来学点东西。
sumos 2013-09-13
  • 打赏
  • 举报
回复
http://bbs.csdn.net/topics/390590608 我这边写了个Task类。可以扩展成支持N个参数。
  • 打赏
  • 举报
回复
引用 4 楼 guokefly 的回复:
void* _Func; 我觉得你这块能用 void* 那说明你也不知道_Func的实际的参数情况。 但是, 注册函数的用户调用函数的用户应该清楚实际的参数类型, 不然的话, 想MFC一样,给_Func做一个WParam, LParam参数。 所以这块可以用强制类型转换 因为_Func本质上是一块内存空间的地址……
对,我就是想,怎么实现让_Func知道它的参数 除了像MFC或者WPF一样,用wparam和lparam等,这什么更好的办法吗?
过客_匆匆 2013-09-13
  • 打赏
  • 举报
回复
void* _Func; 我觉得你这块能用 void* 那说明你也不知道_Func的实际的参数情况。 但是, 注册函数的用户调用函数的用户应该清楚实际的参数类型, 不然的话, 想MFC一样,给_Func做一个WParam, LParam参数。 所以这块可以用强制类型转换 因为_Func本质上是一块内存空间的地址……
  • 打赏
  • 举报
回复
引用 2 楼 allenhiman 的回复:
那你每个combobxo的item就应该包含对应的函数指针 SetItemData(*ptr) comobox有这个绑定的功能
这样是可以,但是我不想为每一项都在注册时候都SetItemData(*ptr)一下。 这样的话,如果我ComboBox有很多下拉项,每次 注册Item的时候,SetItemData(*ptr)就有很多重复,其实ptr指向同一个成员函数。 所以我就想,用个id指定对应的索引项,在处理的时候,全部走一个成员函数。 我是这么想的,如果点击到ComboBox上,自己算出点击在哪一项,然后把这一项的索引传递给对应的对调。
allenhiman 2013-09-13
  • 打赏
  • 举报
回复
那你每个combobxo的item就应该包含对应的函数指针 SetItemData(*ptr) comobox有这个绑定的功能
  • 打赏
  • 举报
回复
沙发留给自己。 就GUI牛人解答

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧