tslediter/funcext/tvclib/utslvclcef.tsf

429 lines
13 KiB
Plaintext

unit utslvclcef;
//20230410
{**
@explan(说明)封装cef到vcl控件,提供cef窗口的宿主控件,加入了,cookie,download,等功能 %%
**}
interface
uses utslvclcefinterface,tslvcl;
type tcefowner = class(tcustomcontrol)
protected
static fargs; //命令行参数
static fcefapp; //app
static fappsetting; //app设置
static finitcef; //初始化标记
static finitcefobj;//初始化标记
static fcefloop; //消息循环
static fcookiemgr;
static fcookiewills;
static fcefwindows;
class function initcef(); //初始化cef
begin
if not finitcef then
begin
fcefwindows := array();
finitcef := true;
sinit();
fcefloop := new tcefproc();
app := initializeapplication();
app.addExitMessageLoopdo(thisfunction(cef_shutdown));
cef_initialize(fargs._getptr_(), fappsetting._getptr_(), fcefapp._getptr_(),0);
fcookiemgr := new cef_cookie_manager_global_t();
if fcookiewills then
begin
for i,v in fcookiewills do
begin
if ifnil(v[1]) then
begin
fcookiemgr.delete_cookies(v[2],v[0],fcookiemgr.callback);
end else
begin
c := new cef_cookie_t();
c.name := v[0];
c.value := v[1];
fcookiemgr.set_cookie(v[2],c,fcookiemgr.callback);
end
end
fcookiewills := array();
end
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+"ceflogfile-"+datetostr(date())+".log";
//fappsetting.browser_subprocess_path := %% F:\cef_105.3.39\AnalyseNG.NET\cefclient.exe%%;
fappsetting.browser_subprocess_path := tslpath()+"tsl_cef_main.exe";
fappsetting.cache_path := tp+"-cefcatche-";// %% F:\cef_105.3.39\tslcache%%;
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();
{frm := new cef_life_span_handler_t();
frm.on_after_created := function(o,b)begin
echo "\r\n craeteted:",b.get_main_frame().get_url(),"<<";
end
frm.on_before_close := function(o,b)begin
echo "\r\n====doclose:",b.get_main_frame().get_url();
end
fclient.on_process_message_received := function()begin
echo "\r\n>>>>:messagesabed:",params[4];
//return 1;
end
fclient.life_span_handler := frm; }
d := new cef_download_handler_t();
fdownloader := d;
d.can_download := function(o,b,u,m)begin
return docandownload(o,b,u,m);
//return true;
end
d.on_before_download := function(o,b,it,s,c)begin
c.cont(s,1);
end
d.on_download_updated := function(o,b,it,c) begin
return dodownloadupdate(o,b,it,c);
end
{fOndownloadupdate := function(o,e)begin
echo "\r\n",e.get_id(),e.is_complete(),"=====",e.is_in_progress(),"===",e.is_complete(),"===",e.get_percent_complete(),"====",e.get_suggested_file_name();
end
foncandownload := function(o,e)begin
echo "\r\n",e.method,"==>>=",e.url;
//e.skip := true;
end}
muh := new cef_context_menu_handler_t();
muh.on_before_context_menu := function(o,b,f,pms,d)begin
ppm := PopupMenu;
if d then d.remove(132);
if ppm then
begin
fpopupmenushine := array();
createusrmenu(ppm,d,27500);
end
end
muh.on_context_menu_dismissed := function(o,b,f)begin
fpopupmenushine := array();
end
muh.on_context_menu_command := function(o,b,f,pms,id,flg)begin
oi := fpopupmenushine[id];
if oi then
begin
e := new tuieventbase(0,0,0,0);
CallMessgeFunction(oi.onclick,oi,e);
return 1;
end
end
fclient.context_menu_handler := muh;
fclient.download_handler := d;
fbrssetting := new cef_browser_settings_t();
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
////////////////cookie///////////////////
function setcookie(n,v,ur);//设置cookie值
begin
if not( n and ifstring(n)) then return 0;
if not( v and ifstring(v)) then return 0;
if not(ur and ifstring(ur)) then
begin
cur := furl;
end else
begin
cur := ur;
end
cookie := new cef_cookie_t();
cookie.name := n;
cookie.value := v;
if fcookiemgr then
begin
return fcookiemgr.set_cookie(cur,cookie,fcookiemgr.callback);
end else
begin
if not(ifarray( fcookiewills)) then fcookiewills := array();
fcookiewills[length(fcookiewills)] := array(n,v,cur);
end
end
function delcookie(n,ur); //根据名字删除cookie
begin
if not( n and ifstring(n)) then return 0;
if not(ur and ifstring(ur)) then
begin
cur := furl;
end else
begin
cur := ur;
end
if fcookiemgr then
begin
fcookiemgr.delete_cookies(cur,n,fcookiemgr.callback);
end else
begin
if not(ifarray( fcookiewills)) then fcookiewills := array();
fcookiewills[length(fcookiewills)] := array(n,nil,cur);
end
end
published
property url:string read furl write seturl;
property oncandownload:eventhandler read FOncandownload write FOncandownload;
property Ondownloadupdate:eventhandler read FOndownloadupdate write fOndownloadupdate;
private
function seturl(url); //设置url
begin
if furl<>url then
begin
furl := url;
if HandleAllocated() then
begin
if fbrower and (fm := fbrower.get_main_frame()) then
begin
fm.load_url(url);
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,furl, fbrssetting, 0, 0);
end
end
function createusrmenu(mu,d,idx); //构造菜单映射
begin
if not mu then return ;//
for i,v in mu.items do
begin
idx++;
fpopupmenushine[idx] := v;
smu := v.ItemCount;
if smu>0 then //存在子节点
begin
nd := d.add_sub_menu(idx,v.Caption);
if not(v.Enabled) then //处理是否有效
begin
d.set_enabled(idx,false);
end else
createusrmenu(v,nd,idx); //处理子菜单
end else //单个菜单
begin
if v.TSeparator then //分割类型
begin
d.add_separator();
end else //添加菜单
begin
d.add_item(idx,v.Caption);
if not(v.Enabled) then d.set_enabled(idx,false); //设置是否enabled
end
end
end
end
function docandownload(o,b,u,m);//是否可以下载处理
begin
if FOncandownload then
begin
e := new tcandownevent(0,0,0,0);
e.url := u;
e.method := m;
CallMessgeFunction(FOncandownload,self(true),e);
return not(e.skip);
end else
begin
return 1;
end
end
function dodownloadupdate(o,b,it,c);//下载过程处理
begin
if FOndownloadupdate and it and c then
begin
e := new tdownupdateevent(0,0,0,0);
e.FDownitem := it;
e.fcallback := c;
CallMessgeFunction(FOndownloadupdate,self(true),e);
end
end
private
[weakref]fbrower;
[weakref]FOncandownload;
[weakref]FOndownloadupdate;
[weakref]fdownloader;
[weakref]fpopupmenushine;
[weakref]fclient;
furl;
fwinfo;
fbrssetting;
fhandlebk;
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
end
type tcandownevent = class(tuieventbase) //是否可以下载
function create(m,w,l,h);override;
begin
inherited;
end
url; //url
method; //post or get
end
type tdownupdateevent=class(tuieventbase)
function create(m,w,l,h);override;
begin
inherited;
end
//call--back;
function cancel();
begin
fcallback.cancel();
end
function pause();
begin
fcallback.pause();
end
function resume();
begin
fcallback.resume();
end
//down ----
function is_complete();//是否完成
begin
return FDownitem.is_complete();
end
function is_in_progress();//正在进行
begin
return FDownitem.is_in_progress();
end
function get_current_speed();//当前速度
begin
return FDownitem.get_current_speed();
end
function get_percent_complete();//完成进度
begin
return FDownitem.get_percent_complete();
end
function get_full_path();//路径
begin
return FDownitem.get_full_path();
end
function get_original_url();//原始路径
begin
return FDownitem.get_original_url();
end
function get_suggested_file_name();//建议文件名
begin
return FDownitem.get_suggested_file_name();
end
function get_total_bytes(); //大小
begin
return FDownitem.get_total_bytes();
end
function get_id(); //序号
begin
return FDownitem.get_id();
end
FDownitem;
fcallback;
end
implementation
initialization
end.