soui4js基于soui4设计实现。

首先我们看一下soui4中如何定义一个窗口类。

soui4最基本的窗口类是SHostWnd和SHostDialog,它需要一个布局xml。

假定布局xml在资源包中的位置为:layout:maindlg。

那么soui4中定义一个窗口可以是下面的代码(为了演示方便,这里使用SHostDialog):

SHostDialog dlg("layout:maindlg");
dlg.DoModal(NULL);

在soui4js中,这两个对象被导出为soui4.JsHostWnd, soui4.JsHostDialog。

如果不需要处理窗口消息或者事件,可以使用下面的方法来直接创建窗口:

let dlg = new soui4.JsHostDialog("layout:maindlg");
dlg.DoModal(0);

可以看出来,js的代码和C++代码基本上是一样的。

如果需要处理UI中的事件要如何处理呢?

在C++中,最简单的方法是从SHostDialog继承一个新的对象,然后使用消息或者事件映射表来响应窗口消息及控件的事件。

伪代码如下:

class CDemoDialog : public SHostDialog{
public:
CDemoDialog():SHostDialog("layout:maindlg"){}
//....
protected:
void OnBtnTest(){
SSLOGI()<<"test button click";
}
EVENT_MAP_BEGIN()
EVENT_NAME_COMMAND(L"btn_test", OnBtnTest)
EVENT_MAP_END()
};

EVENT_MAP_BEGIN, EVENT_MAP_END一起构成SHostDialog的事件响应虚函数,从而实现接管事件处理流程。

在js中,用法基本类似:

class OptionDlg extends soui4.JsHostDialog{
constructor(settings){
super("layout:maindlg");
this.onEvt = this.onEvent;//这一行实现事件处理的接管
} onBtnTest(){
console.log("test button click");
}
onEvent(e){
//事件处理函数,e是事件对象,可以使用GetID(),Sender()等来获取id及发送者
let evt_id = e.GetID();
switch(evt_id){
case soui4.EVT_CMD:
if(e.NameFrom()=="btn_test")
this.onBtnTest();
break;
}
}
}

这样就完成了窗口中事件的处理。

窗口消息处理也类似,只需要设定JsHostDialog.onMsg就可以接管消息处理。

SOUI中另一种常见的事件响应方法是事件订阅:

例如下面的代码实现订阅表头的子控件checkbox的点击事件:

 1 void CMainDlg::InitListCtrl()
2 {
3 //找到列表控件
4 SListCtrl *pList=FindChildByName2<SListCtrl>(L"lc_test");
5 if(pList)
6 {
7 //列表控件的唯一子控件即为表头控件
8 SWindow *pHeader=pList->GetWindow(GSW_FIRSTCHILD);
9 //向表头控件订阅表明点击事件,并把它和OnListHeaderClick函数相连。
10 pHeader->GetEventSet()->subscribeEvent(EVT_HEADER_CLICK,Subscriber(&CMainDlg::OnListHeaderClick,this));
11 }
12 }
13
14 //表头点击事件处理函数
15 BOOL CMainDlg::OnListHeaderClick(IEvtArgs *pEvtBase)
16 {
17 //事件对象强制转换
18 EventHeaderClick *pEvt =(EventHeaderClick*)pEvtBase;
19 SHeaderCtrl *pHeader=(SHeaderCtrl*)pEvt->Sender();
20 //从表头控件获得列表控件对象
21 SListCtrl *pList= (SListCtrl*)pHeader->GetParent();
22 //列表数据排序
23 SHDITEM hditem;
24 hditem.mask=SHDI_ORDER;
25 pHeader->GetItem(pEvt->iItem,&hditem);
26 pList->SortItems(funCmpare,&hditem.iOrder);
27 return true;
28 }
29 //以上代码来自soui4 demo

soui4js包含了一个SConnect方法,可以方便的订阅一个窗口的事件:

函数原型下下:

/**
* 将指定IWindow的指定事件对象连接到指定对象的事件处理方法
* @param pObj IWindow窗口
* @param evtId 事件类型
* @param jsThis 处理事件的对象
* @param jsFun 处理事件的方法
*/
export function SConnect(pObj:IWindow,evtId:number,jsThis:object,jsFun:(evt:IEvtArgs)=>boolean):boolean;

因此在js中可以使用下面的代码来实现事件订阅:

class MainDialog extend soui4.JsHostWnd
{
//...
init(){
soui4.SConnect(this.GetIRoot(),soui4.EVT_MENU_CMD,this,this.onMenuCmd);
}
onMenuCmd(e){
let menuCmd = soui4.toEventMenuCmd(e);
return true;
}
//...
}

具体代码,参考 https://github.com/soui4js-app/somine

