讓基於CEF的應用支援自定義協議

基於CEF開發瀏覽器或Native與Web混合的富客戶端,可以支援自定義協議,當點選網頁上的自定義協議連結時,呼叫系統註冊的協議處理程式。

實現分兩部分:

  • 修改登錄檔註冊自定義協議
  • 基於CEF的程式碼

修改登錄檔註冊自定義協議

假定我們註冊協議是mypro,照下面做即可:

  1. 在HKEY_CLASSES_ROOT下新建項mypro
  2. 在mypro下新建字串值“URL Protocol”,這個字串值的數值資料可有可無
  3. 在mypro下新建shell項,shell下新建open項,open下新建command項
  4. 在command項的預設值是字串值,裡面填寫類似[“C:\Windows\System32\notepad.exe” “%1”]這樣的內容

這樣準備工作就做好了。抓了倆圖,對著看看吧。

CEF程式碼實現

在實現CefClient的派生類時,實現CefRequestHandler即可,類似下面:

class ClientHandler : public CefClient,
public CefRequestHandler
{
...
}

要重寫的CefRequestHandler介面有兩個:

  • OnBeforeBrowse
  • OnProtocolExecution

大概說一下這兩個虛擬函式。

OnBeforeBrowse的原型如下:

  virtual bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool is_redirect);

前兩個引數不說了,關鍵是第三個,它代表了請求,request->GetURL()就能拿到URL,進而可以判斷是否是我們的mypro協議。

OnBeforeBrowse函式在一個頁面開啟之前呼叫,如果你返回false,頁面會繼續載入,如果返回true,就停止載入了。如果你發現是mypro協議,就返回true,讓OnProtocolExecution函式繼續處理,否則返回false,讓瀏覽器繼續載入。

重寫的OnBeforeBrowse程式碼大概如下:

bool ClientHandler::OnBeforeBrowse(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, bool is_redirect)
{
std::wstring url = request->GetURL().ToWString();
return url.find_first_of(L"mypro://") == 0;
}

OnProtocolExecution的原型如下:

virtual void OnProtocolExecution(CefRefPtr<CefBrowser> browser,
const CefString& url,
bool& allow_os_execution) ;

注意第三個引數,allow_os_execution,它預設值為false,不會呼叫登錄檔內註冊的自定義協議,需要修改它為true。

第二引數是來自<a>標籤的href屬性的值,就是URL。如果你想自己在C 程式碼裡處理,可以直接啟動一個應用來處理這個URL,如果你想交給系統處理,只要修改allow_os_execution為true即可。

重寫的OnProtocolExecution程式碼類似下面:

void ClientHandler::OnProtocolExecution(CefRefPtr<CefBrowser> browser,
const CefString& url,
bool& allow_os_execution)
{
// do something with url...
allow_os_execution = true;
}

程式碼實現Ok了。

測試

測試網頁內容如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<p><a  href="mypro://xxx">My Protocol<a/></p>
</body>
</html>

執行效果如下:


CEF專欄:http://blog.csdn.net/column/details/cef-ppapi.html