使用SOUI4的脚本模块
SOUI4.1提供了全新的lua脚本模块支持,使用这个新版本的脚本模块,可以轻松将所有UI布局及业务逻辑全部使用XML+LUA实现,基本上就是一个超轻型浏览器。
SOUI4.0相对于SOUI3最大的区别就是将所有对外导出的必须模块都使用COM接口实现,使用这种技术,任意语言只要支持C接口都可以轻松的调用SOUI4的功能。
再结合lua和C语言交互的便利,我们将这些COM接口全部导出到LUA脚本,使得LUA脚本有了完全控制SOUI4的能力。
SOUI从1.0版本开始,就一直秉承着资源,布局,代码相分离的原则,再经过LUA脚本模块的处理,完全实现了在LUA脚本里加载资源,创建UI,实现业务逻辑全链条需求。
demo代码:https://github.com/soui4-demo/SLuaDemo
界面效果:
实现上面的界面,首先需要一个资源包,在资源包中使用XML定义好布局。
接下来我们使用一个C++工程装配好所必须的模块,核心代码很简单:
1 int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int /*nCmdShow*/)
2 {
3 HRESULT hRes = OleInitialize(NULL);
4 SASSERT(SUCCEEDED(hRes));
5 SetDefaultDir();
6 int nRet = 0;
7 {
8 SouiFactory souiFac;
9 SComMgr comMgr;
10 SApplication *theApp = InitApp(comMgr,hInstance);
11 LoadSystemRes(theApp,souiFac);//load system resource
12 LoadLUAModule(theApp,comMgr); //load lua script module.
13 {
14 SAutoRefPtr<IScriptModule> script;
15 theApp->CreateScriptModule(&script); //create a lua instance
16 script->executeScriptFile("main.lua");//load lua script
17 TCHAR szDir[MAX_PATH];
18 GetCurrentDirectory(MAX_PATH,szDir);
19 SStringA strDir = S_CT2A(szDir);
20 nRet = script->executeMain(hInstance,strDir.c_str(),NULL);//execute the main function defined in lua script
21 }
22 theApp->Release();
23 }
24 OleUninitialize();
25 return nRet;
26 }
上面代码没有任何业务逻辑,只是组装一下必须的组件,然后调用了一个main.lua中的main函数。
所有逻辑都在main.lua脚本中。
1 function onBtnClose(e)
2 slog("onBtnClose");
3 local hostWnd = GetHostWndFromObject(e:Sender());
4 hostWnd:DestroyWindow();
5 PostQuitMessage();
6 end
7
8 function onBtnMin(e)
9 slog("onBtnMin");
10 local hostWnd = GetHostWndFromObject(e:Sender());
11 hostWnd:SendMessage(0x112,0xf020);
12 end
13
14 function onBtnRestore(e)
15 slog("onBtnRestore");
16 local hostWnd = GetHostWndFromObject(e:Sender());
17 local btnMax = hostWnd:FindIChildByNameA("btn_max",-1);
18 local btnRestore = hostWnd:FindIChildByNameA("btn_restore",-1);
19 btnMax:SetVisible(1,1);
20 btnRestore:SetVisible(0,1);
21 hostWnd:SendMessage(0x112,0xf120);
22 end
23
24 function onBtnMax(e)
25 slog("onBtnMax");
26 local hostWnd = GetHostWndFromObject(e:Sender());
27 local btnMax = hostWnd:FindIChildByNameA("btn_max",-1);
28 local btnRestore = hostWnd:FindIChildByNameA("btn_restore",-1);
29 btnMax:SetVisible(0,1);
30 btnRestore:SetVisible(1,1);
31 hostWnd:SendMessage(0x112,0xf030);
32 end
33
34 function onLvBtnClick(e)
35 slog("onLvBtnClick");
36 local pBtn = toSWindow(e:Sender());
37 local pRoot = pBtn:GetIRoot();
38 local iPanel = QiIItemPanel(pRoot);
39 local index = iPanel:GetItemIndex();
40 SMessageBox(GetActiveWindow(),T("you had clicked " .. index .."item"),T"soui lua",0);
41 end
42
43 listview_count = 1000;
44
45 function lv_getView(strCtx, iPos, pItemPanel, xmlTemplate)
46 local pItem = pItemPanel;
47 local nChilds = pItem:GetChildrenCount();
48 if(nChilds == 0) then
49 pItem:InitFromXml(xmlTemplate);
50 end
51 local pTxt = pItem:FindIChildByNameA("lv_txt1",-1);
52 pTxt:SetWindowText(T("hello lua " .. iPos));
53 local pBtn = pItem:FindIChildByNameA("lv_btn1",-1);
54 LuaConnect(pBtn,10000,"onLvBtnClick");
55 end
56
57 function lv_getCount(strCtx)
58 return listview_count;
59 end
60
61 function initListview(hostWnd)
62 slog("init listview");
63 local lvTst = hostWnd:FindIChildByName(L"lv_test",-1);
64 local ilvTst = QiIListView(lvTst);
65
66 local adapter = CreateLvAdapter(100);--100 as the context id for the listview
67 adapter:initCallback(0,"lv_getView");
68 adapter:initCallback(1,"lv_getCount");
69
70 ilvTst:SetAdapter(adapter);
71 adapter:Release();
72 ilvTst:Release();
73 end
74
75 function onBtnResetLv(e)
76 slog("onBtnResetLv");
77 local hostWnd = GetHostWndFromObject(e:Sender());
78 local lvTst = hostWnd:FindIChildByName(L"lv_test",-1);
79 local ilvTst = QiIListView(lvTst);
80 local adapter = ilvTst:GetAdapter();
81 local luaAdapter = toLuaLvAdapter(adapter); -- cast from ILvAdapter to LuaLvAdapter
82 slog("list view context =" .. luaAdapter:getContext());
83 listview_count = 5;
84 luaAdapter:notifyDataSetChanged();
85 ilvTst:Release();
86 end
87
88 function onBtnMenu(e)
89 slog("onBtnMenu");
90 local hostWnd = GetHostWndFromObject(e:Sender());
91 local btn = toSWindow(e:Sender());
92 local souiFac = CreateSouiFactory();
93 local menu = souiFac:CreateMenu(0);
94 souiFac:Release();
95 menu:LoadMenu(T"smenu:menu_test");
96 local rcBtn = btn:GetWindowRect2();
97 SClientToScreen(hostWnd,rcBtn);
98 local cmd = TrackPopupIMenu(menu,0x100,rcBtn.left,rcBtn.bottom,100); --ox100 == TPM_RETURNCMD
99 menu:Release();
100 slog("cmd ret ".. cmd);
101 end
102
103 function onBtnMenuEx(e)
104 slog("onBtnMenuEx");
105 local hostWnd = GetHostWndFromObject(e:Sender());
106 local btn = toSWindow(e:Sender());
107 local souiFac = CreateSouiFactory();
108 local menu = souiFac:CreateMenuEx();
109 souiFac:Release();
110 menu:LoadMenu(T"smenu:menuex_test");
111 local rcBtn = btn:GetWindowRect2();
112 SClientToScreen(hostWnd,rcBtn);
113 local cmd = TrackPopupIMenuEx(menu,0x100,rcBtn.left,rcBtn.bottom,100); --ox100 == TPM_RETURNCMD
114 menu:Release();
115 slog("cmd ret ".. cmd);
116 end
117
118 function onSlidePos(e)
119 local data=toStEventSliderPos(e:Data());
120 local hostWnd = GetHostWndFromObject(e:Sender());
121 local txt = hostWnd:FindIChildByNameA("txt_pos",-1);
122 txt:SetWindowText(T("".. data.nPos));
123 end
124
125 function onBtnInitTreectrl(e)
126 slog("onBtnInitTreectrl");
127 local hostWnd = GetHostWndFromObject(e:Sender());
128 local treeWnd = hostWnd:FindIChildByName(L"tree_test",-1);
129 local treeCtrl = QiITreeCtrl(treeWnd);
130 treeCtrl:RemoveAllItems();
131 local item1= treeCtrl:InsertItem(T"hello",0,1,100,0xffff0000,0xffff0002); --0xffff0000 == STVI_ROOT, 0xffff0002==STVI_LAST
132 treeCtrl:InsertItem(T"lua",0,1,100,item1,0xffff0002);
133 end
134
135 function onBtnDialog(e)
136 slog("onBtnDialog");
137 local btnSender = toSWindow(e:Sender());
138 local hParent = btnSender:GetHostHwnd();
139 local souiFac = CreateSouiFactory();
140 local dialog = souiFac:CreateHostDialog(T"layout:dlg_test");
141 souiFac:Release()
142 local ret = dialog:DoModal(hParent);
143 dialog:Release();
144 end
145
146 function on_toggle(e)
147 slog("on toggle");
148 local hostWnd = GetHostWndFromObject(e:Sender());
149 local leftPane = hostWnd:FindIChildByName(L"pane_left",-1);
150
151 local toggle = toSWindow(e:Sender());
152 local isChecked = toggle:IsChecked();
153 local theApp = GetApp();
154 local anim;
155 if(isChecked == 1) then
156 slog("on toggle true".. isChecked);
157 anim = theApp:LoadAnimation(T"anim:slide_show");
158 else
159 slog("on toggle false".. isChecked);
160 anim = theApp:LoadAnimation(T"anim:slide_hide");
161 end
162 leftPane:SetAnimation(anim);
163 anim:Release();
164 end
165
166 function main(hinst,strWorkDir,strArgs)
167 slog("main start");
168 local souiFac = CreateSouiFactory();
169 local resProvider = souiFac:CreateResProvider(1);-- 1 = res_file
170 InitFileResProvider(resProvider,strWorkDir .."\\uires");
171 local theApp = GetApp();
172 local resMgr = theApp:GetResProviderMgr();
173 resMgr:AddResProvider(resProvider,T"uidef:xml_init");
174 resProvider:Release();
175
176 local hostWnd = souiFac:CreateHostWnd(T"LAYOUT:dlg_main");
177 local hwnd = GetActiveWindow();
178 hostWnd:Create(hwnd,0,0,0,0);
179 hostWnd:ShowWindow(1); --1==SW_SHOWNORMAL
180 initListview(hostWnd);
181
182 local btnClose = hostWnd:FindIChildByNameA("btn_close",-1);
183 LuaConnect(btnClose,10000,"onBtnClose"); --10000 == EVT_CMD
184
185 local btnMax = hostWnd:FindIChildByNameA("btn_max",-1);
186 LuaConnect(btnMax,10000,"onBtnMax");
187
188 local btnRestore = hostWnd:FindIChildByNameA("btn_restore",-1);
189 LuaConnect(btnRestore,10000,"onBtnRestore");
190
191 local btnMin = hostWnd:FindIChildByNameA("btn_min",-1);
192 LuaConnect(btnMin,10000,"onBtnMin");
193
194 local btnMenu = hostWnd:FindIChildByNameA("btn_menu",-1);
195 LuaConnect(btnMenu,10000,"onBtnMenu");
196
197 local btnMenuEx = hostWnd:FindIChildByNameA("btn_menuex",-1);
198 LuaConnect(btnMenuEx,10000,"onBtnMenuEx");
199
200 local btnResetLv = hostWnd:FindIChildByNameA("btn_reset_lv",-1);
201 LuaConnect(btnResetLv,10000,"onBtnResetLv");
202
203 local btnInitTreeCtrl = hostWnd:FindIChildByNameA("btn_init_treectrl",-1);
204 LuaConnect(btnInitTreeCtrl,10000,"onBtnInitTreectrl");
205
206 local slider = hostWnd:FindIChildByNameA("tst_slider",-1);
207 LuaConnect(slider,17000,"onSlidePos");--17000==EVT_SLIDERPOS
208
209 local btnDialog = hostWnd:FindIChildByNameA("btn_dialog",-1);
210 LuaConnect(btnDialog,10000,"onBtnDialog");
211
212 local btnSwitch = hostWnd:FindIChildByNameA("tgl_left",-1);
213 LuaConnect(btnSwitch,10000,"on_toggle");
214
215 souiFac:Release();
216
217 slog("main done");
218 return theApp:Run(hostWnd:GetHwnd());
219 end
这个main.lua演示了怎么处理按钮,sliderbar, text, treectrl, listview等控件的简单使用方法,其它控件使用方法类似。
要知道这个lua脚本模块导出了哪些接口到LUA,可以查看soui4代码中scriptmodule-lua模块。
soui4代码仓库:https://github.com/soui4/soui 或者 https://gitee.com/setoutsoft/soui4
使用SOUI4的脚本模块的更多相关文章
- 【转】PowerShell入门(十一):编写脚本模块
转至:http://www.cnblogs.com/ceachy/archive/2013/03/08/PowerShell_Script_Module.html 现在通过编写模块就可以在PowerS ...
- 两款【linux字符界面下】显示【菜单】,【选项】的powershell脚本模块介绍
两款[linux字符界面下]显示[菜单],[选项]的powershell脚本模块介绍 powershell linux ps1 menu choice Multiselect 传教士 菜单 powe ...
- Linux下查看Python安装了哪些脚本模块
Linux下查看Python安装了哪些脚本模块 1.什么是rpm ? rpm 即RedHat Package Management,是RedHat的发明之一 .现在包括OpenLinux.fedora ...
- msf客户端渗透(七):跳板、post模块、自动运行脚本
跳板 假设有这样一个场景,有一个局域网内网网关是1.1.1.1,局域网里的主机1是kali,它经过一个防火墙连接到公网,主机2和主机3在另一个内网网关为2.1.1.1的局域网,由于防火墙做了设置,只有 ...
- 《Ansible权威指南》笔记(3)——Ad-Hoc命令集,常用模块
五.Ad-Hoc命令集1.Ad-Hoc命令集通过/usr/bin/ansible命令实现:ansible <host-pattern> [options] -v,--verbose ...
- 【转】PowerShell入门(十二):编写PowerShell管理单元和二进制模块
转至:http://www.cnblogs.com/ceachy/archive/2013/03/13/PowerShell_SnapIn.html PowerShell一开始就提出利用管理单元来实现 ...
- plain framework 1 参考手册 入门指引之 模块
模块 总述 基础 数据库 引擎 事件 文件 网络 性能 脚本 系统 工具 总述 上图为plain framework(简称简约框架)所有的模块,包括基础.数据库.引擎.事件.文件.网络.性能.脚本.系 ...
- Linux Default Bootup、Startup、Autoload Configuration file(自启动服务脚本)
目录 . Linux初始化init系统 . Linux配置文件自动加载过程 1. Linux初始化init系统 Linux初始化init系统在不同操作系统系列下的区别 . RHEL : SysVini ...
- 第二十四篇:导出SOUI对象到LUA脚本
LUA是一种体积小,速度快的脚本语言.脚本语言虽然性能上和C++这样的Naitive语言相比差一点,但是开发速度快,可以方便的更新代码等,近年来受到了越来越多开发者的重视. 在SOUI框架中,我把脚本 ...
- 第二十三篇:在SOUI中使用LUA脚本开发界面
像写网页一样做客户端界面可能是很多客户端开发的理想. 做好一个可以实现和用户交互的动态网页应该包含两个部分:使用html做网页的布局,使用脚本如vbscript,javascript做用户交互的逻辑. ...
随机推荐
- CommonsCollections5(基于ysoserial)
环境准备 JDK1.8(8u421)我以本地的JDK8版本为准.commons-collections(3.x 4.x均可这里使用3.2版本) cc3.2: <dependency> &l ...
- 我的neovim配置
init.vim " Vim with all enhancements "文件管理器,我想试一下ranger syntax enable syntax on let maplea ...
- linux学习用到的命令
创建快件方式 ln 创建目录的快件方式 sudo ln -s /root/myhack/ /root/Desktop以上指令是创建软链接到桌面. ln -s /mnt/hgfs/VMware_shar ...
- mvn eclipse:eclipse -Dwtpversion=2.0 -DdownloadSources=true -DdownloadJavadocs=true -DjdkLevel=1.6
mvn eclipse:eclipse -Dwtpversion=2.0 -DdownloadSources=true -DdownloadJavadocs=true -DjdkLevel=1.6
- 六、FreeRTOS学习笔记-任务挂起和恢复
任务的挂起与恢复的API函数介绍 API函数 描述 vTaskSuspend() 挂起任务 vTaskResume() 恢复被挂起的任务 xTaskResumeFromISR() 在中断中恢复被挂起的 ...
- 一文搞懂flex(弹性盒布局)
1.什么是弹性布局 Flex是Flexible Box的缩写,翻译成中文就是"弹性盒子",用来为盒装模型提供最大的灵活性.任何一个容器都可以指定为Flex布局. 她是一种现代的CS ...
- L4168爱普生打印机重新刷机解决printer mode问题
同事的一台EPSON L4168打印机出现无法打印的故障,显示printer mode.使用官网的升级工具,在更新升级模式下(用电源+左+下+三角形四个手指按住开启)刷机,重启问题依旧(仍然显示pri ...
- 设计模式【3.3】-- CGLIB动态代理源码解读
cglib 动态代理 cglib介绍 CGLIB 是一个开源项目,一个强大高性能高质量的代码生成库,可以在运行期拓展 Java 类,实现 Java 接口等等.底层是使用一个小而快的字节码处理框架 AS ...
- C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...
- RabbitMQ快速入门 整合 SpringBoot
RabbitMQ快速入门 整合 SpringBoot 概述 大多应用中,可通过消息服务中间件来提升系统异步通信.扩展解耦能力.流量削峰 消息服务中两个重要概念: 消息代理(`message broke ...