DCEF3 相关资料
转自:https://www.cnblogs.com/xiefang2008/p/5969610.html
DCEF3 调用 js
http://www.cnblogs.com/Delphi-Farmer/p/4103708.html
DCEF3 调用 js
http://www.cnblogs.com/Delphi-Farmer/p/4103708.html
interface uses ceflib;//其它 type //这里建议用class 不建议用class(TThread) 不然有些地方要报错 TMyExtension = class(TThread) // or just class, (extension code execute in thread) public class function _geta:string; end; TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn) protected procedure OnWebKitInitialized; override; end; implementation class function TMyExtension._geta: string; begin Result:='调用成功'; end; procedure TCustomRenderProcessHandler.OnWebKitInitialized; begin TCefRTTIExtension.Register('JS_DELPHI', TMyExtension); end; initialization CefRenderProcessHandler := TCustomRenderProcessHandler.Create; end.
JS调用实例:
<script> alert( JS_DELPHI._geta() ); <script>
这种方式调用时要写注册的类名:JS_DELPHI
在CEF1中是不需要写类名的,这点要注意
Dcef 与 js 交互
type TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn) protected procedure OnWebKitInitialized; override; end; TDcefb_Extension = class class procedure DoTest(Msg: string); end; class procedure TDcefb_Extension.DoTest(Msg: string); begin ShowMessage(Msg); end; procedure TCustomRenderProcessHandler.OnWebKitInitialized; begin TCefRTTIExtension.Register('Dcefb_Test', TDcefb_Extension); end;
工程文件内添加
CefRenderProcessHandler := TCustomRenderProcessHandler.Create; if not CefLoadLibDefault then Exit; 测试代码 DcefBrowser1.ExecuteJavaScript('Dcefb_Test.DoTest("TestStr");');
2. 关于 Tchrome 中加载 JS 与 delphi 交互问题
http://www.cnblogs.com/Delphi-Farmer/archive/2013/05/17/3083794.html
按 Ctrl+C 复制代码
按 Ctrl+C 复制代码
黑屏问题
因为部分集成显卡版本太老或是不支持,导致webkit渲染失败,手动添加参数,关闭硬件渲染
procedure OnbeforeCmdLine(const processType: ustring; const commandLine: ICefCommandLine); begin commandLine.AppendSwitch('disable-gpu'); end; CefOnBeforeCommandLineProcessing := OnbeforeCmdLine;
让 DCEF 支持摄像头
当前版本需要手动添加参数,可能以后dcef3会提供接口甚至回调事件
procedure OnbeforeCmdLine(const processType: ustring; const commandLine: ICefCommandLine); begin commandLine.AppendSwitch('enable-media-stream'); end; CefOnBeforeCommandLineProcessing := OnbeforeCmdLine;
支持 Flash
需要用到pepperflash插件,由于git上不能上传这类文件,还有版权问题,就未添加到TDcefBrowser里
if not CefLoadLibDefault then Exit; CefAddWebPluginPath(ExtractFilePath(Paramstr(0)) + 'PepperFlash\pepflashplayer.dll'); CefRefreshWebPlugins();
解决语言环境问题
单纯的设置CefLocale := 'zh-CN'有时并不能解决问题,JS获取的navigator.language的确为zh-CN,但很多网页通过HTTPACCEPTLANGUAGE来判断语言,例如QQ邮箱,因此我们需要在OnBeforeResourceLoad事件中做相应的设置
procedure TMainForm.DcefBrowserBeforeResourceLoad(const PageIndex: Integer; const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; var CancelLoad: Boolean); var hm: ICefStringMultimap; begin if Not request.IsReadOnly then begin hm := TCefStringMultimapOwn.Create; request.GetHeaderMap(hm); hm.Append('Accept-Language', 'zh-CN'); request.SetHeaderMap(hm); end; end;
CefSharp 实现 javascript 回调 c# 方法
http://www.cnblogs.com/worgeling/p/3421648.html
在构建完WebView webView = new WebView(url)后,即可调用RegisterJsObject方法来注册一个js对象,从而前端的javascript就可以访问这个对象,调用定义的方法。
public class CallbackObjectForJs{ public void showMessage(string msg){ MessageBox.Show(msg); } } WebView webView = new WebView("http://localhost:8080"); webView.RegisterJsObject("callbackObj", new CallbackObjectForJs());
前端页面javascript代码即可访问对象 callbackObj。
<script type="text/javascript"> callbackObj.showMessage('message from js'); </script >
注意:CallbackObjectForJs的showMessage方法首字母不能使大写,不然javascript回调的时候找不到对应的方法。原因还在分析中。。。
PS:cefsharp是一个用于C#的浏览器控件(开源),C#自带的控件在IE内核适配的问题上处理起来有点麻烦,同时如果网页是重度使用javascript,那你可以考虑基于cef的各种浏览器控件,执行效率飙升。cefsharp的github:https://github.com/cefsharp/CefSharp
Use this code to delete Cookies from Chromium Version CEF3:
Use c_WB_ClearCookies for deleating all Cookies
Use c_WB_Clear_url_Cookies for deleating all Cookies only from one speceally Url like this -> c_WB_Clear_url_Cookies('http://google.com','cookie_name');
type CefTask = class(TCefTaskOwn) procedure Execute; override; public var url,cookieName: ustring; constructor create; virtual; end; constructor CefTask.create; begin inherited create; url := ''; cookieName := ''; end; procedure CefTask.Execute; var CookieManager: ICefCookieManager; begin CookieManager := TCefCookieManagerRef.Global; CookieManager.DeleteCookies(url,cookieName); end; procedure c_WB_ClearCookies; var Task: CefTask; begin Task := CefTask.Create; CefPostTask(TID_IO, Task); end; // c_WB_Clear_url_Cookies('http://google.com','cookie_name'); procedure c_WB_Clear_url_Cookies(c_url,c_cookieName: ustring); var Task: CefTask; begin Task := CefTask.Create; Task.url := c_url; Task.cookieName := c_cookieName; CefPostTask(TID_IO, Task); end;
For list all Cookies to get the cookieName use Procedure list_all_cookies
procedure pausek; var M: TMsg; begin while PeekMessage(M, 0, 0, 0, pm_Remove) do begin TranslateMessage(M); DispatchMessage(M); end; end; procedure pause(i:longint); var j : nativeint; begin for j := 1 to i do begin pausek; sleep(100); end; end; procedure list_all_cookies; var CookieManager: ICefCookieManager; cookie_list : string; const lf = chr(13) + chr(10); begin cookie_list := ''; CookieManager := TCefCookieManagerRef.Global; CookieManager.VisitAllCookiesProc( function(const name, value, domain, path: ustring; secure, httponly, hasExpires: Boolean; const creation, lastAccess, expires: TDateTime; count, total: Integer; out deleteCookie: Boolean): Boolean begin cookie_list := cookie_list + inttostr(count) + ': ' + domain + ' - ' + name + ' - ' + value + ' - ' + path + lf; if (count<total) then result := true; end ); pause(10); ShowMessage(cookie_list); end;
Create and get a cookie
http://stackoverflow.com/questions/16086160/delphi-chromium-embedded-create-and-get-a-cookie/23723741#23723741
Uses ceflib; const DefaultCookiesDir = 'Cookies/'; implementation {$R *.dfm} procedure TForm1.Button2Click(Sender: TObject); var CookieManager: ICefCookieManager; CookiesPath : String; begin CookiesPath := ExtractFilePath(Application.ExeName) + DefaultCookiesDir + 'User1'; CookieManager := TCefCookieManagerRef.GetGlobalManager; CookieManager.SetStoragePath(CookiesPath); Chromium1.Load('www.vk.com'); end;
A guy form the official's DCEF3 forum provided the solution below, tested and approved !
CookieManager: ICefCookieManager; FormCreate: begin CookiesPath := ExtractFilePath(Application.ExeName) + 'cookies'; CookieManager := TCefCookieManagerRef.Global(nil); CookieManager.SetStoragePath(CookiesPath, True, nil); end; FormClose: begin CookieManager.FlushStore(nil); end
为按钮添加单击事件 Sample
{$I cef.inc} type TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn) protected procedure OnWebKitInitialized; override; function OnProcessMessageReceived(const browser: ICefBrowser; sourceProcess: TCefProcessId; const message: ICefProcessMessage): Boolean; override; end; TTestExtension = class class function hello: string; end; procedure TMainForm.Button2Click(Sender: TObject); begin Chromium.browser.SendProcessMessage(PID_RENDERER, TCefProcessMessageRef.New('visitdom'));//操作DOM end; procedure ButtonClickProc(const Event: ICefDomEvent); begin ShowMessage('Click The Button'); end; procedure VisitDomProc(const Doc: ICefDomDocument); var ButtonNode: ICefDomNode; begin ButtonNode := Doc.GetElementById('su1'); if Assigned(ButtonNode) then ButtonNode.AddEventListenerProc('click', True, ButtonClickProc); end; { TCustomRenderProcessHandler } function TCustomRenderProcessHandler.OnProcessMessageReceived( const browser: ICefBrowser; sourceProcess: TCefProcessId; const message: ICefProcessMessage): Boolean; begin {$IFDEF DELPHI14_UP} if (message.Name = 'visitdom') then begin browser.MainFrame.VisitDomProc( VisitDomProc); Result := True; end else {$ENDIF} Result := False; end; procedure TCustomRenderProcessHandler.OnWebKitInitialized; begin {$IFDEF DELPHI14_UP} TCefRTTIExtension.Register('app', TTestExtension); {$ENDIF} end; { TTestExtension } class function TTestExtension.hello: string; begin Result := 'Hello from Delphi'; end; initialization CefRenderProcessHandler := TCustomRenderProcessHandler.Create; CefBrowserProcessHandler := TCefBrowserProcessHandlerOwn.Create; end.