SOUI中提供了大部分常用的win32标准控件的实现,如pushbutton, checkbox, radiobox, edit, richedit, listbox, combobox, treectrl, listctrl (report), hotkeyctrl等。

大部分控件在接收用户输入后,会发生状态的改变,并以事件的形式传递给UI的所有者。

在SOUI中提供了两种处理事件的方式:

1、在SHostWnd的派生类中重载

    virtual BOOL SHostWnd::_HandleEvent(SOUI::EventArgs *pEvt){return FALSE;}

为了更方便的处理事件,SOUI提供了一组宏来构造这个事件处理函数,从而提供一种类似消息映射的事件处理形式。

如demo的CMainDlg中的实现:

    //UI控件的事件及响应函数映射表
EVENT_MAP_BEGIN()
EVENT_ID_COMMAND(, OnClose)
EVENT_ID_COMMAND(, OnMaximize)
EVENT_ID_COMMAND(, OnRestore)
EVENT_ID_COMMAND(, OnMinimize)
EVENT_NAME_CONTEXTMENU(L"edit_1140",OnEditMenu)
EVENT_NAME_COMMAND(L"btn_msgbox",OnBtnMsgBox)
EVENT_NAME_COMMAND(L"btnSelectGif",OnBtnSelectGIF)
EVENT_NAME_COMMAND(L"btn_menu",OnBtnMenu)
EVENT_NAME_COMMAND(L"btn_webkit_go",OnBtnWebkitGo)
EVENT_NAME_COMMAND(L"btn_webkit_back",OnBtnWebkitBackward)
EVENT_NAME_COMMAND(L"btn_webkit_fore",OnBtnWebkitForeward)
EVENT_NAME_COMMAND(L"btn_webkit_refresh",OnBtnWebkitRefresh)
EVENT_NAME_COMMAND(L"btn_hidetst",OnBtnHideTest)
EVENT_NAME_COMMAND(L"btn_insert_gif",OnBtnInsertGif2RE)
EVENT_MAP_END()

上面的EVENT_MAP_BEGIN()和EVENT_MAP_END()结合构造出一个_HandleEvent函数的实现,具体可以自己展开这两个宏查看代码。

同时SOUI也提供了一组解析SOUI::EventArgs *pEvt的宏,如上例中的EVENT_NAME_COMMAND, EVENT_ID_COMMAND等。

帮助用户直接从控件的name或者ID属性映射到消息响应函数。

这种事件响应方式最大的好处是能够集中处理事件的分发,方便阅读代码,同时也和传统的MFC,WTL的编程风格类似,降低用户的学习成本。

2、采用事件订阅的方式响应控件事件

虽然事件映射表提供了一种简单有效的事件响应机制,由于事件映射表是一种编译期形成的静态的映射表,对于在运行期动态创建的控件的事件响应就无能为力了。

在MFC中,程序员通过要重载窗口类的DefWindowProc来处理运行期间动态创建的控件发来的消息。

这种方式灵活性够了,但是不够优雅,要在一个函数里做大量的swich分枝,导致这个处理函数很难维护。

设计模式里的观察者模式可以比较好的解决这个问题。

为些在SOUI中我提供了一种事件订阅的事件处理模式。

我们先看一下demo中怎样处理列表控件的表头点击来执行排序操作:

void CMainDlg::InitListCtrl()
{
//找到列表控件
SListCtrl *pList=FindChildByName2<SListCtrl>(L"lc_test");
if(pList)
{
//列表控件的唯一子控件即为表头控件
SWindow *pHeader=pList->GetWindow(GSW_FIRSTCHILD);
//向表头控件订阅表明点击事件,并把它和OnListHeaderClick函数相连。
pHeader->GetEventSet()->subscribeEvent(EVT_HEADER_CLICK,Subscriber(&CMainDlg::OnListHeaderClick,this));
//省略列表初始化代码
}
} //表头点击事件处理函数
bool CMainDlg::OnListHeaderClick(EventArgs *pEvtBase)
{
//事件对象强制转换
EventHeaderClick *pEvt =(EventHeaderClick*)pEvtBase;
SHeaderCtrl *pHeader=(SHeaderCtrl*)pEvt->sender;
//从表头控件获得列表控件对象
SListCtrl *pList= (SListCtrl*)pHeader->GetParent();
//列表数据排序
SHDITEM hditem;
hditem.mask=SHDI_ORDER;
pHeader->GetItem(pEvt->iItem,&hditem);
pList->SortItems(funCmpare,&hditem.iOrder);
return true;
}

通过事件订阅可以在运行时方便的将一个控件的事件关联到一个处理函数上,当然也可以随时取消订阅。

同时事件订阅也是在脚本中响应控件事件的唯一方式(关于在SOUI中使用LUA脚本将在后续讲解)。

