如何避免使用TWebBrowser刷新 [英] How can I avoid refresh with TWebBrowser
问题描述
我有一个显示Google地图页面的TWebBrowser组件。问题是当用户按F5刷新页面并重新加载页面时。这导致javascript变量重新初始化并与Delphi失去同步,并出现一个脚本错误对话框,
'undefined'为null或不是一个对象。
我想停止刷新用户。
我为OnBeforeNavigate2尝试了这个活动:
程序TNewOrganizationForm.mapAddressBeforeNavigate2(ASender:TObject;
const pDisp:IDispatch; var URL,Flags,TargetFrameName,PostData,
标题:OleVariant; var Cancel:WordBool );
开始
继承;
取消:=分配(fMapEngine),而不是fMapEngine.Loading;
结束
但是当我设置一个断点,甚至没有被调用。还有另一种方式?
Ronald你可以使用 IHTMLDocument2.onkeydown 事件拦截和阻止密钥。
首先分配事件处理程序,您必须使用 IHTMLEventObj
作为参数。
THTMLProcEvent =对象的过程(发件人:TObject;事件:IHTMLEventObj);
那么您必须从 InterfacedObject
和 IDispatch
来传递和处理事件。
最后你可以处理onkeydown事件中截获的密钥这种方式
Var
HTMLDocument2:IHTMLDocument2;
begin
如果未分配(WebBrowser1.Document)然后退出;
HTMLDocument2:=(WebBrowser1.Document AS IHTMLDocument2);
如果HTMLDocument2.parentWindow.event.keyCode = VK_F5然后//比较键
begin
HTMLDocument2.parentWindow.event.cancelBubble:= True; //取消键
HTMLDocument2.parentWindow.event.keyCode:= 0;
结束
结束
//检查完整的源代码
<$单位Unit55; p $ p>
接口
使用
Windows,消息,SysUtils,变体,类,图形,控件,表单,
对话框,OleCtrls,SHDocVw,MSHTML;
类型
//创建过程类型以分配事件
THTMLProcEvent =过程(Sender:TObject;事件:IHTMLEventObj)的对象;
//创建一个新的类用于从twebbrowser
管理事件THTMLEventLink = class(TInterfacedObject,IDispatch)
private
FOnEvent:THTMLProcEvent;
private
构造函数Create(Handler:THTMLProcEvent);
函数GetTypeInfoCount(out Count:Integer):HResult;标准
函数GetTypeInfo(Index,LocaleID:Integer; out TypeInfo):HResult;标准
函数GetIDsOfNames(const IID:TGUID; Names:Pointer;
NameCount,LocaleID:Integer; DispIDs:Pointer):HResult;标准
函数Invoke(DispID:Integer; const IID:TGUID; LocaleID:Integer;
标志:Word; var Params; VarResult,ExcepInfo,ArgErr:Pointer):HResult;标准
public
属性OnEvent:THTMLProcEvent读取FOnEvent写入FOnEvent;
结束
TForm55 = class(TForm)
WebBrowser1:TWebBrowser;
procedure FormShow(Sender:TObject);
procedure WebBrowser1NavigateComplete2(ASender:TObject; const pDisp:IDispatch; var URL:OleVariant);
procedure FormCreate(Sender:TObject);
private
{私有声明}
FOnKeyDownConnector:THTMLEventLink; //指向事件处理程序的指针
procedure WebBrowser1OnKeyDown(Sender:TObject; EventObjIfc:IHTMLEventObj); //事件处理程序
public
{公共声明}
end;
var
Form55:TForm55;
实现
{$ R * .dfm}
构造函数THTMLEventLink.Create(Handler:THTMLProcEvent);
开始
继承创建;
_AddRef;
FOnEvent:= Handler;
结束
函数THTMLEventLink.GetIDsOfNames(const IID:TGUID; Names:Pointer; NameCount,LocaleID:Integer; DispIDs:Pointer):HResult;
begin
结果:= E_NOTIMPL;
结束
函数THTMLEventLink.GetTypeInfo(Index,LocaleID:Integer; out TypeInfo):HResult;
begin
结果:= E_NOTIMPL;
结束
函数THTMLEventLink.GetTypeInfoCount(out Count:Integer):HResult;
begin
结果:= E_NOTIMPL;
结束
函数THTMLEventLink.Invoke(DispID:Integer; const IID:TGUID; LocaleID:Integer; Flags:Word; var Params; VarResult,ExcepInfo,ArgErr:Pointer):HResult;
var
HTMLEventObjIfc:IHTMLEventObj;
begin
结果:= S_OK;
如果分配(FOnEvent)然后FOnEvent(Self,HTMLEventObjIfc);
结束
程序TForm55.FormCreate(发件人:TObject);
begin
FOnKeyDownConnector:= THTMLEventLink.Create(WebBrowser1OnKeyDown); //分配事件处理程序的地址
end;
程序TForm55.WebBrowser1NavigateComplete2(ASender:TObject; const pDisp:IDispatch; var URL:OleVariant);
var
HTMLDocument2:IHTMLDocument2;
begin
HTMLDocument2:=(WebBrowser1.Document AS IHTMLDocument2);
HTMLDocument2.onkeydown:= FOnKeyDownConnector as IDispatch; //分配事件处理程序
end;
procedure TForm55.WebBrowser1OnKeyDown(Sender:TObject; EventObjIfc:IHTMLEventObj);
Var
HTMLDocument2:IHTMLDocument2;
begin
//最后在这里做你的东西,在这种情况下我们将拦截并阻止F5键。
如果未分配(WebBrowser1.Document)然后退出;
HTMLDocument2:=(WebBrowser1.Document AS IHTMLDocument2);
如果HTMLDocument2.parentWindow.event.keyCode = VK_F5然后
begin
HTMLDocument2.parentWindow.event.cancelBubble:= True;
HTMLDocument2.parentWindow.event.keyCode:= 0;
结束
结束
程序TForm55.FormShow(发件人:TObject);
begin
WebBrowser1.Navigate('www.google.com');
结束
结束。
I have a TWebBrowser component that show a Google maps page. The problem is that when user press F5 the page refresh and page reloads. This cause javascript variables to reinitialize and get out of sync with Delphi and a scripting error dialog appear, 'undefined' is null or not an object.
I want to stop refresh from the user.
I tried this event for OnBeforeNavigate2:
procedure TNewOrganizationForm.mapAddressBeforeNavigate2(ASender: TObject;
const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
Headers: OleVariant; var Cancel: WordBool);
begin
inherited;
Cancel := Assigned(fMapEngine) and not fMapEngine.Loading;
end;
But when I set a breakpoint it is not even called. Is there another way ?
Ronald you can use the IHTMLDocument2.onkeydown event to intercept and block a key.
to assign an event handler first you must create a procedure type using the IHTMLEventObj
as parameter.
THTMLProcEvent = procedure(Sender: TObject; Event: IHTMLEventObj) of object;
then you must create an class descendent from InterfacedObject
and IDispatch
to pass and process the events .
finally you can process the intercepted key in the onkeydown event in this way
Var
HTMLDocument2 : IHTMLDocument2;
begin
if Not Assigned(WebBrowser1.Document) then Exit;
HTMLDocument2:=(WebBrowser1.Document AS IHTMLDocument2);
if HTMLDocument2.parentWindow.event.keyCode=VK_F5 then //compare the key
begin
HTMLDocument2.parentWindow.event.cancelBubble:=True; //cancel the key
HTMLDocument2.parentWindow.event.keyCode :=0;
end;
end;
//check the full source code
unit Unit55;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OleCtrls, SHDocVw, MSHTML;
type
//Create the procedure type to assign the event
THTMLProcEvent = procedure(Sender: TObject; Event: IHTMLEventObj) of object;
//Create a new class for manage the event from the twebbrowser
THTMLEventLink = class(TInterfacedObject, IDispatch)
private
FOnEvent: THTMLProcEvent;
private
constructor Create(Handler: THTMLProcEvent);
function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
function GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
public
property OnEvent: THTMLProcEvent read FOnEvent write FOnEvent;
end;
TForm55 = class(TForm)
WebBrowser1: TWebBrowser;
procedure FormShow(Sender: TObject);
procedure WebBrowser1NavigateComplete2(ASender: TObject; const pDisp: IDispatch; var URL: OleVariant);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
FOnKeyDownConnector: THTMLEventLink; //pointer to the event handler
procedure WebBrowser1OnKeyDown(Sender: TObject; EventObjIfc: IHTMLEventObj);//the event handler
public
{ Public declarations }
end;
var
Form55: TForm55;
implementation
{$R *.dfm}
constructor THTMLEventLink.Create(Handler: THTMLProcEvent);
begin
inherited Create;
_AddRef;
FOnEvent := Handler;
end;
function THTMLEventLink.GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): HResult;
begin
Result := E_NOTIMPL;
end;
function THTMLEventLink.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult;
begin
Result := E_NOTIMPL;
end;
function THTMLEventLink.GetTypeInfoCount(out Count: Integer): HResult;
begin
Result := E_NOTIMPL;
end;
function THTMLEventLink.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;
var
HTMLEventObjIfc: IHTMLEventObj;
begin
Result := S_OK;
if Assigned(FOnEvent) then FOnEvent(Self, HTMLEventObjIfc);
end;
procedure TForm55.FormCreate(Sender: TObject);
begin
FOnKeyDownConnector := THTMLEventLink.Create(WebBrowser1OnKeyDown); //assign the address of the event handler
end;
procedure TForm55.WebBrowser1NavigateComplete2(ASender: TObject; const pDisp: IDispatch; var URL: OleVariant);
var
HTMLDocument2 : IHTMLDocument2;
begin
HTMLDocument2:=(WebBrowser1.Document AS IHTMLDocument2);
HTMLDocument2.onkeydown := FOnKeyDownConnector as IDispatch; //assign the event handler
end;
procedure TForm55.WebBrowser1OnKeyDown(Sender: TObject; EventObjIfc: IHTMLEventObj);
Var
HTMLDocument2 : IHTMLDocument2;
begin
//finally do your stuff here, in this case we will intercept and block the F5 key.
if Not Assigned(WebBrowser1.Document) then Exit;
HTMLDocument2:=(WebBrowser1.Document AS IHTMLDocument2);
if HTMLDocument2.parentWindow.event.keyCode=VK_F5 then
begin
HTMLDocument2.parentWindow.event.cancelBubble:=True;
HTMLDocument2.parentWindow.event.keyCode :=0;
end;
end;
procedure TForm55.FormShow(Sender: TObject);
begin
WebBrowser1.Navigate('www.google.com');
end;
end.
这篇关于如何避免使用TWebBrowser刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!