如何避免使用TWebBrowser刷新 [英] How can I avoid refresh with TWebBrowser

查看:141
本文介绍了如何避免使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