认识soui4js(第4篇):定义一个窗口类,响应控件的事件的更多相关文章

  1. C#中一个窗口是一个类呢,还是一个窗口类的实例呢?(转)

    C#中一个窗口是一个类呢,还是一个窗口类的实例呢? 答: 没有一个人说到重点上. 一个窗口,它不是仅仅用一个类可以描述的: 首先,这个窗口的数据类型类型,是从Form类派生下来的,也就是说它的定义是一 ...

  2. 实验四 (1):定义一个形状类(Shape)方法:计算周长,计算面积

    (1)定义一个形状类(Shape)方法:计算周长,计算面积子类:矩形类(Rectangle) :额外的方法:differ() 计算长宽差圆形类(Circle)三角形类(Triangle)正方形类(Sq ...

  3. 定义一个Rectangle类,该类提供getLength和getWidth方法。

    import java.util.Comparator; /** * 定义一个Rectangle类,该类提供getLength和getWidth方法.利用图1-18中的findMax例程编写 * 一种 ...

  4. java定义一个Circle类,包含一个double型的radius属性代表圆的半径,一个findArea()方法返回圆的面积

    需求如下:(1)定义一个Circle类,包含一个double型的radius属性代表圆的半径,一个findArea()方法返回圆的面积. (2)定义一个类PassObject,在类中定义一个方法pri ...

  5. 定义一个Person类,其中包括:1.定义属性:姓名、年龄、民族作为成员变量。定义静态成员变量:人数2.定义构造方法:对成员变量进行初始化。3.定义多个方法:分别显示相应的属性值,例如getName(){System.out.print("名称="+name+";"); }4.定义一个方法“成长”:实现年龄的增加,每执行一次年龄增加1

    题目显示不全,完整题目描述: (1)定义一个Person类,其中包括:1.定义属性:姓名:年龄:民族作为成员变量.定义静态成员变量:人数2.定义构造方法:对成员变量进行初始化.3.定义多个方法:分别显 ...

  6. Java初学者作业——定义一个计算器类, 实现计算器类中加、 减、 乘、 除的运算方法, 每个方法能够接收2个参数。

    返回本章节 返回作业目录 需求说明: 定义一个计算器类, 实现计算器类中加. 减. 乘. 除的运算方法, 每个方法能够接收2个参数. 实现思路: 定义计算器类. 定义计算器类中加.减.乘.除的方法. ...

  7. 34 异常机制 异常体系结构 Java把异常当做对象来处理 并定义一个基类java.lang.Throwable作为所有异常的超类 Error Exception

    异常体系结构 概念 Java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类. 在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Erro ...

  8. 【Windows编程】系列第二篇:Windows SDK创建基本控件

    在Win32 SDK环境下,怎么来创建常用的那些基本控件呢?我们知道如果用MFC,简单的拖放即可完成大多数控件的创建,但是我们既然是用Windows SDK API编程,当然是从根上解决这个问题,实际 ...

  9. ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇

    原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇 第三章 为控件添加事件 好了,我们之前以前开发一个控件.而且也添加了属性,开发也很规范,但是那个控件还差最后一点:添加事件. 系列 ...

  10. ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇

    原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇 第三章 为控件添加事件 后篇 前一篇文章只是简单的说了下事件,但是大家应该方法,在ASP.NET自定义控件中只是简单那么定义事件是 ...

随机推荐

  1. [昌哥IT课堂]|欢迎 MySQL 9.0,回顾 Oracle 在 8.0 版中的管理(译)

    对于新兴技术和社区的管理是相对容易的.经过 29 年发展,MySQL 已成为全球数百万用户中使用最广泛且备受信任的开源数据库之一.在这一规模的社区领导中可能存在复杂性.我们努力寻求稳定和创新的平衡,为 ...

  2. axios获取上传进度报错xhr.upload.addEventListener is not a function

    错误问题 Vue:xhr.upload.addEventListener is not a function 这个问题是因为mockjs改动了axios里面XMLHttpRequest对象致使的 根据 ...

  3. 简单端口映射、转发、重定向工具之Rinetd

    ◆一.概述 Rinetd是为在一个Unix和Linux操作系统中为重定向传输控制协议(TCP)连接的一个工具.将 TCP 连接从一个 IP 地址和端口重定向到另一个.它处理文件中/etc/rinetd ...

  4. vue项目中如何加载markdown

    场景 今天忽然临时接到一个需求: 就是将markdown文件直接在vue项目中进行加载,并正常显示出来. 这......,我知道是可以进行加载markdown文件的. 但是我之前没有做过,答复的是:可 ...

  5. xtrabackup脚本

    xtrabackup是MySQL的一种物理备份工具,相对于mysqldump,备份和还原速度更快 , 我写了一份可以进行备份 + 还原的脚本 #!bin/bash all_bak_path=" ...

  6. 记一次cenos7安装nginx

    安装依赖 yum -y install gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel 下 ...

  7. ArkTs布局入门04——相对布局 & 媒体查询

    1.相对布局 1.1.概述 RelativeContainer为采用相对布局的容器,支持容器内部的子元素设置相对位置关系.子元素支持指定兄弟元素作为锚点,也支持指定父容器作为锚点,基于锚点做相对位置布 ...

  8. Gitlab 实现仓库完全迁移

    方法一:最快 gitlab用url导入注意事项看图 方法二 首先需要在新的服务服务器上新建一个项目 然后用 Git Bash 执行以下命令 git clone --mirror 项目原代码仓库地址 / ...

  9. Qt数据库应用8-数据导出组件示例说明

    一.前言 为了方便用户学习使用本组件,特意针对每个功能模块,每种可能的应用场景,都编写了对应的示例demo,从初级示例到中级示例再到高级示例以及多线程示例等,层层加码,针对结构体数据都做了相当详细细致 ...

  10. Qt音视频开发32-Onvif网络设置

    一.前言 用onvif协议来对设备的网络信息进行获取和设置,这个操作在众多的NVR产品中,用的很少,绝大部分用户都还是习惯直接通过摄像机的web页面进去配置,其实修改网络配置的功能在大部分的NVR中都 ...