現時点では、これはデスクトップアプリケーションを開発するための非常に強力なツールです 。このコントロールを使用したソリューションのリストは、 ここにあります 。 しかし、EvernoteやSteamなどの有名な製品で使用されていると言えば十分です。
このフレームワークは何を提供しますか?
- CEFでは、独自のプロトコルハンドラを作成できるため、独自の「プライベート」暗号化アルゴリズムを実装できます(はい-
はい、古いInternet Explorerと企業Webソリューションの残念なユーザーは、ActiveXを使用しています)。 同じことが静的プログラムリソースからデータをロードするために使用できます - CEFを使用すると、Javascript仮想マシンのオブジェクト空間でネイティブ関数をラップできます。 大量のデータを処理するためのリソース集約型の操作は、より厳密で高速なプログラミング言語に移行できます。
- CEFを使用すると、ナビゲーションのイベント、ファイルのダウンロードなどを処理できます。
一般に、Google Chromeのような独自のブラウザを作成できるすべてのもの(しかし、なぜですか?)。 ただし、HTML5 / CSS3インターフェースとハードウェアアクセラレーショングラフィックスを使用して独自のアプリケーションを作成するために必要になります。
そして今、悲しいことについて
記事の冒頭に記載されているリンクが埋め込まれたchromiumembeddedライブラリは、C ++で実装されています。 しかし、ソリューションが別の制御されたプログラミング言語で既に機能している場合はどうでしょうか? 特に、Java、Delphi、Python、および.NETのラッパーがあります。 .NET用のCefSharpライブラリの使用について説明します。
CefSharpに会う
CefSharpは、 chromembeddedのラッパーライブラリです。 ただし、その機能は後者の機能においてやや劣っています。
利用可能なもの:
- WebViewクラスコンポーネントを無制限に作成
- ページ読み込みイベント、ナビゲーションイベントの処理
- カスタムプロトコルハンドラー。
- ページ実行時のJsコードインジェクション
- 静的メソッドを使用したグローバル[ネイティブコード]オブジェクトの作成
不足しているもの:
- 通常のイベントモデル。 いいえ、真剣に、これは.NETライブラリのようには見えません。
public Window(string Url, CefSharp.BrowserSettings settings = null) { // ... _Browser = new WebView(Url, settings ?? new CefSharp.BrowserSettings { DefaultEncoding = "UTF-8" }); _Browser.PropertyChanged += _Browser_PropertyChanged; // ... } void _Browser_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == "IsBrowserInitialized" && !isInitialized) doSomeStuff(); // }
- WebViewクラスの異なるインスタンスにさまざまなオブジェクトを埋め込みます。 誰でも絶対に登録済みのメソッドを呼び出すことができるという事実に同意する必要があります
- CLRからJSへ、またはその逆への型変換。 この問題を視覚的に解決するための松葉杖についてさらに説明します。
- 呼び出されたメソッドを、WebViewが配置されている特定のフォームに関連付けることはできません。
- マイナスではありませんが、CefSharpをコンパイルする環境はVisual Studio 2008である必要があります。
推奨事項として、ライブラリの操作を非常に迅速に開始できることに注意してください(コンパイルされたバージョンがある場合)。また、HTML + JSソリューションの理解レベルがWPFのレベルよりも低いこと、および複雑な技術を何ヶ月も勉強することを恐れて、あなたの好きなHTMLを簡単に使うことができます。
最初の知り合い
作業に必要な3つの主なものは、ローカルプロトコルハンドラー、グローバルオブジェクト、およびフレームワークを管理するオブジェクトです。
ローカルプロトコルハンドラー
いくつかのクラスが実装されています:ファクトリー(CefSharp.ISchemeHandlerFactoryインターフェースを実装)と、実際には、ハンドラー自体(CefSharp.ISchemeHandlerインターフェースを実装)。
最初のものでは、すべてが明確です:
public class LocalSchemeHandlerFactory : ISchemeHandlerFactory { public ISchemeHandler Create() { return new LocalSchemeHandler(); } }
2番目は難しくありません:
public class LocalSchemeHandler : ISchemeHandler { // , , public bool ProcessRequest(IRequest request, ref string mimeType, ref Stream stream) { // IRequest // mimeType MIME- . , Chromium text/javascript text/plain image/png // Stream , - MemoryStream , return true; // . false } }
アプリケーションのjsファイルを含めるには、ResourceManagerクラスのGetStreamまたはGetStringメソッドを使用できます。 プラス-アプリケーションのソースコードは、.exeまたは.dllファイル内に配置されます。 マイナスの点-js-codeを変更するときは、毎回アプリケーションを再コンパイルする必要があります。
.NETとJS間のブリッジオブジェクト
さらに簡単です-メソッドとフィールドを含む通常のオブジェクトです。 1マイナス-プロジェクト全体で、そのようなクラスのコピーが1つあります。
CEFの初期化
クラスをApplicationContextの後継にすることにしました。 ウィンドウ表示の場合、WinFormsはより高速に実行され、WPFをドラッグする必要はありません。
public class ApplicationController : ApplicationContext { protected Dictionary<string, object> registeredObjects; public ApplicationController(CefSharp.Settings settings = null) { registeredObjects = new Dictionary<string, object>(); string resources = Path.Combine(Directory.GetCurrentDirectory(), "cache"); if (Directory.Exists(resources)) Directory.CreateDirectory(resources); CefSharp.CEF.Initialize(settings ?? new CefSharp.Settings() { Locale = "ru", CachePath = resources }); CefSharp.CEF.RegisterScheme("local", new LocalSchemeHandlerFactory()); registerJsObject("Form", new WindowObject()); // -. } public void registerJsObject(string Name, object Object) { if (!registeredObjects.ContainsKey(Name)) { registeredObjects.Add(Name, Object); CefSharp.CEF.RegisterJsObject(Name, Object); } } }
これで、実際には、すべてです。 フォームを作成し、それにWebViewコンポーネントを追加して、好きなように作業できます。
あなたがこの場所まで読んだことがあるなら、あなたは忍耐強い人であり、私はあなたに感謝しています。
しかし、これは私たちにとって十分ではありません
前述したように、CefSharpにはいくつかの欠陥があります。 たとえば、WebViewコンポーネントを含むフォームに関連付けることはできません。 このために、ある種の残酷な松葉杖が誕生しました。それを一般公開します。
コードの断片で記事を散らかさないために、リストからいくつかの抜粋を提供します。
1フォームから継承した新しいウィンドウクラス
- FormEnumeratorのサブクラスが含まれています。これは、各ウィンドウに一意の文字列識別子を割り当て、すべてのWindowオブジェクトへのリンクを保存します。 getWindowByIdメソッドを使用して、フォームを取得できます。
- ブラウザ環境から呼び出しを受信し、フォーム関数を呼び出すJSInvoke静的メソッド
- .NET JSメソッドを呼び出すCSInvokeメソッド
- プライベートメソッドgetFormRefrection。フォームのCLRメソッドのラッパーを作成します。 文字列は、反射データに基づいてStringBuilderによって形成されます。 次のようになります。
2共通のCall Bridgeオブジェクト
JSからC#への呼び出し操作を実行します。
public class WindowObject { public string Invoke(string Id, string Method, string JSONData) { object x = JSON.JsonDecode(JSONData); if (x is ArrayList) { ArrayList y = (ArrayList)x; object[] args = new object[y.Count]; for (var i = 0; i < args.Length; i++) args[i] = y[i]; return JScripter.CreateString(Window.JSInvoke(Id, Method, args)); } else return JScripter.CreateString(Window.JSInvoke(Id, Method, new object[] { x })); } public void Close(string Id) { Window.FormEnumerator.getWindow(Id).Close(); } }
注意深い読者は、何かが間違っていることに気付くでしょう。通常のオブジェクトの代わりに、CefSharpでは、int、double、bool、stringなどの単純な型のみを交換できます。 しかし、実際には、通常は正反対です。 したがって、この松葉杖はJSONでデータのパッキング/アンパッキングを使用します。 解決策は不完全で、無駄な時間がかかりますが、これらはライブラリの制限です。
DataContractJsonSerializerは特定のタイプでのみ機能するため、使用するには問題があります。 そのため、プロジェクトでは100%マネージパーサーを使用しました。 松葉杖も。
ここでコードを見つけることができます。