本文目錄一覽:
- 1、能不能用c++寫程序,然後裏面嵌入一個網頁,網頁需要支持Js,並且也可以用c++獲取這個網頁的一切
- 2、如何在CEF JS與browser進程間異步通信
- 3、Xilium.CefGlue怎麼使用Js調用C#方法
- 4、如何利用CEF3創建一個簡單的應用程序
- 5、wpf寫的前端改成用js寫可以嗎?
能不能用c++寫程序,然後裏面嵌入一個網頁,網頁需要支持Js,並且也可以用c++獲取這個網頁的一切
你可以把chromium的開源工程拿來,這個工程你來改造,就可以辦到。
不過難度相對不低,你說的對,類似於自己完成瀏覽器。
chromium的cef3 API可以幫助你完成這些事情。
如何在CEF JS與browser進程間異步通信
基於CEF開發時經常需要在JS和C++代碼間通信,我們在CEF中JavaScript與C++交互中討論了常見的交互方式,不過都是在Renderer進程中,這次來看看如何在JS和Browser進程間通信,基本介紹可以看這裡:
具體做法,上面給出的鏈接里有大概說明,另外在cef_message_router.h中有詳細說明,它分了9步,有需要的可以去查看。我試驗了下可行。按照我的實驗,從三個方面來說說:
browser進程
renderer進程
html中的js
foruok原創,轉載請關注微信訂閱號「程序視界」聯繫foruok。
browser進程
1)配置browser進程這一側的Message Router
使用CefMessageRouterConfig來定義可以在html中使用的方法名字。代碼片段可能如下:
…
CefMessageRouterConfig g_messageRouterConfig;
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// Enable High-DPI support on Windows 7 or newer.
CefEnableHighDPISupport();
g_messageRouterConfig.js_query_function = “cefQuery”;
g_messageRouterConfig.js_cancel_function = “cefQueryCancel”;
CefMainArgs main_args(hInstance);
…
}
注意我在main函數之外定義了一個CefMessageRouterConfig的實例,然後在main函數中設置了query和cancel這兩個函數。它們定義了可以在html的js代碼里使用的方法,比如根據上面代碼,你可以用window.cefQuery({…})。
2)創建CefMessageRouterBrowserSide的實例
browser進程這邊需要一個CefMessageRouterBrowserSide的實例來處理renderer進程發過來的消息。建議把這個實例作為成員變量放在CefClient的派生類中,因為它CefMessageRouterBrowserSide定義了一些方法,需要在指定的地方調用。
聲明和初始化的代碼片段:
CefRefPtrCefMessageRouterBrowserSide m_browser_side_router;
…
extern CefMessageRouterConfig g_messageRouterConfig;
m_browser_side_router = CefMessageRouterBrowserSide::Create(g_messageRouterConfig);
…
3)調用預定義方法
CefMessageRouterBrowserSide預定義了下列接口,需要在指定地方調用:
// call from CefClient::OnProcessMessageReceived
bool OnProcessMessageReceived(…)
// call from CefLifeSpanHandler::OnBeforeClose()
void OnBeforeClose(CefRefPtrCefBrowser browser)
// call from CefRequestHandler::OnRenderProcessTerminated()
void OnRenderProcessTerminated(CefRefPtrCefBrowser browser)
// call from CefRequestHandler::OnBeforeBrowse()
void OnBeforeBrowse(…)
所以,我們的這個ClientHandler類,聲明如下:
class ClientHandler : public CefClient,
public CefDisplayHandler,
public CefLifeSpanHandler,
public CefLoadHandler,
public CefRequestHandler
{
…
}
ClientHandler要實現CefClient的OnProcessMessageReceived、CefLifeSpanHandler的OnBeforeClose、CefRequestHandler的OnRenderProcessTerminated和OnBeforeBrowse方法,在這些方法里調用CefMessageRouterBrowserSide的同名方法即可。代碼片段如下:
void ClientHandler::OnBeforeClose(CefRefPtrCefBrowser browser)
{
CEF_REQUIRE_UI_THREAD();
m_browser_side_router-OnBeforeClose(browser);
…
}
bool ClientHandler::OnProcessMessageReceived(CefRefPtrCefBrowser browser,
CefProcessId source_process,
CefRefPtrCefProcessMessage message)
{
if (m_browser_side_router-OnProcessMessageReceived(browser, source_process, message)) return true;
return false;
}
bool ClientHandler::OnBeforeBrowse(CefRefPtrCefBrowser browser, CefRefPtrCefFrame frame, CefRefPtrCefRequest request, bool is_redirect)
{
m_browser_side_router-OnBeforeBrowse(browser, frame);
return false;
}
void ClientHandler::OnRenderProcessTerminated(CefRefPtrCefBrowser browser, TerminationStatus status)
{
m_browser_side_router-OnRenderProcessTerminated(browser);
}
4) 在browser進程里實現處理JS查詢的handler
CefMessageRouterBrowserSide定義了一個內部類Handler,繼承它:
class BrowserSideJSHandler : public CefMessageRouterBrowserSide::Handler
{
public:
BrowserSideJSHandler();
virtual bool OnQuery(CefRefPtrCefBrowser browser,
CefRefPtrCefFrame frame,
int64 query_id,
const CefString request,
bool persistent,
CefRefPtrCallback callback);
virtual void OnQueryCanceled(CefRefPtrCefBrowser browser,
CefRefPtrCefFrame frame,
int64 query_id);
};
實現 OnQuery 和 OnQueryCanceled兩個方法:
bool BrowserSideJSHandler(CefRefPtrCefBrowser browser,
CefRefPtrCefFrame frame, int64 query_id,
const CefString request, bool persistent, CefRefPtrCallback callback)
{
if (request == “HelloCefQuery”)
{
callback-Success(“HelloCefQuery Ok”);
return true;
}
else if (request == “GiveMeMoney”)
{
callback-Failure(404, “There are none thus query!”);
return true;
}
return false; // give other handler chance
}
void BrowserSideJSHandler::OnQueryCanceled(CefRefPtrCefBrowser browser, CefRefPtrCefFrame frame, int64 query_id)
{
//cancel our async query task…
}
5)給CefMessageRouterBrowserSide的實例添加handler
我在ClientHandler類中定義了一個BrowserSideJSHandler的實例,類似下面:
class ClientHandler : public CefClient,
public CefDisplayHandler,
public CefLifeSpanHandler,
public CefLoadHandler,
public CefRequestHandler
{
…
CefRefPtrCefMessageRouterBrowserSide m_browser_side_router;
BrowserSideJSHandler m_jsHandler;
…
}
然後在ClientHandler構造函數中加入了下列代碼:
m_browser_side_router-AddHandler(m_jsHandler, true);
上面的代碼把BrowserSideJSHandler加入到browser進程里的消息路由器中。
好了,到這裡browser進程配置完成。接下來看renderer進程。
Xilium.CefGlue怎麼使用Js調用C#方法
第1篇:.NET多種WebKit內核/Blink內核瀏覽器初步測評報告
第2篇:Xilium CefGlue 關於 CLR Object 與 JS 交互類庫封裝報告:導航篇
第3篇:Xilium CefGlue 關於 CLR Object 與 JS 交互類庫封裝報告:官方原生方法分析
第4篇:Xilium CefGlue 關於 CLR Object 與 JS 交互類庫封裝報告:委託回調方法分析
第5篇:Xilium CefGlue 關於 CLR Object 與 JS 交互類庫封裝報告:自動註冊JS腳本+委託回調方法分析
第6篇:Xilium CefGlue 關於 CLR Object 與 JS 交互類庫封裝報告:自動註冊JS腳本+自動反射方法分析
第7篇:Xilium CefGlue 關於 CLR Object 與 JS 交互類庫封裝報告:全自動註冊與反射方法分析
如何利用CEF3創建一個簡單的應用程序
開始
首先,根據自身所使用的開發平台,可以去 這裡 下載對應的發佈版本。針對這個教程,我們需要下載1750或者更新的版本。當前支持的平台有Windows, Linux和Mac OS X。每一個版本都包含了當在特定平台上編譯特定版本CEF3時所需要的所有文件和資源。您可以通過包含在裡邊的 REDME.txt 文件或者在Wiki上GeneralUsage 中的 Getting Started,了解每個發佈版本的具體內容和細節。
編譯發佈版本中的項目
以CEF發佈版本為基礎開發的應用程序可以使用標準的平台編譯工具進行編譯執行。包括 Windows 平台下的 Visual Studio, Mac OS X 平台下的 Xcode, 以及 Linux 平台下的 gcc/make。針對平台的不同,項目的編譯過程也有些許的不同和要求。
Windows
Windows 平台下編譯 Cefsimple 步驟:
1. 用對應的 Visual Studio 版本打開項目解決方案。舉個例子,如果你安裝的是 Visual Studio 2010, 那麼,打開的就是 cesimple2010.sln。
2. 如果你下載的是 x64版本,請確保你選擇的是 x64的開發平台。
3. 開始編譯。
4. 如果編譯通過,那麼,在當前解決方案的目錄下,將出現「out/Debug」(或者 「out/Release」)文件夾。
5. 執行文件夾下 cefsimple.exe, 確保能正確運行。
加載一個自定義URL
cefsimple項目中默認加載的URL是 google.com,當然,你也可以用自定義的 URL 去替代它,最方便的就是通過命令行搞定。
# Load the local file 「c:\example\example.html」
cefsimple.exe –url=
除了命令行的方法,也可以通過直接修改在 cefsimple/simple.cpp 文件中的代碼,達到你的目的。
# Load the local file 「c:\example\example.html」
…
if (url.empty())
url = ;
應用程序組成
所有的 CEF 應用程序都有一下主要組成部分:
1. CEF 的動態鏈接庫 。(在 Windows 平台下就是 libcef.dll)
2. 支持庫。(ICU, FFMPEG等)
3. 資源。(html/js/css, strings等)
4. 客戶端執行文件。(本教程中就是 cefsimple.exe.)
要點(必看)
1. CEF 使用的是多進程。應用程序主進程是瀏覽器進程,而其他子進程是由 renderer, plugins, GPU等創建。
2. 在 Windows 和 Linux 平台下的執行文件可以被主進程和子進程使用。
3. CEF 中所有進程都可以是多線程的。CEF提供了許多功能和接口在不同的線程中傳遞任務。
4. 一些回調方法和函數只能在特定的進程或者線程中使用。在你第一次使用新的回調方法或者函數之前,請確保你已經閱讀了 API 頭文件中源碼,看使用要求。
流程分析
cefsimple 應用程序首先初始化CEF,然後創建了一個簡單的彈出瀏覽器窗口。當關閉了所有的瀏覽器窗口,應用程序就會結束。程序執行流程如下:
1. 系統執行入口點函數(main or wWinMain),並創建瀏覽器進程。
2. 入口點函數:
1. 創建能夠處理進程級別的回調方法的 SimpleApp 實例。
2. 初始化 CEF,進入 CEF 消息循環。
3. 初始化 CEF 之後,調用 SimpleApp::OnContextInitialized() 。這個方法中:
1. 創建單例的 SimpleHandler 。
2. 由 CefBrowserHost::CreateBrowsersync() 方法創建一個瀏覽器窗口。
4. 所有的瀏覽器共享 SimpleHandler 實例, 此實例能定製瀏覽器行為、處理瀏覽器相關回調方法(life span, loading state, title display等)。
5. 當一個瀏覽器窗口關閉的時候,調用 SimpleHandler::OnBeforeClose() 。當所有的瀏覽器窗口全部關閉時,OnBeforeClose() 函數就會執行跳出 CEF 消息循環的行為,退出應用程序。
入口點函數
程序的運行開始於瀏覽器進程中的入口點函數。這個函數會初始化 CEF 以及所有跟操作系統有關的對象。
Windows
#include windows.h
#include “cefsimple/simple_app.h”
#include “include/cef_sandbox_win.h”
// Set to 0 to disable sandbox support.
#define CEF_ENABLE_SANDBOX 1
#if CEF_ENABLE_SANDBOX
// The cef_sandbox.lib static library is currently built with VS2010. It may not
// link successfully with other VS versions.
#pragma comment(lib, “cef_sandbox.lib”)
#endif
// Entry point function for all processes.
int APIENTRY wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow) {
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
void* sandbox_info = NULL;
#if CEF_ENABLE_SANDBOX
// Manage the life span of the sandbox information object. This is necessary
// for sandbox support on Windows. See cef_sandbox_win.h for complete details.
CefScopedSandboxInfo scoped_sandbox;
sandbox_info = scoped_sandbox.sandbox_info();
#endif
// Provide CEF with command-line arguments.
CefMainArgs main_args(hInstance);
// SimpleApp implements application-level callbacks. It will create the first
// browser instance in OnContextInitialized() after CEF has initialized.
CefRefPtrSimpleApp app(new SimpleApp);
// CEF applications have multiple sub-processes (render, plugin, GPU, etc)
// that share the same executable. This function checks the command-line and,
// if this is a sub-process, executes the appropriate logic.
int exit_code = CefExecuteProcess(main_args, app.get(), sandbox_info);
if (exit_code = 0) {
// The sub-process has completed so return here.
return exit_code;
}
// Specify CEF global settings here.
CefSettings settings;
#if !CEF_ENABLE_SANDBOX
settings.no_sandbox = true;
#endif
// Initialize CEF.
CefInitialize(main_args, settings, app.get(), sandbox_info);
// Run the CEF message loop. This will block until CefQuitMessageLoop() is
// called.
CefRunMessageLoop();
// Shut down CEF.
CefShutdown();
return 0;
}
SimpleApp
SimpleApp 負責處理進程級別的回調方法。它會曝露出一些在多進程中共享或者被特定進程使用的接口和方法。CefBrowserProcessHandler 接口,在瀏覽器進程中調用。還有一個被分離出 CefBrowserProcessHandler 接口(例子項目沒有展示)只會在渲染進程中被調用。由於 CefBrowserProcessHandler 不光實現了 CefApp, 同時還有 CefBrowserProcessHandler,所以它的返回值必須是[this]。
// simple_app.h
#include “include/cef_app.h”
class SimpleApp : public CefApp,
public CefBrowserProcessHandler {
public:
SimpleApp();
// CefApp methods:
virtual CefRefPtrCefBrowserProcessHandler GetBrowserProcessHandler()
OVERRIDE { return this; }
// CefBrowserProcessHandler methods:
virtual void OnContextInitialized() OVERRIDE;
private:
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(SimpleApp);
};
// simple_app.cpp
#include “cefsimple/simple_app.h”
#include string
#include “cefsimple/simple_handler.h”
#include “cefsimple/util.h”
#include “include/cef_browser.h”
#include “include/cef_command_line.h”
SimpleApp::SimpleApp() {
}
void SimpleApp::OnContextInitialized() {
REQUIRE_UI_THREAD();
// Information used when creating the native window.
CefWindowInfo window_info;
#if defined(OS_WIN)
// On Windows we need to specify certain flags that will be passed to
// CreateWindowEx().
window_info.SetAsPopup(NULL, “cefsimple”);
#endif
// SimpleHandler implements browser-level callbacks.
CefRefPtrSimpleHandler handler(new SimpleHandler());
// Specify CEF browser settings here.
CefBrowserSettings browser_settings;
std::string url;
// Check if a “–url=” value was provided via the command-line. If so, use
// that instead of the default URL.
CefRefPtrCefCommandLine command_line =
CefCommandLine::GetGlobalCommandLine();
url = command_line-GetSwitchValue(“url”);
if (url.empty())
url = “”;
// Create the first browser window.
CefBrowserHost::CreateBrowserSync(window_info, handler.get(), url,
browser_settings, NULL);
}
SimpleHandler
SimpleHandler 負責處理瀏覽器級別的回調方法。這些回調方法會在瀏覽器進程中執行。在這個項目中,針對所有的瀏覽器使用相同的 CefClient 實例,但是如果你願意,可以在自己的應用程序中使用不同的 CefClient實例的。
// simple_handler.h
#include “include/cef_client.h”
#include list
class SimpleHandler : public CefClient,
public CefDisplayHandler,
public CefLifeSpanHandler,
public CefLoadHandler {
public:
SimpleHandler();
~SimpleHandler();
// Provide access to the single global instance of this object.
static SimpleHandler* GetInstance();
// CefClient methods:
virtual CefRefPtrCefDisplayHandler GetDisplayHandler() OVERRIDE {
return this;
}
virtual CefRefPtrCefLifeSpanHandler GetLifeSpanHandler() OVERRIDE {
return this;
}
virtual CefRefPtrCefLoadHandler GetLoadHandler() OVERRIDE {
return this;
}
// CefDisplayHandler methods:
virtual void OnTitleChange(CefRefPtrCefBrowser browser,
const CefString title) OVERRIDE;
// CefLifeSpanHandler methods:
virtual void OnAfterCreated(CefRefPtrCefBrowser browser) OVERRIDE;
virtual void OnBeforeClose(CefRefPtrCefBrowser browser) OVERRIDE;
// CefLoadHandler methods:
virtual void OnLoadError(CefRefPtrCefBrowser browser,
CefRefPtrCefFrame frame,
ErrorCode errorCode,
const CefString errorText,
const CefString failedUrl) OVERRIDE;
// Request that all existing browser windows close.
void CloseAllBrowsers(bool force_close);
private:
// List of existing browser windows. Only accessed on the CEF UI thread.
typedef std::listCefRefPtrCefBrowser BrowserList;
BrowserList browser_list_;
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(SimpleHandler);
};
// simple_handler.cpp
#include “cefsimple/simple_handler.h”
#include sstream
#include string
#include “cefsimple/util.h”
#include “include/cef_app.h”
#include “include/cef_runnable.h”
namespace {
SimpleHandler* g_instance = NULL;
wpf寫的前端改成用js寫可以嗎?
可以。
通過NuGet獲取CefSharp.WpF組件。xmlns:cefSharp=”clr-namespace:CefSharp.Wpf,assembly=CefSharp.Wpf”加載,需要把項目的cpu設置成x86,Framework4.5。
js全稱JavaScript,是運行在瀏覽器上的腳本語言,連續多年被評為全球最受歡迎的編程語言。js可以使網頁具有交互性,例如響應用戶點擊,給用戶提供更好的體驗。還可以根據用戶的操作,動態的創建頁面。主要目的是為了解決服務器終端語言,比如Perl,遺留的速度問題。當時服務端需要對數據進行驗證,由於網絡速度相當緩慢,只有28.8kbps,驗證步驟浪費的時間太多。於是Netscape的瀏覽器Navigator加入了Javascript,提供了數據驗證的基本功能。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/185565.html