第八篇:SOUI中控件事件的响应的更多相关文章

  1. 第二十七篇:SOUI中控件属性查询方法

    SOUI项目的SVN根目录下有一个doc目录,下面有一份控件属性表.包含了大部分控件的大部分属性,不过也不一定完全准确.最保险的办法还是查源代码. SOUI对象包含控件及ISkinObj等从SObje ...

  2. 第二十五篇:在SOUI中做事件分发处理

    不同的SOUI控件可以产生不同的事件.SOUI系统中提供了两种事件处理方式:事件订阅 + 事件处理映射表(参见第八篇:SOUI中控件事件的响应) 事件订阅由于直接将事件及事件处理函数连接,不存在事件分 ...

  3. Dev中控件的js事件代码放在form标签中存在问题

    Dev中控件的js事件代码放在form标签中会获取不到(head标签中有其他js代码,未验证是否是这个问题)

  4. 第二十八篇:SOUI中自定义控件开发过程

    在SOUI中已经提供了大部分常用的控件,但是内置控件不可能满足用户的所有要求,因此一个真实的应用少不得还要做一些自定义控件. 学习一个新东西,最简单的办法就是依葫芦画瓢.事实上在SOUI系统中内置控件 ...

  5. 利用ICommand和ITool重写Arcengine中控件的事件

    Arcengine窗体开发中,不同命令或者工具可能会触发同一控件的同一事件,这样会造成该事件中代码的混乱.以主窗体的AxMapcontrol控件为例,当开始画图时因为有很多种类型的Feature,所以 ...

  6. 第八篇 Integration Services:高级工作流管理

    本篇文章是Integration Services系列的第八篇,详细内容请参考原文. 简介在前面两篇文章,我们创建了一个新的SSIS包,学习了SSIS中的脚本任务和优先约束,并检查包的MaxConcu ...

  7. Android开源项目第一篇——个性化控件(View)篇

    本文为那些不错的Android开源项目第一篇——个性化控件(View)篇,主要介绍Android上那些不错个性化的View,包括ListView.ActionBar.Menu.ViewPager.Ga ...

  8. duilib中控件拖拽功能的实现方法(附源码)

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41144283 duilib库中原本没有显示的对控件增加拖拽的功能,而实际 ...

  9. Android开发UI之开源项目第一篇——个性化控件(View)篇

    原文:http://blog.csdn.net/java886o/article/details/24355907 本文为那些不错的Android开源项目第一篇——个性化控件(View)篇,主要介绍A ...

随机推荐

  1. 【leetcode】Dungeon Game

    Dungeon Game The demons had captured the princess (P) and imprisoned her in the bottom-right corner ...

  2. ACL

    http://man.chinaunix.net/linux/debian/debian_learning/ch01s04.html http://blog.csdn.net/xiangliangyu ...

  3. mysql中表名是order的CRUD的错误

    org.springframework.jdbc.BadSqlGrammarException: ### Error querying database. Cause: com.mysql.jdbc. ...

  4. wxpython 基本的控件 (文本)

    wxPython 工具包提供了多种不同的窗口部件,包括了本章所提到的基本控件.我们涉及静态文本.可编辑的文本.按钮.微调.滑块.复选框.单选按钮.选择器.列表框.组合框和标尺.对于每种窗口部件,我们将 ...

  5. iso网络各层协议

    (1)网卡的作用就是把数据进行串并转换(串连数据是比特流形式的,存在与本计算机内部,而计算机与计算机之间是通过帧形式的数据来进行数据传输的),MAC子层规定了如何在物理线路上传输的frame,LLC的 ...

  6. springMVC中ajax的使用

    springMVC中使用ajax有两种方法,第一种是根据servletAPI来使用ajax,第二种是根据springMVC给我们提供的API来使用. 一.根据servletAPI: springMVC ...

  7. codeforces 507B. Painting Pebbles 解题报告

    题目链接:http://codeforces.com/problemset/problem/509/B 题目意思:有 n 个piles,第 i 个 piles有 ai 个pebbles,用 k 种颜色 ...

  8. vs2010 快捷键大全

    vs2010 快捷键大全 VS2010版快捷键 Ctrl+E,D ----格式化全部代码 Ctrl+E,F ----格式化选中的代码 CTRL + SHIFT + B生成解决方案 CTRL + F7 ...

  9. JAVA回调接口的理解

    A类持有B接口的对象引用,B接口有一个callBack()方法,C类是B类的实现类,实现了callBack()方法,把C类传入A类,当A类执行完操作后调用callBack()方法,这时候A调用的就是C ...

  10. 【jquery】一个简单的单选、多选、全选、反选、删除的小功能

    对表格内容进行单行删除.单行选中.多行选中.全选.反选.删除选中行等操作 HTML代码 <table class="table table-bordered border-shadow ...