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. Node.js——Async

    一:流程控制 为了适应异步编程,减少回调的嵌套,我尝试了很多库.最终觉得还是async最靠谱. 地址:https://github.com/caolan/async Async的内容分为三部分: 流程 ...

  2. 数据库Error:The ScriptCollection in ScriptName not find

    System.InvalidOperationException: The ScriptCollection in ScriptName not find 在 WMI.SQL.HELPER.CONFI ...

  3. DataTemplate应用

    在WPF中,决定数据外观的是DataTemplate,即DataTemplate是数据内容的表现形式,一条数据显示成什么样子,是简单的文本还是直观的图形,就是由DataTemplate决定的.下面通过 ...

  4. 一名Delphi程序员的开发习惯

    一名Delphi程序员的开发习惯 有关开发习惯的一些想法,如鲠在喉,不吐不快.究其发贴动机,当然不排除有骗取参与分的可能,但另一方面,也希望能给同行(念Xing)者提供一些 建议,或者参考(希望不是误 ...

  5. java web 学习 --第九天(Java三级考试)

    第八天的学习内容如下:http://www.cnblogs.com/tobecrazy/p/3468458.html Java servlet 技术 Servlet是使用java servlet应用程 ...

  6. ACM/ICPC 之 枚举(POJ1681-画家问题+POJ1166-拨钟问题+POJ1054-讨厌的青蛙)

    POJ1681-画家问题 枚举的经典例题,枚举第一行即可,其余行唯一. //画家问题,y表示黄色,w表示白色,怎样让墙上所有方格为y,操作类似熄灯问题poj1222 //memory 136K Tim ...

  7. 原:[eclipse启动错误] JVM terminated.Exit code=2

    启动eclipse的时候忽然出现以下错误: 解决方案: 删除环境变量PATH或者Path中的 C:\ProgramData\Oracle\Java\javapath

  8. codeforces 515C. Drazil and Factorial 解题报告

    题目链接:http://codeforces.com/problemset/problem/515/C 题目意思:给出含有 n 个只有阿拉伯数字的字符串a(可能会有前导0),设定函数F(a) = 每个 ...

  9. 手动关闭searchDisplayControlelr

    两行代码搞定 [searchBar endEditing:YES]; [searchDisplayControllersetActive:NO];

  10. jsonp注意事项

    自己测试的: <?php ');                     }                 }); } </script>     <!DOCTYPE htm ...