起因 在某些情況下,有將從某種類型的語言翻譯成另一種類型語言的需求。比如在生成實體時,可能需要將中文名稱轉換成英文。於是利用CEFSharp山寨了一個翻譯器。效果圖如下: CEF簡介 CEF全稱為Chromium Emmbed Framework,是一個開源項目。用於嵌入基於 Google Chro ...
起因
在某些情況下,有將從某種類型的語言翻譯成另一種類型語言的需求。比如在生成實體時,可能需要將中文名稱轉換成英文。於是利用CEFSharp山寨了一個翻譯器。效果圖如下:
CEF簡介
CEF全稱為Chromium Emmbed Framework,是一個開源項目。用於嵌入基於 Google Chromium 項目的 Web 瀏覽器控制項。
CEF在.NET中的應用
CEF是由C++所寫,無法直接應用到.NET中。需要通過某種形式進行包裝。常見的有Xilium.CefGlue和CEFSharp。我個人比較熟悉CEFSharp一些。
在CEFSharp的眾多功能中,我最喜歡CEF執行JS代碼、註冊本地對象這兩項功能,結合上述兩項功能,可以作出很多有意思的效果出來。
由於CEFSharp的WPF版本在Win10會出現無法輸入中文的問題,所以我一般都使用CEFSharp的WinForm版本,在WPF中,也是通過WindowsFormsHost來進行包裝。
山寨翻譯器的原理
山寨翻譯器就是在界面上放了一個CEFSharp的瀏覽器,瀏覽器訪問必應翻譯。當在界面上輸入中文時,利用JS代碼將必應翻譯頁面的待翻譯句子設為界面上的中文,然後利用JS代碼模擬點擊翻譯按鈕,當必應翻譯獲得結果時,利用JS調用本地代碼將界面結果設置為必應翻譯的結果。
此時,有人會提出疑問了。CEFSharp的瀏覽器在哪?我怎麼沒在界面上看到?其實這裡用了一個小Trick,將瀏覽器的寬度和高度都設成了1像素,當然看不到了。
一些細節
延時觸發翻譯
當輸入要翻譯的中文較快時,如果每次輸入一變化,就調用一次前文所說的翻譯過程,這樣效率比較低。而且還存在交互性問題,如果不阻塞用戶的輸入,這樣在網路不穩定的情況下,先前的翻譯結果可能最後才到,這樣翻譯結果就不准確了。如果阻塞的話,網路快還好說,網路慢輸一下卡一下,體驗極其不好。
所以我基於Blend的Interactivity新建了ThrottleInvokeCommandAction,可以在無操作後一定的時間調用命令。
翻譯完成通知
由於我們不知道什麼時候翻譯完成了,此時可以監聽DOMNodeInserted事件以得到通知。當事件發生時,會自動調用註冊的本地對象的方法,不過在js中的方法名稱和C#方法名稱是不一樣的,需要使用首字母小寫的形式。
啟用開發者工具
在CEF中,可以啟用開發者工具,這樣會方便我們的調試。在我的代碼中,監聽了CEF的鍵盤事件,當按下F12時,就顯示開發者工具。
進階
上述只是一個簡單的翻譯,在必應翻譯頁面上還有其他翻譯可選項,可將其整合到山寨翻譯器中。比如多個候選項的選擇,或是將翻譯過程整合到實體生成中。
代碼下載
博客園:Translator
註意事項
- 下載的源代碼中缺少引用 的DLL,相關DLL見截圖
獲取cefsharp39可通過nuget,命令如下:Install-Package CefSharp.WinForms -Version 39.0.0
獲取Prism可通過nuget,命令如下:Install-Package Prism -Version 4.1.0
- 運行前請將cefsharp39相關引用文件複製到生成目錄中。
- 在工程屬性的生成標簽頁上,請將目標平臺設為x86。