使用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做用户交互的逻辑. ...
随机推荐
- gh-ost工具在线改表过程的详细解析
gh-ost,是github开源的一款在线修改MySQL表结构的工具https://github.com/github/gh-ost/,它不使用pt-osc的触发器机制,而是使用解析binlog来实现 ...
- 鸿蒙UI开发快速入门 —— part09: 应用级状态管理LocalStorage & AppStorage
1.说在前面的话 前面几个章节中介绍的装饰器(@State.@Props.@Link.@Provide.@Consume.@Observed.@ObjectLink)仅能在页面内,即一个组件树上共享状 ...
- nginx的子路径重写替换
在nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url加/,表示绝对根路径:如果没有/,表示相对路径,把匹配的路径部分也给代理走. 假设下面四种情况分别用 http ...
- 【CLS数据淘金第四期】网络流日志-云联网日志分析
导语 云联网(Cloud Connect Network,CCN)云联网覆盖全球 20+ 地域,提供云上私有网络间(VPC).VPC 与本地数据中心间(IDC)内网互联的服务,具备全网多点互联.路由自 ...
- 3.QMainWindow
QMainWindow介绍 QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar),多个工具栏(tool bars),多个铆接部件(dock widgets),一个状 ...
- 中电金信:技术实践|Flink维度表关联方案解析
导语:Flink是一个对有界和无界数据流进行状态计算的分布式处理引擎和框架,主要用来处理流式数据.它既可以处理有界的批量数据集,也可以处理无界的实时流数据,为批处理和流处理提供了统一编程模型. 维 ...
- 架构发展趋势以及 d2js 的未来
目前架构有几个热点方向:微服务, dubbo, Faas,还有 TiDB. 现在开发模式是前后端分离基本成为行规. 应该说以大部分企业业务量级.人员规模来说,要去和淘宝等大厂去对标是非常傻的.对大部分 ...
- hibernate错误org.hibernate.AnnotationException: No identifier specified for entity:
实体类继承BaseEntity时报错.解决方法:在属性或者get方法上加@Id@Id@GeneratedValue(strategy=GenerationType.AUTO)@Column(uniqu ...
- 免费学习基于SpringBoot的高考志愿智能推荐系统
免费学习基于SpringBoot的高考志愿智能推荐系统 摘要 科学技术日新月异,人们的生活都发生了翻天覆地的变化,高考志愿智能推荐系统管理当然也不例外.过去的信息管理都使用传统的方式实行,既花费了时间 ...
- .NET周刊【12月第3期 2024-12-15】
国内文章 重磅推出 Sdcb Chats:一个全新的开源大语言模型前端 https://www.cnblogs.com/sdcb/p/18597030/sdcb-chats-intro Sdcb Ch ...