delphi – 如何从TWebBrowser控件中与TAutoIntfObject对象互操作
我有一个TWebBrowser控件,它实现了IDocHostUIHandler,以通过IDispatch容器扩展
JavaScript互操作的控制.这工作正常,除了我不知道,如何将事件从JavaScript调度回Web浏览器控件.
扩展对象是一个基于TAutoIntfObject的容器,如 type TZoomChangeEvent = procedure(Sender: TObject; ZoomLevel: Integer) of object; TOpenLayersExt = class(TAutoIntfObject,IOpenLayers) private FOnZoomChange: TZoomChangeEvent; // the ZoomChange method is invoked from JavaScript procedure ZoomChange(ZoomLevel: Integer); safecall; public property OnZoomChange: TZoomChangeEvent read FOnZoomChange write FOnZoomChange; end; implementation procedure TOpenLayersExt.ZoomChange(ZoomLevel: Integer); begin if Assigned(FOnZoomChange) then FOnZoomChange(Self,ZoomLevel); end; 这样的TWebBrowser控件: type TMapBrowser = class(TWebBrowser,IDocHostUIHandler) private // the extension object FExtObj: TOpenLayersExt; // IDocHostUIHandler::GetExternal method function GetExternal(out ppDispatch: IDispatch): HRESULT; stdcall; // this is the TOpenLayersExt.OnZoomChange event method implementation procedure OnZoomChange(Sender: TObject; Zoom: Integer); public // ordinary constructor constructor Create(AOwner: TComponent); override; end; implementation constructor TMapBrowser.Create(AOwner: TComponent); begin inherited Create(AOwner); // create extension object FExtObj := TOpenLayersExt.Create; // here the event method is properly binded; if I'd change the FExtObj type // to IDispatch with TOpenLayersExt(FExtObj) typecast,it wouldn't FExtObj.OnZoomChange := OnZoomChange; end; function TMapBrowser.GetExternal(out ppDispatch: IDispatch): HRESULT; begin // the problem is that I don't know how to properly pass this object to the // ppDispatch parameter; if this GetExternal method is called second time,// the FExtObj seems to be released,but I don't get why ppDispatch := FExtObj as IDispatch; Result := S_OK; end; 问题是,如果我将FExtObj对象声明为TOpenLayersExt,则事件方法被绑定,但是在第一个扩展对象方法调用(来自JavaScript)之后,似乎释放了FExtObj对象引用. 如果我将其声明为IDispatch,则在调用JavaScript函数后不会释放引用,但OnZoomChange事件未绑定. 很难在这里发布完整的代码,因为它是由Delphi 7制作的更多部分组成的. 所以我的问题是,如何在Web浏览器控件中使用来自TAutoIntfObject扩展对象的事件;如何声明扩展对象,所以我将能够处理来自Web浏览器控件的事件并将其传递给仍然保持接口对象引用的IDocHostUIHandler :: GetExternal方法参数? 解决方法
使用引用计数,即.保持FExtObj作为对接口的引用,而不是对象:
private // the extension object FExtObj: IDispatch; … constructor TMapBrowser.Create(AOwner: TComponent); var AExtObj: TOpenLayersExt; begin inherited Create(AOwner); // create extension object AExtObj := TOpenLayersExt.Create; AExtObj.OnZoomChange := OnZoomChange; FExtObj := AExtObj as IDispatch; end; destructor TMapBrowser.Destroy; begin FExtObj := nil; inherited Destroy; end; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |