Sciter / HTML / C?;谧烂娴膽?yīng)用程序演練
本文介紹了如何通過 C# 使用Sciter通過使用創(chuàng)建基 于HTML 的桌面應(yīng)用程序 SciterSharp 庫(kù)(.NET綁定過Sciter API)。 為了快速啟動(dòng)我們的應(yīng)用程序,我們使用一個(gè)Sciter引導(dǎo)模板,這有助于使我們的跨Windows和Linux應(yīng)用程序編譯。 Sciter是使桌面應(yīng)用程序的
本文介紹了如何通過
C# 使用Sciter通過使用創(chuàng)建基
于HTML 的桌面應(yīng)用程序
SciterSharp 庫(kù)(.NET綁定過Sciter API)。為了快速啟動(dòng)我們的應(yīng)用程序,我們使用一個(gè)Sciter引導(dǎo)模板,這有助于使我們的跨Windows和Linux應(yīng)用程序編譯。
Sciter是使桌面應(yīng)用程序的一個(gè)多平臺(tái)的HTML渲染引擎。在這些很酷的功能,它具有以下支持:
< - >為UI的本地集成主機(jī)通訊,DOM操作,資源跟蹤,所有通過C#
量好CSS3與使用Flex單位一個(gè)漂亮的布點(diǎn)系統(tǒng)
通過TIScript語(yǔ)言腳本(JavaScript的擴(kuò)展)
一個(gè)腳本API的前端級(jí)DOM /風(fēng)格操作,AJAX調(diào)用,JSON,...
這也是免費(fèi)用于商業(yè)用途,雖然它不是開源。它分布作為你的C / C ++ SDK內(nèi)找到本機(jī)共享庫(kù)(DLL)。該SDK包含用于構(gòu)建Windows,Linux和OSX。
Sciter技術(shù)在現(xiàn)實(shí)世界中的一些大的軟件使用,證明多遠(yuǎn),你可以去用它:ICQ客戶端,諾頓,停住下,BitDefender,ESET殺毒軟件。
該示例桌面應(yīng)用程序使用“ 谷歌API客戶端庫(kù).NET ”查詢谷歌的字體 用于顯示用戶可用的字體列表和一個(gè)按鈕來下載它們。這將需要本地C#編碼以及HTML和腳本,用于使用戶界面,以及該2層之間進(jìn)行通信的混合。這樣,您將獲得如何創(chuàng)建一個(gè)位本機(jī)C#編碼的應(yīng)用涉及熟悉,并與異步資源加載,并在如何通過UI /原生層之間的數(shù)據(jù)。完整的源代碼也可在GitHub上。
Sciter代替,比如說,CefSharp或Electron.io的注意事項(xiàng)
目前已經(jīng)有大量的用于在.NET應(yīng)用程序中嵌入HTML內(nèi)容選項(xiàng)。CefSharp和Electron.io似乎是最流行的,并且都使用鉻作為下劃線引擎。由于Sciter不是一個(gè)流行的Web瀏覽器,那么為什么我選擇了它,而不是一個(gè)眾所周知的HTML引擎像壁虎或鉻與尖端HTML5技術(shù)的支持使用標(biāo)準(zhǔn)的發(fā)動(dòng)機(jī)?那么,你需要為自己決定什么是適合你的,什么是適合你的項(xiàng)目。我所能做的就是告訴你什么讓我采取Sciter,如何使用技術(shù),并且解決它的缺點(diǎn)。
Sciter特定功能集
Sciter不嘗試實(shí)現(xiàn)HTML5標(biāo)準(zhǔn),不過,這并不意味著你之前的HTML / CSS知識(shí)不能被使用。以下是你可能需要考慮對(duì)不同內(nèi)容的摘要:
CSS支持帳戶的所有基本屬性(全CSS2.1)和CSS3的一些重要的東西(邊界半徑,箱陰影,線性漸變,見CSS屬性的支持片 ;也CSS布點(diǎn)有點(diǎn)Sciter具體的,主要由彎曲通過單位和“流:”屬性,這比對(duì)CSS3 Flexbox的順便說一句容易得多。
腳本是通過TIScript語(yǔ)言所作的; 它不與標(biāo)準(zhǔn)的瀏覽器的API一致,它具有一個(gè)有據(jù)可查的它自己的API集; 但因?yàn)樗且粋€(gè)Javascript擴(kuò)展,網(wǎng)絡(luò)程序員將下跌完全熟悉它。
HTML5的特性之一,有Sciter等同于以下幾點(diǎn):繪圖畫布,SVG,的WebSockets API,<視頻>,CSS動(dòng)畫/過渡,自定義字體(你可以使用例如FontAwesome); 其他HTML5功能你也許可以實(shí)現(xiàn)與一個(gè)位附加本地編碼。
使用Sciter的優(yōu)勢(shì)
我為什么選擇Sciter比其他引擎的原因在于,首先,Sciter是制作的桌面應(yīng)用程序,而不是網(wǎng)頁(yè)瀏覽器量身定做。我覺得這樣的承諾所帶來的它是如何被開發(fā)了的時(shí)候(很多善良已經(jīng)10歲的道路)。
我對(duì)Sciter使用建議是,當(dāng)你想為你的HTML應(yīng)用良好的本地支持:你把所有的選擇你喜歡的編程語(yǔ)言(D,C#,C ++,Python和德爾福,圍棋),它具有操縱一個(gè)成熟的本地API的靈活性您的應(yīng)用程序的每一個(gè)方面。
標(biāo)準(zhǔn)的瀏覽器引擎被設(shè)計(jì)成訪問從網(wǎng)絡(luò)服務(wù)器遠(yuǎn)程提供的網(wǎng)頁(yè),以執(zhí)行它們沙箱,其中系統(tǒng)資源被嚴(yán)格控制。Sciter被設(shè)計(jì)為從任何來源處理資源:資源裝載是完全可定制的,并且它也具有從BLOB的緊縮數(shù)據(jù)加載資源的API。
在TIScript你可以處理的系統(tǒng)資源(文件,套接字IPC)和原生層容易說話。因?yàn)椋阍谧鲎烂鎽?yīng)用程序,假定你正在處理可信資源執(zhí)行它Sciter沒有什么太大的安全約束及其相關(guān)的開銷。
鉻是中小型應(yīng)用的真正臃腫。鉻集成原生層有嚴(yán)重的問題。例如,在上述這篇文章,你不能讓復(fù)雜的JavaScript對(duì)象到C#層,則需要將其轉(zhuǎn)換為JSON第一和發(fā)送的對(duì)象向后字符串。
Sciter不僅僅是跨平臺(tái),支持Windows和Linux / GTK和OSX,但它也有許多編程語(yǔ)言:C#,C ++,D,Python和Delphi和圍棋(我是C#和D的作者和維護(hù)者的)
輕量級(jí):引擎是你需要沿著你的產(chǎn)品附帶一個(gè)本機(jī)DLL
高性能:有發(fā)動(dòng)機(jī)啟動(dòng)無(wú)延時(shí),如果其他人相比臃腫的HTML引擎具有更低的內(nèi)存消耗,并繪制后端是GPU加速(Direct2D的在Windows,開羅Linux和CoreGraphics中的OSX)
優(yōu)秀的本地窗口集成:創(chuàng)建多個(gè)Sciter窗口實(shí)例,他們都共享同一個(gè)TIScript VM,因此您可以共享之間的數(shù)據(jù); 航空DWM-啟用了Windows,WS_EX_LAYERED窗口(桌面透明度); 允許創(chuàng)建本地Windows / HWND作為子DOM元素 看樣,您可以創(chuàng)建窗口的例子:http://misoftware.rs/Bootstrap/Templates
可定制的本土資源加載; 定制調(diào)試輸出消息
< - >本地集成DOM操作,DOM事件回調(diào)和TIScript原生API CefSharp不公開一個(gè)DOM API; 與SciterSharp您可以查看/從C#操作DOM!這對(duì)于調(diào)試最有用的,因?yàn)镈OM操作你通??梢酝ㄟ^腳本做
隨著版本3.3.1.4,你可以用它來 渲染UI在DirectX窗口,在這里看到和圖像如下:
使用Sciter的缺點(diǎn)
這不是一個(gè)所見即所得的環(huán)境類似的WebForms或WPF,你需要寫HTML代碼和預(yù)覽造成視覺的sciter.exe工具(當(dāng)然,如果你認(rèn)為HTML是一個(gè)很好的方法,在所見即所得那么它真的不是一個(gè)劣勢(shì))
缺乏HTML5的功能和W3C標(biāo)準(zhǔn):不能簡(jiǎn)單地抓取像jQuery或引導(dǎo)圖書館和Sciter使用
Linux的/ GTK支持有許多HTML / CSS缺失的功能,如果相比于Windows的版本,這是比較成熟的; 我沒有測(cè)試OSX支持,因?yàn)槲也粨碛幸慌_(tái)蘋果機(jī)=(但據(jù)說是因?yàn)樵赪indows中一樣好
1.入門
要開始,你心里一定有什么,我們將在本文中實(shí)現(xiàn)和所涉及的目標(biāo):
-我們將步行通過創(chuàng)建一個(gè)桌面應(yīng)用程序,顯示可用谷歌字體列表與按鈕又讓用戶下載一個(gè).zip與整個(gè)字體系列
- 這整篇文章將在Visual Studio 2015年完成,但最后我將展示如何編譯它使用的Linux的MonoDevelop
-The前端/ UI完全是用HTML / CSS和腳本與TIScript制成
-The后端在C#中,涉及:
-Google .NET API:用于查詢谷歌字體
異步-Handling谷歌響應(yīng)和返回的數(shù)據(jù)傳遞給UI層
-我們使用SciterSharp庫(kù)及其對(duì)很多事情API超過Sciter引擎,從UI通信資源加載
-我們從預(yù)制的IDE項(xiàng)目開始,我們從Sciter引導(dǎo)頁(yè)面下載上線
- 我們選擇多平臺(tái)的模板,所以我們可以很容易地編寫Windows和Linux
所以上手,我們需要獲得一些資源,因此遵循以下3個(gè)步驟。
下載Sciter引導(dǎo)包
由于我們要?jiǎng)?chuàng)建一個(gè)多平臺(tái)的桌面應(yīng)用程序,你必須明白,支持不同的操作系統(tǒng)意味著要處理不同的API集。通常你想在多個(gè)平臺(tái)上工作的統(tǒng)一的API工作。但有時(shí)是不可能的,你必須訴諸使用OS特定API。在C#中做到這一點(diǎn)周圍的平臺(tái)特定的代碼#如果/#ENDIF條件編譯塊。的Win32 API和GTK + 3 API:這種情況可能會(huì)在我們的例子,因?yàn)槲覀冋谔幚韮蓚€(gè)不同的操作系統(tǒng)和它們各自的窗口系統(tǒng)是必需的。
幸運(yùn)的是,你不必太擔(dān)心,因?yàn)槲覀儗⒂米鲎钚〉臉影宕a模板開始。它不僅僅是代碼,它也包含了適當(dāng)?shù)腟citerSharp依賴配置,你可以在VS和MonoDevelop中編譯您的應(yīng)用程序打開的.sln,它包含兩個(gè)項(xiàng)目(每個(gè)平臺(tái)/ IDE)。
所以,去Sciter引導(dǎo)下載頁(yè)面,并按照下列步驟操作:
- 步驟1:選擇“視窗32-64bits和MONO / GTK 64位/ Visual Studio或MonoDevelop的> = 5.10 / C?!?div style="height:15px;">
- 步驟2:選擇“多平臺(tái)模板”
-步驟3:編寫項(xiàng)目的標(biāo)題-此文章中,我們使用 FontLister(標(biāo)題名稱必須遵循C#標(biāo)識(shí)符規(guī)則)
- 步驟4:點(diǎn)擊“下載”按鈕
解壓.zip內(nèi)容,并在Visual Studio 2015年按Build按鈕打開的.sln,等待它下載SciterSharp的NuGet包,然后運(yùn)行該應(yīng)用程序。Cooool,你已經(jīng)有一個(gè)Sciter多平臺(tái)應(yīng)用程序的運(yùn)行。這是不容易?
如果你得到編譯錯(cuò)誤,那是因?yàn)镾citerSharp的NuGet沒有正確下載。進(jìn)入包管理器控制臺(tái),并嘗試發(fā)出“更新的程序包-Reinstall”命令來修復(fù)它。
注意,這個(gè)解決方案包含兩個(gè)項(xiàng)目。由于我們并不需要建立MONO / GTK項(xiàng)目于Windows系統(tǒng)(它甚至不會(huì)運(yùn)行),可隨時(shí)右鍵單擊該項(xiàng)目項(xiàng)并選擇“卸載項(xiàng)目”。
手動(dòng)安裝
SciterSharp可以下載并安裝由你自己,如果你正在開始一個(gè)項(xiàng)目,并且不希望使用Sciter引導(dǎo)。
-安裝它作為一個(gè)的NuGet包:為的Windows或MONO / GTK + 3
-Or下載從整個(gè)項(xiàng)目https://github.com/midiway/SciterSharp ; 我強(qiáng)烈建議這樣做,因?yàn)檫@樣的話,你可以調(diào)試和步驟在SciterSharp代碼,看看它在做什么,這是一個(gè)非常小的項(xiàng)目呢
然而,這些方法不支持這篇文章,因?yàn)槲覀円_始Sciter引導(dǎo)模板代碼,因?yàn)樗嵌嗥脚_(tái)的準(zhǔn)備,我們希望我們的應(yīng)用程序在Windows和Linux上運(yùn)行。
安裝的NuGet包,并獲得谷歌API密鑰
我們需要通過的NuGet包的其他.NET庫(kù)。你必須將包安裝到這兩個(gè)項(xiàng)目(FontListerGTK和FontListerWindows)。你可以這樣做右鍵單擊“FontLister”解決方案項(xiàng)目和“管理的NuGet的解決方案包”(注意FontListerGTK項(xiàng)目必須加載)。
安裝這些包的NuGet:
-Google.Apis.Webfonts.v1
-Newtonsoft.Json
你需要讓自己的查詢谷歌字體的谷歌API密鑰。
-進(jìn)入 谷歌開發(fā)者控制臺(tái)
- 創(chuàng)建一個(gè)新項(xiàng)目
- 在總覽頁(yè)面,有一個(gè)輸入其內(nèi)容為“搜索所有100+的API'; 搜索“字體”
- 選擇“Web字體開發(fā)者API”,然后點(diǎn)擊藍(lán)色的“啟用API”按鈕
- 現(xiàn)在去憑證/新憑證/服務(wù)器密鑰
- 由于我們會(huì)從本地桌面應(yīng)用程序僅查詢谷歌的字體,簡(jiǎn)單的服務(wù)器密鑰就足夠了
- 按創(chuàng)建并彈出顯示的API密鑰,只需保存到某個(gè)地方
下載Sciter SDK
抓住Sciter SDK 從這里。該SDK主要是使用C / C ++ API開發(fā),但它也有所有Sciter二進(jìn)制文件和工具。我們從SDK需要的是sciter.exe位于/ bin目錄中找到工具。我建議你運(yùn)行它,銷任務(wù)欄中的圖標(biāo)。我們將使用這個(gè)工具,兩件事情:
-你用它查看您編寫HTML代碼的結(jié)果; 你通常編輯HTML代碼,并切換回sciter.exe和按F5刷新頁(yè)面; 也就是說,sciter.exe就像一個(gè)瀏覽器為Sciter HTML內(nèi)容; 它也有F12工具相當(dāng)于DOM檢查和腳本調(diào)試。
-它也可以訪問到文件自帶的SDK里面捆綁; 點(diǎn)擊?標(biāo)記按鈕左側(cè)的工具欄,并且將打開一個(gè)包含您使用的腳本所有TIScript API的描述,也教你關(guān)于語(yǔ)言; 您將在咨詢了很多,相信我。
2.代碼手 - >后端
在我們開始之前,我想向您推薦挫折的常見原因做這類桌面應(yīng)用程序的時(shí)候,我們面對(duì)的問題。
它是Web開發(fā)單獨(dú)的工作慣例兩個(gè)人之間:一個(gè)人負(fù)責(zé)的UI / UX思(前端),以及其他負(fù)責(zé)業(yè)務(wù)邏輯,基于UI事件(后端)驅(qū)動(dòng)程序。
隨著Sciter,如Web開發(fā),可以實(shí)現(xiàn)工作流的形式相同。但你會(huì)獨(dú)自將不可避免地在同一時(shí)間做兩件事,它可以是非常令人沮喪。
在做UI編碼和思考,通常情況下,帶著幾分CSS和HTML的,你取得成果非???,你能直觀地看到結(jié)果。后端通常需要更多的精神堅(jiān)韌的工作和思維方式的程序。問題是,這兩種思維模式不兼容,好痛我的大腦時(shí),我做的混合兩件事。由于這樣,我真的鼓勵(lì)你努力習(xí)慣單獨(dú)做這些事情,因?yàn)槲視?huì)告訴你。
我們將與后端在哪里,在做實(shí)際的UI之前,我們將使用兩種不同的UI成語(yǔ)定義的連接點(diǎn)開始。在Sciter有3個(gè)成語(yǔ)后端< - > UI溝通你可以在閱讀的細(xì)節(jié)在這里。
這是一個(gè)步行通過,我們將主要從默認(rèn)的代碼從引導(dǎo)模板添加或調(diào)整代碼。
窗口創(chuàng)建
我們的應(yīng)用程序的初始化文件Program.cs中,在那里你找到窗口創(chuàng)建代碼,這是不言自明的。該SciterWindow類是用于創(chuàng)建和處理一個(gè)不可知論者的方法OS本地窗口為托管Sciter HTML頁(yè)面。對(duì)于我們的FontLister,我改變了窗口的標(biāo)題和大小,所以我結(jié)束了:
隱藏 復(fù)制代碼
// 創(chuàng)建窗口var wnd = new SciterWindow();wnd.CreateMainWindow(800, 600);wnd.CenterTopLevelWindow();wnd.Title = "Font Lister"; 在Windows只,您可以從SciterWindow類衍生物覆蓋ProcessWindowMessage()虛方法,所以你可以處理的Win32消息。
從理論上講,只需SciterWindow實(shí)例,你已經(jīng)可以加載并調(diào)用LoadHtml(),例如顯示一個(gè)HTML頁(yè)面:
隱藏 復(fù)制代碼
wnd.LoadHtml("<html><body>Hello World!</body></html>");wnd.Show();
但是,我們希望得到更深入和控制有關(guān)HTML頁(yè)面的加載一切,這就是為什么我們需要一個(gè)SciterHost實(shí)例來包裝HTML加載過程。
網(wǎng)頁(yè)托管解釋
SciterHost類是控制沿托管HTML頁(yè)面的生活諸多方面的核心部件。本質(zhì)上,它讓你跟蹤以下通知了Sciter引擎產(chǎn)生:
-SC_LOAD_DATA和SC_DATA_LOADED使您能夠控制資源加載,并在下一節(jié)解釋。
- SC_POSTED_NOTIFICATION你打電話SciterHost.PostNotification后()方法被接受; 因?yàn)樵赨I線程總是收到此消息是在多線程的情況下非常有用; SciterHost提供,你可以從一個(gè)工作線程用來執(zhí)行在UI線程特定委托的InvokePost()方法。
- SC_ATTACH_BEHAVIOR:一個(gè)請(qǐng)求到本機(jī)的行為(SciterEventHandler instace)附加到DOM元素。
- SC_ENGINE_DESTROYED:產(chǎn)生之前發(fā)動(dòng)機(jī)被破壞,關(guān)閉主窗口后。
SciterHost類有相應(yīng)的overridables方法為你處理這些通知。
此外,SciterHost可以讓你通過附加AttachEvh()方法的一個(gè)窗口級(jí)別的事件處理程序。此處理程序從網(wǎng)頁(yè)接收的每個(gè)事件之前被分派到目標(biāo)DOM元素。
引導(dǎo)程序代碼來已經(jīng)與需要設(shè)置一個(gè)SciterHost一切:
隱藏 復(fù)制代碼
// 準(zhǔn)備SciterHost然后加載頁(yè)面var host = new Host();host.SetupWindow(wnd);host.AttachEvh(new HostEvh());host.SetupPage("index.html"); 其實(shí)引導(dǎo)擴(kuò)展SciterHost與主機(jī)類,所以托管相關(guān)的代碼位于一個(gè)單獨(dú)的類/文件(Host.cs)。
需要注意的是之前加載HTML頁(yè)面,我們必須先調(diào)用SetupWindow()將SciterWindow到SciterHost相關(guān)聯(lián),還可選附加SciterEventHandler來接收即將被裝載SetupPage頁(yè)面的事件()。
從分組數(shù)據(jù)資源加載
隨著SC_LOAD_DATA和SC_DATA_LOADED通知您可以跟蹤和定制由你的HTML頁(yè)面(HTML頁(yè)面本身,圖片,腳本,CSS)要求每個(gè)資源的加載或者你可以忽略它并保留默認(rèn)加載機(jī)制。
你可以注意到,在從Host.cs文件BaseHost類,引導(dǎo)代碼通過覆蓋OnLoadData()方法使用一個(gè)自定義加載策略。
隱藏 復(fù)制代碼
protected override SciterXDef.LoadResult OnLoadData(SciterXDef.SCN_LOAD_DATA sld){ if(sld.uri.StartsWith("archive://app/")) { // load resource from SciterArchive string path = sld.uri.Substring(14); byte[] data = _archive.Get(path); if(data!=null) _api.SciterDataReady(_wnd._hwnd, sld.uri, data, (uint) data.Length); } return SciterXDef.LoadResult.LOAD_OK;} Sciter資源通過標(biāo)準(zhǔn)URL機(jī)制跟蹤。我們?cè)谧鍪裁?,如果資源的URL開頭存檔://應(yīng)用程序/(即:協(xié)議),我們從我們的SciterArchive實(shí)例加載資源持有我們所有的資源在一個(gè)BLOB壓縮格式。這BLOB包含在文件ArchiveResource.cs并重新創(chuàng)建每次我們通過在項(xiàng)目中已經(jīng)配置的預(yù)生成命令生成項(xiàng)目的時(shí)間。
注意從SciterArchive BLOB裝車僅在釋放模式完成。在調(diào)試模式的資源從文件系統(tǒng)直接加載。
BaseHost類SetupPage()方法是負(fù)責(zé)加載初始HTML頁(yè)面并指定其URL和基礎(chǔ)協(xié)議相關(guān):文件:///或存檔://應(yīng)用程序/,這使得調(diào)試和發(fā)布模式加載策略之間的這種差異。
為什么這一切?因?yàn)槲覀兊陌l(fā)布版本將包含包裝中的.exe決策部署更加容易內(nèi)的所有資源。我們的DEBUG版本將更快從文件系統(tǒng)加載資源。
GOOGLE 1 -裝載,并通過GOOGLE字體列表到UI層。在“應(yīng)用程序事件”的成語(yǔ)(主機(jī)- > UI)
對(duì)于與谷歌的字體處理相關(guān)的事情,我們創(chuàng)建一個(gè)專用的類。整個(gè)類的代碼是在文件中的數(shù)據(jù)/ GAPI.cs,你可以從成品樣品.ZIP復(fù)制。
這個(gè)類需要解決的第一個(gè)任務(wù)是通過谷歌的API請(qǐng)求可用谷歌的字體列表,并通過此列表UI層。由于這個(gè)操作需要一定的時(shí)間,因?yàn)樗鼜幕ヂ?lián)網(wǎng)上獲取數(shù)據(jù),你不希望在主UI線程出現(xiàn)這種處理,而是在后臺(tái)線程。所以,在這里,實(shí)現(xiàn)它的代碼:
隱藏 復(fù)制代碼
public static void Setup(){ new Thread(() => { var service = new WebfontsService(new Google.Apis.Services.BaseClientService.Initializer() { ApiKey = API_KEY }); var request = service.Webfonts.List(); request.Sort = WebfontsResource.ListRequest.SortEnum.Popularity; _fontlist = request.Execute().Items;// if you get an Exception here, plz disable your Firewall! Debug.Assert(_fontlist.Count > 0); ... 請(qǐng)確保你有設(shè)置API_KEY變量您的谷歌API密鑰。谷歌的字體返回列表存儲(chǔ)在一個(gè)靜態(tài)變量“_fontlist,因?yàn)槲覀円院笮枰牧斜碇小?div style="height:15px;">
現(xiàn)在,我們需要把這個(gè)列表傳遞到UI層,它顯示給用戶的字體列表:
隱藏 復(fù)制代碼
... // converts the Webfont list to JSON string string json = JsonConvert.SerializeObject(_fontlist); // converts the JSON string to SciterValue SciterValue sv = SciterValue.FromJSONString(json); // calls UI layer TIScript function with the font data Program.HostInstance.InvokePost(() => { Program.HostInstance.CallFunction("View_OnFontList", sv); }); }).Start();} 在這里你找到“應(yīng)用程序事件”互動(dòng)的原則/成語(yǔ)的用法你可以閱讀更多有關(guān)在這里。但它是非常簡(jiǎn)單的:原生應(yīng)用層簡(jiǎn)單地調(diào)用腳本函數(shù)將數(shù)據(jù)傳遞給UI層(主機(jī)- > UI通訊)
這是通過一個(gè)全球腳本函數(shù)的名稱與Program.HostInstance.CallFunction()方法完成的(或命名空間一個(gè))和任何數(shù)量的SciterValue參數(shù)。但是,請(qǐng)注意,此代碼將在后臺(tái)線程來執(zhí)行。這是危險(xiǎn)的,可能會(huì)導(dǎo)致數(shù)據(jù)損壞,因?yàn)槲也恢繲IScript 100%線程安全的。
最安全的是要切換回UI線程,并從那里做調(diào)用腳本。這就是為什么Program.HostInstance.InvokePost的使用(()=> {...})方法,將執(zhí)行在UI線程上下文拉姆達(dá)參數(shù)。
SciterValue類是用來代表/在C#創(chuàng)建TIScript數(shù)據(jù)之一。對(duì)于從IList中讓我們的SciterValue <WebFont>我們做一個(gè)小小的trickie轉(zhuǎn)換。我們首先轉(zhuǎn)換的IList <WebFont>以JSON字符串,然后用SciterValue.FromJSONString(JSON)的JSON解析到一個(gè)新的SciterValue。和它的作品非常好!
GOOGLE 2 -下載和GOOGLE字體保存為zip格式。在“POST請(qǐng)求”的成語(yǔ)(UI - >主機(jī)- > UI)
第二個(gè)任務(wù)我們GAPI C#類確實(shí)是下載一個(gè)給定的字體家族(可包含多個(gè).TTF文件),在一個(gè).zip收拾他們,并將其保存在指定文件夾。
處理它的方法非常簡(jiǎn)單,不言自明的,只是讀到的資料。它的簽名是:
隱藏 復(fù)制代碼
public static void DownloadFont(string family, string savefolder) { ... } 我們通過字體的名稱和路徑在哪里保存的.zip。我們下載使用WebClient.DownloadFile()調(diào)用,這確實(shí)需要時(shí)間遠(yuǎn)程的字體文件,因此DownloadFont()方法不應(yīng)該從UI線程調(diào)用的,而是從工作線程。
隨著文件下載到臨時(shí)文件夾,.NET已經(jīng)從一個(gè)文件夾中的.zip文件,該文件通過調(diào)用發(fā)生打包文件,一個(gè)很好的API:
隱藏 復(fù)制代碼
ZipFile.CreateFromDirectory(tmppath, savefolder + "/" + family + ".zip"); (您必須添加一個(gè)引用到System.IO.Compression.FileSystem裝配使用這個(gè)API)
字體下載發(fā)生在用戶點(diǎn)擊我們的HTML頁(yè)面的下載按鈕,所以我們需要一種方法來檢測(cè)這個(gè)UI事件觸發(fā)的字體下載。我們不會(huì)阻止用戶界面,同時(shí)下載正在發(fā)生,我們需要一種方法來告訴用戶界面完成時(shí)。為此,我們使用“POST請(qǐng)求”的成語(yǔ)(UI - >主機(jī) - > UI)。基本上這個(gè)成語(yǔ)UI要求有回調(diào)腳本函數(shù)一起為資源原生層,當(dāng)資源是可用的,所以通過將結(jié)果返回給用戶界面層主體應(yīng)該調(diào)用。
執(zhí)行此代碼是在文件Host.cs:
隱藏 縮小
復(fù)制代碼
protected override bool OnScriptCall(SciterElement se, string name, SciterValue[] args, out SciterValue result){ result = null; switch(name) { case "Host_DownloadFont": string savefolder = args[0].Get(""); string family = args[1].Get(""); SciterValue async_cbk = args[2]; Task.Run(() => { bool res; try { GAPI.DownloadFont(family, savefolder); res = true; } catch(Exception) { res = false; } if(async_cbk.IsUndefined()) return;// no callback provided Program.HostInstance.InvokePost(() => { async_cbk.Call(new SciterValue(res)); }); }); return true; } return false;} 在UI / HTML腳本代碼,我們將調(diào)用view.Host_DownloadFont(文件夾,家庭功能(){...})時(shí),下載按鈕被按下,這在我們的主機(jī)類的我們OnScriptCall()C#處理結(jié)束。
引用:
在TIScript,只要您撥打“視圖”變量的方法,而這個(gè)功能的方法是不確定的,Sciter引擎調(diào)用連接到您的SciterHost OnScriptCall()事件處理程序,給它一個(gè)機(jī)會(huì)來處理不存在的函數(shù)名。如果從返回'真'OnScriptCall處理程序,這意味著你處理呼叫和腳本虛擬機(jī)將不會(huì)觸發(fā)“視圖(View([對(duì)象視圖]))沒有方法- Host_DownloadFont”異常并停止執(zhí)行腳本。
當(dāng)腳本調(diào)用 view.Host_DownloadFont(文件夾,家庭功能(RES){...}),我們收到的給定的參數(shù)在C#作為SciterValue數(shù)組。從這個(gè)數(shù)組,我們手動(dòng)前兩個(gè)itens使用轉(zhuǎn)換為字符串ARGS [0]獲得(“”) ,所以我們有savefolder和家人字符串變量(可以為所有基本的C#類做這樣的轉(zhuǎn)換,則Get()方法對(duì)INT獲?。?),布爾獲取(真),等過載..)。我們節(jié)省第三SciterValue阿根廷,腳本回調(diào),作為原料SciterValue變量“async_cbk”。
我們的處理程序,然后開始運(yùn)行在后臺(tái)線程的GAPI.DownloadFont()過程的任務(wù)。需要注意的是,因?yàn)檫@取決于網(wǎng)絡(luò)的可用性,所以其在try / catch塊包圍它可能會(huì)失敗。當(dāng)DownloadFont()完成后,我們有一個(gè)布爾結(jié)果是如果發(fā)生成功下載,我們將傳回UI層作為標(biāo)志。
正如在“應(yīng)用程序事件”的成語(yǔ),我們需要切換回UI線程通過使用調(diào)用腳本函數(shù)Program.HostInstance.InvokePost()。然后,我們只需使用SciterValue的call()方法傳遞布爾調(diào)用腳本回調(diào)結(jié)果作為SciterValue了?,F(xiàn)在你知道,SciterValue是處理任何類型的數(shù)據(jù)TIScript多purpouse類。
后端測(cè)試
我們的后端的一切都在原地。從我們的Main()方法,我們的主機(jī)類調(diào)用SetupPage()后加載HTML頁(yè)面,我們必須調(diào)用:
隱藏 復(fù)制代碼
..FontLister.Data.GAPI.Setup();.. 此方法GAPI類創(chuàng)建一個(gè)查詢谷歌API的字體列表,然后通過調(diào)用腳本全局函數(shù)“View_OnFontList”通過列表UI層的線程(見GOOGLE 1節(jié))。
因此,對(duì)于測(cè)試是否所有工作正常,只是把一個(gè)斷點(diǎn)文件GAPI.cs其內(nèi)容的46行:
隱藏 復(fù)制代碼
..Program.HostInstance.CallFunction( “ View_OnFontList”,SV); // - >斷點(diǎn)這里 .. 并開始調(diào)試我們的應(yīng)用程序。它應(yīng)該命中斷點(diǎn),否則檢查是否有早期異常。因此,谷歌API的測(cè)試只是真的按F5調(diào)試我們的應(yīng)用程序。
現(xiàn)在我們需要測(cè)試它會(huì)從我們的UI層被調(diào)用的方式調(diào)試我們的代碼。正如所以我們會(huì)從C#直接模擬用戶界面的要求,讓你學(xué)會(huì)如何測(cè)試的東西沒有前端。
這一行46后,把下面的一行47:
隱藏 復(fù)制代碼
Program.HostInstance.CallFunction("View_OnFontList", sv);// line 46Program.HostInstance.EvalScript("view.Host_DownloadFont(\"D:/\", \"Open Sans\", function(res) {})");// line 47 應(yīng)該是這樣的:
到底是什么它做什么?view.Host_DownloadFont是我們HostEvh事件處理類原生處理(見GOOGLE 2部分)的函數(shù),因此當(dāng)您從TIScript調(diào)用此函數(shù),它結(jié)束beeing由C#代碼處理。
我們現(xiàn)在做的就是通過模擬EvalScript從C#這個(gè)腳本調(diào)用()。我們通過作為參數(shù)TIScript代碼在我們SciterWindow的全局命名空間執(zhí)行。
什么會(huì)發(fā)生的是,它會(huì)調(diào)用我們?cè)诠雀?節(jié)中定義的Host_DownloadFont處理程序。需要注意的是我們傳遞3個(gè)參數(shù)來Host_DownloadFont:
- “D:/”
- “打開三世”
- 功能(RES){}
分別是:目錄中保存的.zip,字體家庭,和一個(gè)空的回調(diào)函數(shù)。
好了,現(xiàn)在你可以調(diào)試,看看是否一切工作正常。將斷點(diǎn)在我們剛剛添加的47行,并在文件Host.cs斷點(diǎn),一行33按F5鍵,它應(yīng)該首先再次命中47行,按F5,然后就應(yīng)該打線33.現(xiàn)在你可以步驟中的代碼,直到它到達(dá)GAPI.DownloadFont()。這個(gè)電話后,稍等一下,并檢查文件“打開Sans.zip”在您的D創(chuàng)建:驅(qū)動(dòng)程序。我們剛剛仿真和測(cè)試,當(dāng)用戶下載一個(gè).zip一個(gè)給定的字體家庭會(huì)發(fā)生什么。刪除47行。
3.代碼手 - >前端
現(xiàn)在我們正在進(jìn)入發(fā)展的一個(gè)全新的領(lǐng)域其中涉及純HTML / CSS和腳本與TIScript語(yǔ)言。我可能會(huì)說這是比后端更容易,只要你有一點(diǎn)HTML和CSS的經(jīng)驗(yàn)。即使你是在網(wǎng)絡(luò)技術(shù)方面的專家,這是值得閱讀本節(jié),因?yàn)樵赟citer HTML / CSS的支持有一些細(xì)微之處并非由標(biāo)準(zhǔn)的瀏覽器支持。TIScript擁有標(biāo)準(zhǔn)的JS很多差異,但它仍然一個(gè)Javascript語(yǔ)言一樣。
當(dāng)我們與后端做了,我們就可以編寫和測(cè)試從后端完全不沾邊的前端,所以不要求工作后端。
HTML
這是我們需要更換為index.html的內(nèi)容中的所有HTML:
隱藏 復(fù)制代碼
<html><head></head><body> <div .warning>Loading Google fonts..</div> <div #list /></body></html> 這是標(biāo)準(zhǔn)的HTML,直到你注意到一些細(xì)微之處。注意,我們宣布<div>元素:
<DIV #list />
有兩個(gè)Sciter具體的事情,在這里你必須知道。首先,請(qǐng)注意我們沒有一個(gè)結(jié)束</ div>標(biāo)簽。如果元素包含沒有孩子,可以完全省略結(jié)束標(biāo)記,不管它是什么HTML標(biāo)簽。在瀏覽器中,<DIV>的總是需要關(guān)閉標(biāo)簽。
二,而不是用一個(gè)id =“XYZ”屬性聲明元素的ID,如<DIV ID =“名單”/> ,我們可以簡(jiǎn)單地說#THE_ID,你會(huì)寫在CSS中的ID選擇。您可以為類屬性做同樣的,所以<DIV CLASS =“名單列表色”/>可以寫成<DIV .list.list色/> 。通過使用相同的語(yǔ)法從CSS中寫一個(gè)元素的ID或類非常聰明的方法。Sciter支持更多的屬性快捷方式,在這里看到。
此外,在Sciter,你可以使用任何標(biāo)記名稱,例如<列表的的的細(xì)節(jié)> </列表的的的細(xì)節(jié)>。但你也需要設(shè)置顯示CSS屬性,所以下面有必要進(jìn)行列表的的的細(xì)節(jié)可見:
隱藏 復(fù)制代碼
list-of-details{ display: block;// or inline, inline-block, ..} CSS
對(duì)于造型我們的頁(yè)面,我們需要下列CSS <style>標(biāo)簽,你應(yīng)該把在<head>標(biāo)簽中:
隱藏 復(fù)制代碼
<style> body { margin: 0; padding: 10px; flow: vertical; background: #eee; font-family: system; } li { padding: 10px; margin-bottom: 10px; border: solid 1px #BBB; box-shadow: 0px 1px 1px #EEE; background: white; } h1 { margin: 0; margin-bottom: 10px; } b { font-size: 18px; } b.success { color: green; } b.error { color: red; }</style> 沒有什么好說的,這僅僅是標(biāo)準(zhǔn)的CSS。這里唯一的Sciter具體的事情是“流”屬性,你可以閱讀更多有關(guān)在這里。本質(zhì)上,它是對(duì)CSS3 Flexbox的布點(diǎn)的等效的,但其具有不同的命名和行為。
在'柔性'屬性決定如何元素的兒童將被定位在里面。我們使用的“垂直”值說垂直布局元素,一是波紋管其他的,行,如果不管它的內(nèi)嵌或塊元素。
TIScript
腳本語(yǔ)言被認(rèn)為是本地函數(shù)/組件和UI事件/元素間的膠水。此外,腳本的主要目的之一是更新DOM的狀態(tài),讓您的動(dòng)態(tài)添加到您的網(wǎng)頁(yè)。
TIScript分隔不同的線程模型。HTML,CSS和腳本(后面UI代碼)是基于assynchronous資源負(fù)載,而應(yīng)用程序核心包括用于供給上的用戶界面的同步程序,但是舒服,因?yàn)樗慌c用戶界面和它的事件和線程模型并列。
對(duì)于我們的應(yīng)用程序,這里是你需要添加到<head>標(biāo)簽中的所有腳本代碼:
隱藏 縮小
復(fù)制代碼
<script type="text/tiscript"> function View_OnFontList(data) { $(.warning).remove(); for(var item in data) { var el_item = self#list.$append(<li><h1>{item.family}</h1><button>Download Font Family</button></li>); el_item.family = item.family; } } self.on("click", "button", function() { var el_btn = this; var folder = view.selectFolder(); if(folder) { el_btn.state.disabled = true; el_btn.text = "Downloading.."; var family = el_btn.$p(li).family; view.Host_DownloadFont(folder, family, function(res) { if(res) el_btn.$after(<b .success>Download completed with success!</b>); else el_btn.$after(<b .error>Error downloading!</b>); el_btn.remove(); }); } });</script>
需要注意的是TIScript代碼必須 <腳本類型=“文/ tiscript”>標(biāo)簽,而不是簡(jiǎn)單地<script>標(biāo)記之間猶豫。
我無(wú)法解釋這個(gè)代碼,因?yàn)樗隽吮疚牡姆秶D梢粤私飧嘤嘘P(guān)TIScript 這里。但是它可以很容易地被JS開發(fā)商只通過讀取它的理解。但是,請(qǐng)注意,從普通的JavaScript以下區(qū)別:
-strings文字只被允許使用雙引號(hào):“我的字符串”是有效的TIScript串,“我的字符串'是無(wú)效的語(yǔ)法;
其中名稱以$開頭-函數(shù)/方法stringizer功能:
-the參數(shù)字面理解為一個(gè)字符串,字符'('和')'是由自己提供報(bào)價(jià)的作用。
-其通常接收HTML參數(shù)在函數(shù)中使用:$追加(<DIV>)
-or功能接收CSS選擇器:$(DIV>跨度)
尤其是圓形你注意到一個(gè)$全局函數(shù)的存在,作為JQuery的,用于選擇DOM元素,但有一個(gè)稍微好一點(diǎn)的語(yǔ)法,而不需要用引號(hào)引起來的字符串參數(shù),聰明的你不覺得?。?div style="height:15px;">
在現(xiàn)代瀏覽器,我們有F12工具,使我們能夠檢查運(yùn)行的JavaScript代碼加載的頁(yè)面和事件調(diào)試的DOM。Sciter相當(dāng)于這是sciter.exe工具,正如我以前說過。
為了測(cè)試我們的前端,通過sciter.exe打開index.html文件從Windows資源管理器中的文件拖放正下降到里面。你會(huì)看到“谷歌加載字體..”一個(gè)永遠(yuǎn)站在信息。既然我們沒有后臺(tái),就永遠(yuǎn)不會(huì)消失。但由于腳本,我們可以很容易模仿,這些2層之間流動(dòng)的數(shù)據(jù)。
View_OnFontList([ { family: "Helvetica" }, { family: "Open Sans" }, { family: "Consola" }]); 此代碼添加到您的<script>標(biāo)記的結(jié)束,回到sciter.exe,然后按刷新按鈕。這就是它。它應(yīng)該顯示與3字體的列表。您可以通過點(diǎn)擊“齒輪”按鈕,將顯示如下窗口檢查DOM:
而在VS調(diào)試,確保有打開輸出窗口,因?yàn)镾citer輸出信息到標(biāo)準(zhǔn)輸出,其范圍從簡(jiǎn)單的警告,但更重要的是,TIScript執(zhí)行錯(cuò)誤和無(wú)法識(shí)別的CSS規(guī)則(這是最常見的錯(cuò)誤,從我的經(jīng)驗(yàn)發(fā)生)。
但它在C#中調(diào)試工作,確保實(shí)現(xiàn)本機(jī)調(diào)試所以你會(huì)看到在輸出窗口Sciter錯(cuò)誤信息:項(xiàng)目屬性/調(diào)試/選中“啟用本 地代碼調(diào)試”。
在正常的瀏覽器,我們可以檢查你的活潑運(yùn)行HTML頁(yè)面(F12工具)的DOM。我們可以通過在inspector.exe工具遠(yuǎn)程檢查我們運(yùn)行C#程序中Sciter到這一點(diǎn)。
SciterSharp提供了一種簡(jiǎn)單的方法做這個(gè)(你可能想了解涉及的機(jī)制在這里)。首先,你需要把inspector.exe的副本,Sciter SDK一旁的主要FontLister.exe可執(zhí)行文件(完整的示例下載已經(jīng)擁有它)。然后,在C#中,您只需撥打SciterHost類的DebugInspect()方法:
// Prepares SciterHost and then load the pagevar host = new Host();host.SetupWindow(wnd);host.AttachEvh(new HostEvh());host.SetupPage("index.html");host.DebugInspect();// >-- call it after SetupPage().. ,它就會(huì)打開Sciter檢查。有了它打開,在你的程序中,你CTRL + SHIFT +點(diǎn)擊任何元素在DOM樹中選擇它,如下所示:
然后,只需打開MonoDevelop的解決方案,用鼠標(biāo)右鍵單擊該項(xiàng)目FontListerGTK,單擊“設(shè)為啟動(dòng)項(xiàng)目”,并嘗試建立。希望這將編譯原樣。
現(xiàn)在,如果你嘗試運(yùn)行,它可能會(huì)拋出一個(gè)“TypeInitializationException”與內(nèi)'DllNotFoundException:sciter-gtk-64.so“。這是因?yàn)閱握也坏絊citer DLL(的.so)。您需要安裝到Linux環(huán)境。最簡(jiǎn)單的辦法就是 下載這個(gè)腳本只是(樣品.ZIP已經(jīng)包含在根文件夾該文件),然后:
sudo bash install-libsciter.sh 我面臨著Linux的另一個(gè)問題是,谷歌網(wǎng)絡(luò)字體API是拋出異常。希望我找到一個(gè)解決辦法在這里,是我化險(xiǎn)為夷:
-SciterX.API.SciterSetOption()API提供了許多選項(xiàng)。一個(gè)我有時(shí)用的就是改變SCITER_SET_GFX_LAYER選項(xiàng),讓您(在Windows Direct2D的默認(rèn)設(shè)置)設(shè)置GFX后端。為什么?因?yàn)樵谂f電腦,發(fā)動(dòng)機(jī)經(jīng)常死機(jī)是由于舊的顯示硬件/驅(qū)動(dòng)器,這樣你就可以做的是切換到非加速GFX模式下,將此選項(xiàng)設(shè)置為GFX_LAYER_WARP,它是基于CPU的圖像渲染:
SciterX.API.SciterSetOption(IntPtr.Zero, SciterXDef.SCITER_RT_OPTIONS.SCITER_SET_GFX_LAYER, new IntPtr((int) SciterXDef.GFX_LAYER.GFX_LAYER_WARP)); -Another API使你可以添加CSS文件到所有HTML頁(yè)面的引擎創(chuàng)建。請(qǐng)注意,許多腳本功能創(chuàng)建新的HTML頁(yè)面,就像view.msgbox(),你不必對(duì)這些頁(yè)面的樣式直接控制,所以這個(gè)API可能是有用的。
string css = "html { background: silver; }";byte[] bytes = Encoding.UTF8.GetBytes(css);SciterX.API.SciterAppendMasterCSS(bytes, (uint) bytes.Length); 原生C#DOM操作
在這篇文章中,我們還沒有使用它,但SciterSharp庫(kù)中有通過SciterElement類操作頁(yè)面的DOM一個(gè)完整的API。同樣以SciterValue,SciterElement為任何類型的DOM操作的多purpouse類:創(chuàng)建元素,遍歷DOM樹,改變?cè)顟B(tài)/屬性/ CSS,等等...
// 獲取頁(yè)面的<body>var se_body = wnd.RootElement.SelectFirst("body");// append a <h1>header to itse_body.TransformHTML("<h1>Wow, this header was created natively!</h1>", SciterXDom.SET_ELEMENT_HTML.SIH_INSERT_AT_START);// set <h1>color to bluese_body[0].SetStyle("color", "#00F"); TIScript:查看全局?jǐn)?shù)據(jù)/通信
期望有時(shí)有一種方法來共享不同的HTML頁(yè)面之間的數(shù)據(jù),例如,不同的<幀>的網(wǎng)頁(yè),或者甚至做的多個(gè)Sciter窗口之間的通信。因?yàn)樵谕贿M(jìn)程Sciter窗口共享相同TIScript VM是可能的。
view.CreateAlert = function() { self.$append(<div .alert />)} ..makes的view.CreateAlert()提供全球范圍內(nèi),所以你可以從任何頁(yè)面調(diào)用它。
view.standardAlerts = { success: "You did it, I knew you could!" warning: "Hey, you were advised", error: "Huston, we have a problem!"}; 資源加載:通過注射在每一頁(yè)TIScript內(nèi)容'sciter:調(diào)試peer.tis“
首先,你需要確保當(dāng)您創(chuàng)建SciterWindow,你通過SciterXDef.SCITER_CREATE_WINDOW_FLAGS.SW_ENABLE_DEBUG的則CreateMainWindow()。請(qǐng)注意,如果你調(diào)用它只是通過傳遞窗口的大小,默認(rèn)情況下,它會(huì)得到這個(gè)標(biāo)志,無(wú)論如何,所以下面的調(diào)用是確定:
SW_ENABLE_DEBUG使您可以使用inspector.exe工具遠(yuǎn)程檢查你的頁(yè)面。為了做到這一點(diǎn),發(fā)動(dòng)機(jī)注入文件“sciter:調(diào)試peer.tis'來加載的所有頁(yè)面。我們可以通過自定義'sciter:調(diào)試peer.tis“的內(nèi)容,欺騙引擎通過SC_LOAD_DATA通知的處理文件,所以它會(huì)加載我們給出TIScript內(nèi)容,而不是。要做到這一點(diǎn),在你SciterHost派生類中,添加以下到OnLoadData()方法overrided:
if(sld.uri=="sciter:debug-peer.tis"){ string TIScript_content = "function Meow() { stdout.println(1234); }"; byte[] buffer = Encoding.UTF8.GetBytes(TIScript_content); _api.SciterDataReady(_wnd._hwnd, sld.uri, buffer, (uint)buffer.Length);} 這將使得功能喵()可在全球范圍內(nèi)的所有頁(yè)面。請(qǐng)注意,您可以添加任何TIScript代碼,所以你可以例如,添加,改變頁(yè)面的DOM功能的代碼,或檢查與加載頁(yè)面URL self.url() ,并做一些定制的程序。
? -你可以寫HTML像PHP <PHP回聲“無(wú)所謂”; ?>在這里,你可以在HTML的中間混合輸出的可編程性,請(qǐng)參閱:http://sciter.com/forums/topic/new-page-load-using-tiscript/#post-43481
這結(jié)束了beeing一個(gè)很長(zhǎng)的文章,即使它涵蓋了理解所有參與基于C#Sciter桌面應(yīng)用程序的作品的要領(lǐng)。希望它是一個(gè)讀數(shù)清晰。
我計(jì)劃繼續(xù)我的Sciter教學(xué)系列怎么辦HTML / CSS動(dòng)畫的Sciter特定方式的教程。也是我下一個(gè)主要目標(biāo)是有OSX /單聲道SciterSharp支持,如何在這個(gè)平臺(tái)上使用適當(dāng)?shù)慕坛?。敬?qǐng)期待!