前一節,分析了三種界面美化方案,都是控件級的美化。今天再來分析一下窗口級的美化。上一次講的DirectUI,你們反響通常,效果和創新都不足。那是沒有講完的原故。今天……仍是沒有講完,不過效果應該還行吧:)。html
Hook的方式使用DirectUI,是侷限在控件裏。若是建立一個相似Canvas的可視控件,把全部控件包裝在一個(或幾個)控件裏面,我把這種方式稱之包裝(Wrap)。前端
在現有界面上改造,不須要改動原有代碼,只需在界面open事件中打開u_dui控件,並of_load("ui.xml")便可,全部消息轉到相應名稱的控件的事件中。ui.xml是DirectUI的界面定義文件,以下圖(全部資源來源於網絡)node
相比DirectUI的界面包裝,WebUI的界面包裝更爲流行。使用Web控件替代原有控件,能夠作出很是好的效果。編程
Sciter及其前身HtmlLayout,都是大名鼎鼎的WebUI控件,使用普遍。Sciter的Powerbuilder封裝,在PowerFramework中有提供。緩存
Sciter是最先一批專業的WebUI解決方案,相比Cef近百兆的體積,它的只有幾兆。因此在通用軟件中普遍使用。前端框架
Sciter的缺點就是不徹底與Js兼容,在體積與速度方面有優點,在兼容性方面就有劣勢了。因爲前端飽受IE的折磨,建議對體積與速度方面不太敏感的應用不要使用。網絡
Sciter的效果仍是很讚的,下圖是QQ動態登陸界面。框架
Miniblink是這兩年冒出的嵌入式Web新秀,更新很是快,因此用起來很放心。它的大小20多兆,比Cef小不少,並且使用的是比較新的Chrome內核版本,相比Sciter,Miniblink幾乎沒有兼容性的問題。能夠順利運行幾乎全部的前端框架。測試
PowerFramework也封裝了Miniblink,並且還全面導出了Powerbuilder的JS接口,使用方便。在PowerPlume裏面,也封裝了Miniblink(u_wui),可是沒有像n_lua對象,或者PowerFramework同樣導出JS接口。至於爲何,往下看就知道了。使用效果以下圖:動畫
前面所說的包裝(Wrap)所有都手工進行的,就是手工編寫相應的XML,或者HTML。對於個別的界面美化是可行的,若是對於大型管理軟件作這樣的美化修改是不可能的。界面的數量太多,手工編寫工做量太大,並且測試工做量一樣巨大。這時,咱們要求對現有界面進行自動包裝,生成相應的XML或者HTML。
DriectUI的自動包裝工做,比較好作。只需在控件的相應位置,添加一個控件,把原有控件置爲底層便可。
u_dui控件使用方法以下:
1 if not isvalid(iu_dui) then 2 cb_unwrap.event clicked() 3 OpenUserObject(iu_dui, "u_dui", 0, 0) 4 iu_dui.of_load("ui2.xml") 5 6 iu_dui.of_wrap(cb_dui, "") 7 iu_dui.of_wrap(cb_wui, "") 8 iu_dui.of_wrap(cb_unwrap, "") 9 10 iu_dui.of_wrap(st_1, "") 11 iu_dui.of_wrap(st_2, "") 12 iu_dui.of_wrap(sle_1, "") 13 iu_dui.of_wrap(sle_2, "") 14 end if
對於Datawindow這樣的控件,暫時沒有包裝方案,因此不動便可。
這個部分最難。涉及的方面很是多。
要求生成的代碼必需要有通用性、可定製化、簡單清晰。要達到這個要求,必須是動態頁面,而非靜態HTML。因此選型的時候,重點考慮了React、Vue、Angular,而不是傳統的JQuery+Bootstrap。
React做爲大熱的前端框架,這裏就不詳細介紹了。React只負責View的部分,這正是咱們須要的,相比大而全的Angular更適合WebUI包裝。而基於MVVM模型的Vue,則可能在接口方面有更底層的修改需求,因此最終選擇了React。
完整的MVC框架,應該是React+Redux組合,則使用PB替換Redux就是咱們的目標。首先,咱們來分析一下Redux。下面是簡化版Redux:
// Mini Redux const createStore = (reducer) => { let state; let listeners = []; const getState = () => state; const dispatch = (action) => { state = reducer(state, action); listeners.forEach(listener => listener()); }; const subscribe = (listener) => { listeners.push(listener); return () => { listeners = listeners.filter(l => l !== listener); } }; dispatch({}); return { getState, dispatch, subscribe }; }; const reducer = function (state, action) { ... return null; }; const store = createStore(reducer); const state = store.getState();
因爲Redux的靈感來自於Flux的單向數據流,全部的數據只有一個入口Reducer。因此,最終設計的JS接口只有一個(又雙叒叕是一個接口?!)
pbSend( { type: 'clicked', payload: {name: 'button', value: ''} } );
u_wui的使用方式與u_dui相似,只多了一個of_render(template, output)接口
1 OpenUserObject(iu_wui, "u_wui", 0, 0) 2 iu_wui.width = parent.width 3 iu_wui.height = parent.height 4 5 iu_wui.of_wrap(cb_dui, "") 6 iu_wui.of_wrap(cb_wui, "") 7 iu_wui.of_wrap(cb_unwrap, "") 8 9 iu_wui.of_wrap(st_1, "") 10 iu_wui.of_wrap(st_2, "") 11 iu_wui.of_wrap(sle_1, "") 12 iu_wui.of_wrap(sle_2, "") 13 14 iu_wui.of_render("res/html/wui.tpl", "res/html/wui.html")
WebUI在使用時,加載會有一段時間的空白頁面, 可使用各類技術手段來解決,好比加載動畫,好比服務端渲染(緩存的方式)等等,本節就不深刻了。
預告:PowerPlume共分爲內外上下後前6部分18篇,敬請期待。
有人留言說,PB9能不能支持,固然能支持(多了pblua.pbd,pbdui.pbd,pbwui.pbd三個文件)。PB8及如下的因爲不支持PBNI,因此不能支持。
WindowsXP不能運行的問題,沒有測試過,本次試着降級VC++版本爲VC2010進行編譯。
提供了PB9.0 PB10.5 PB11.5 PB12.5四個版本
Miniblink node.dll: node.rar
Miniblink因爲太大,因此沒有包含在源碼內,採用的是miniblink-190226版本,使用其它版本可能會找不到API。
<本節完>