第八篇:SOUI中控件事件的响应

时间:2022-12-30 23:08:36

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开源项目第一篇——个性化控件&lpar;View&rpar;篇

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

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

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

  9. Android开发UI之开源项目第一篇——个性化控件&lpar;View&rpar;篇

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

随机推荐

  1. Location对象、History对象

    Location对象: Window对象的location属性引用的是Location对象,它表示窗口中当前显示的内容的URL,Document对象的location属性也引用Location对象,w ...

  2. Grovvy初识

    1.Groovy和Java对比 Groovy的松散的语法允许省略分号和修饰符 除非另行指定,Grovvy的所有内容都为public Grovvy允许定义简单脚本,同时无需定义正规的class对象 Gr ...

  3. 201521123087《Java程序设计》 第八周学习总结

    1. 本周学习总结 2. 书面作业 本次作业题集集合 List中指定元素的删除(题目4-1)1.1 实验总结                                               ...

  4. &period;NET Core 微服务实例

    关于微服务,MSDN给出了定义和架构图:https://docs.microsoft.com/zh-cn/azure/architecture/guide/architecture-styles/mi ...

  5. LeetCode高频148错题记录

    3. Max Points on a Line 共线点个数3种解法 思路一:思考如何确定一条直线,两点法,确定斜率后带入一点.有三种情况,1. 两点重合,2. 斜率不存在,3. 正常算,依次以每个点为 ...

  6. Ubuntu 16&period;04&period;4 LTS &plus; Ambari 2&period;6&period;1&period;5 &plus; HDP 2&period;6&period;4&period;0 安装部署

    服务器 主机名 master slave1 slave2 slave3 IP 192.168.1.40 192.168.1.41 192.168.1.42 192.168.1.43 离线包服务器: 1 ...

  7. hive 桶表

    转自:https://blog.csdn.net/csdnliuxin123524/article/details/81052974 桶表(bucket table): 原理: 分区表是按照经常查询的 ...

  8. 【343】MathJax、LaTex、Mathml 数学公式

    参考:cnblog中添加数学公式支持 分类参考: 1. 基本功能 MathJax 我的LaTeX入门 MathJax basic tutorial and quick reference 分段函数:矩 ...

  9. Candy leetcode java

    题目: There are N children standing in a line. Each child is assigned a rating value. You are giving c ...

  10. Q147 对链表进行插入排序

    插入排序的动画演示如上.从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示). 每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中. 插入排序算法: 插入排序 ...