unit utslvclcef; //20250410 {** @explan(说明)封装cef到vcl控件,提供cef窗口的宿主控件 %% **} interface uses utslvclcefinterface,tslvcl; type tcefowner = class(tcustomcontrol) {** @explan(说明)窗口的宿主控件 **} protected static fargs; //命令行参数 static fcefapp; //app static fappsetting; //app设置 static finitcef; //初始化标记 static finitcefobj;//初始化标记 static fcefloop; //消息循环 static fcefwindows; class function initcef(); //初始化cef begin if not finitcef then begin fcefwindows := array(); finitcef := true; sinit(); fcefloop := new tcefproc(); fcefapp.on_before_command_line_processing := function(o,u,cmd) begin //cmd.set_program(%% D:\Program Files\Tinysoft\AnalyseNG.NET\tsl_cef_main.exe%%); //cmd.Append_Switch("single-process"); end app := initializeapplication(); app.addExitMessageLoopdo(thisfunction(cef_shutdown)); cef_initialize(fargs._getptr_(), fappsetting._getptr_(), fcefapp._getptr_(),0); end end class function sinit();override; //初始化 begin if not finitcefobj then begin inherited; finitcefobj := true; fargs := new cef_main_args_t(); fcefapp := new cef_app_t(); fappsetting := new cef_settings_t(); tp := unit(utslvclauxiliary).gettemppath(); fappsetting.log_file := tp+"-cefownerlogfile-"+datetostr(date())+".log"; fappsetting.browser_subprocess_path := tslpath()+"tsl_cef_main"; fappsetting.cache_path := tp+"-cefownercatche-"; fappsetting.log_severity :=99;//0; end end public function create(AOwner); begin inherited; width := 300; height := 300; fwinfo := new cef_window_info_t(); fclient := new cef_client_t(); fbrssetting := new cef_browser_settings_t(); ftimer := new TTimer(self); end function checknewchild(c);override; begin return false; end function WMSize(o,e);override; begin if not HandleAllocated() then return ;// ch := _wapi.GetWindow(o.handle,GW_CHILD); if ch then begin rc := ClientRect; _wapi.SetWindowPos(ch,0,rc[0],rc[1],rc[2],rc[3],0); end end function InitializeWnd();override; begin inherited; if HandleAllocated() then begin if not ifarray(fcefwindows) then begin fcefwindows := array(); end fhandlebk := inttostr(handle); fcefwindows[fhandlebk] := self(true); initbrowser(); end end function DestroyHandle();override; begin inherited; reindex(fcefwindows,array(fhandlebk:nil)); fbrower := nil; end function Recycling();override; begin inherited; end function reload(ic); //重新加载,ic 是否忽略缓存 begin if fbrower then begin if ic then fbrower.reload_ignore_cache(); else fbrower.reload(); end end function showdevtools(); //打开调试窗口 begin if fbrower then begin host := fbrower.get_host(); if host then begin host.show_dev_tools(); end end end function closedevtools(); //关闭调试窗口 begin if fbrower then begin host := fbrower.get_host(); if host then begin host.close_dev_tools(); end end end published property client read fclient; property appsetting read getappsetting; property url:string read furl write seturl; {** @param(url)(string)网址 %% **} private function seturl(u); //设置url begin if furl<>u then begin furl := u; if HandleAllocated() then begin if fbrower {and (fm := fbrower.get_main_frame())} then begin add_lazy_load(); end else begin initbrowser(); end end end end function initbrowser(); //初始加载url begin if csDesigning in ComponentState then return ; if furl and ifstring(furl) then begin initcef(); r := ClientRect; fwinfo.parent_window := handle; fwinfo.window_name := Caption; fwinfo.bounds.x := r[0]; fwinfo.bounds.y := r[1]; fwinfo.bounds.width := r[2]; fwinfo.bounds.height := r[3]; fbrower := cef_browser_host_create_browser_sync_tsl(fwinfo, fclient,"", fbrssetting, 0, 0); add_lazy_load(); end end function lazy_load(); begin if not fneedload then return ; if fbrower then begin fm := fbrower.get_main_frame(); if fm then fm.load_url(furl); fneedload := false; end end function add_lazy_load(); begin fneedload := true; ftimer.timeout(thisfunction(lazy_load()),60); end private [weakref]fbrower; [weakref]fclient; furl; fwinfo; fbrssetting; fhandlebk; ftimer; fneedload; class function tslpath(); //tsl.exe 目录 begin p := pluginpath(); iof := iofileseparator(); for i:= length(p)-1 downto 1 do begin if p[i]=iof then return p[1:i]; end return p; end function getappsetting(); begin return fappsetting; end end implementation initialization end.