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. jQuery清除文本框,内容并设置不可用

    JQuery清除文本框,内容并设置不可用  如果是设置只读,则将disabled换成readonly function CleanText(textid) { $("#"+text ...

  2. ubuntu下查找某个文件的路径

    参考:ubuntu下如何查找某个文件的路径      http://blog.csdn.net/lieyanhaipo/article/details/17055667 在Ubuntu有时候会遇到记得 ...

  3. poj 1326

    http://poj.org/problem?id=1326 一个模拟的水题 题意就是要你算飞行的英里数. F代表头等舱,为实际飞行的英里数的2倍. B为商务舱,为实际飞行的英里数的1.5倍. Y为经 ...

  4. spring boot redis缓存JedisPool使用

    spring boot redis缓存JedisPool使用 添加依赖pom.xml中添加如下依赖 <!-- Spring Boot Redis --> <dependency> ...

  5. emoji表情初探

    2015年12月28日 14:24:51 星期一 首先注意的地方: 1. emoji是需要操作系统支持的, 例如: ios更新时, 会在升级日志里说明, 增加了对多少个emoji图标的支持. 原理上是 ...

  6. 【故障处理】mysql出现大量slave bin日志,将磁盘空间占满

    master服务器IO线程 NO  问题描述:造成大量slave bin 日志 大量占用磁盘 排查解决步骤: 1.检查是配置的问题还是mysql数据库本身的故障 2.将master的机器 mysql_ ...

  7. shell变量判空几种方法

    强烈声明:关于对数字的比较以及判断是否为空 最好在外层添加""引起来,这样可以避免空与其他字符比较时报错的问题. 1. 变量通过" "引号引起来 #!/bin/ ...

  8. ASM:《X86汇编语言-从实模式到保护模式》5-7章:汇编基础

    第5-7章感觉是这一本书中比较奇怪的章节,可能是作者考虑到读者人群水平的差异,故意由浅入深地讲如何在屏幕上显示字符和使用mov,jmp指令等等,但是这样讲的东西有点重复,而且看了第六,第七章以后,感觉 ...

  9. 绿色通道(codevs 3342)

    题目描述 Description <思远高考绿色通道>(Green Passage, GP)是唐山一中常用的练习册之一,其题量之大深受lsz等许多oiers的痛恨,其中又以数学绿色通道为最 ...

  10. 从数据库导出数为生成excel表

    mysql -umaster -hxx.xx.xx.xx -p -e "set names utf8; use xxxdb;select * from t_order where t_ord ...