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
标签:脚本,end,FindIChildByNameA,hostWnd,slog,SOUI4,模块,btn,local From: https://www.cnblogs.com/setoutsoft/p/16841661.html