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的脚本模块的更多相关文章

  1. 【转】PowerShell入门(十一):编写脚本模块

    转至:http://www.cnblogs.com/ceachy/archive/2013/03/08/PowerShell_Script_Module.html 现在通过编写模块就可以在PowerS ...

  2. 两款【linux字符界面下】显示【菜单】,【选项】的powershell脚本模块介绍

    两款[linux字符界面下]显示[菜单],[选项]的powershell脚本模块介绍 powershell linux  ps1 menu choice Multiselect 传教士 菜单 powe ...

  3. Linux下查看Python安装了哪些脚本模块

    Linux下查看Python安装了哪些脚本模块 1.什么是rpm ? rpm 即RedHat Package Management,是RedHat的发明之一 .现在包括OpenLinux.fedora ...

  4. msf客户端渗透(七):跳板、post模块、自动运行脚本

    跳板 假设有这样一个场景,有一个局域网内网网关是1.1.1.1,局域网里的主机1是kali,它经过一个防火墙连接到公网,主机2和主机3在另一个内网网关为2.1.1.1的局域网,由于防火墙做了设置,只有 ...

  5. 《Ansible权威指南》笔记(3)——Ad-Hoc命令集,常用模块

    五.Ad-Hoc命令集1.Ad-Hoc命令集通过/usr/bin/ansible命令实现:ansible <host-pattern> [options]    -v,--verbose  ...

  6. 【转】PowerShell入门(十二):编写PowerShell管理单元和二进制模块

    转至:http://www.cnblogs.com/ceachy/archive/2013/03/13/PowerShell_SnapIn.html PowerShell一开始就提出利用管理单元来实现 ...

  7. plain framework 1 参考手册 入门指引之 模块

    模块 总述 基础 数据库 引擎 事件 文件 网络 性能 脚本 系统 工具 总述 上图为plain framework(简称简约框架)所有的模块,包括基础.数据库.引擎.事件.文件.网络.性能.脚本.系 ...

  8. Linux Default Bootup、Startup、Autoload Configuration file(自启动服务脚本)

    目录 . Linux初始化init系统 . Linux配置文件自动加载过程 1. Linux初始化init系统 Linux初始化init系统在不同操作系统系列下的区别 . RHEL : SysVini ...

  9. 第二十四篇:导出SOUI对象到LUA脚本

    LUA是一种体积小,速度快的脚本语言.脚本语言虽然性能上和C++这样的Naitive语言相比差一点,但是开发速度快,可以方便的更新代码等,近年来受到了越来越多开发者的重视. 在SOUI框架中,我把脚本 ...

  10. 第二十三篇:在SOUI中使用LUA脚本开发界面

    像写网页一样做客户端界面可能是很多客户端开发的理想. 做好一个可以实现和用户交互的动态网页应该包含两个部分:使用html做网页的布局,使用脚本如vbscript,javascript做用户交互的逻辑. ...

随机推荐

  1. 一款绘制3D架构图的在线神器:iCraft Editor

    在软件开发的世界里,架构图是系统设计的蓝图,它们不仅帮助团队理解系统的整体结构,还能提升沟通效率,确保项目的顺利推进.然而,绘制一张清晰.直观的架构图,往往需要大量时间和专业工具.面对繁琐的操作和复杂 ...

  2. 如何进行个人wiki写作

    Wiki是一种内容管理系统,它的特点包括:多人协作模式.内容逐步积累.网状知识链接.而用作个人知识管理的个人wiki,就利用了内容逐步积累和网状知识链接这两个特点.因为是个人的,所以用不着协作. 怎么 ...

  3. JavaCC 研究与应用( 8000字 心得 源程序)

    一.JavaCC简介 JavaCC(Java Compiler Compiler)是一个用JAVA开发的最受欢迎的语法分析生成器.这个分析生成器工具可以读取上下文无关且有着特殊意义的语法并把它转换成可 ...

  4. golang之copier

    今天我们要介绍的copier库就能处理不同类型之间的赋值.除此之外,copier还能: 调用同名方法为字段赋值: 以源对象字段为参数调用目标对象的方法,从而为目标对象赋值(当然也可以做其它的任何事情) ...

  5. cento 申请ssl证书笔记

    如果您的Certbot工具没有内置的Nginx插件,您可以尝试以下方法来申请证书并配置Nginx服务器: 安装Certbot的Nginx插件: sudo yum install certbot-ngi ...

  6. C# 学习笔记 0415

    关于零碎的知识笔记总结,你可能需要知道的 一.Linq相关 Find()和First()与FirstOrDefault Find方法只能在List上使用,而后者能更广泛应用在IEnemerable上. ...

  7. Java 动态设置 JVM 参数的方法

    Java虚拟机(JVM)在运行Java应用时,其性能调优和资源管理至关重要.虽然许多JVM参数在启动时通过命令行设置,但在应用运行期间动态调整某些参数也是可行的.通过动态设置JVM参数,开发者可以更有 ...

  8. 怎么禁用 vscode 中点击 go 包名时自动打开浏览器跳转到 pkg.go.dev

    本文引用怎么禁用 vscode 中点击 go 包名时自动打开浏览器跳转到 pkg.go.dev 在 vscode 设置项中配置 gopls 的 ui.navigation.importShortcut ...

  9. 前端每日一知之BFC

    脑图在线链接 本文内容依据[js每日一题]公众号精彩文章总结而来

  10. Qt QTtoolButton 鼠标移动到按钮上时,弹出菜单后,按钮的hover状态无法恢复的问题

    需求:QTtoolButton 鼠标移到按钮上时,弹窗菜单,并且点击菜单或者其他地方,菜单关闭后,按钮的hover状态需要恢复原状. 1. 创建按钮和菜单,并安装事件过滤器 m_Menu = new ...