简体   繁体   English

如何避免使用TWebBrowser刷新

[英]How can I avoid refresh with TWebBrowser

I have a TWebBrowser component that show a Google maps page. 我有一个TWebBrowser组件,用于显示Google地图页面。 The problem is that when user press F5 the page refresh and page reloads. 问题是,当用户按F5键时,页面将刷新并重新加载页面。 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. 这将导致JavaScript变量重新初始化并与Delphi不同步,并出现脚本错误对话框, “未定义”为null或不是对象。

I want to stop refresh from the user. 我想停止从用户刷新。

I tried this event for OnBeforeNavigate2: 我为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. Ronald可以使用IHTMLDocument2.onkeydown事件来拦截和阻止键。

to assign an event handler first you must create a procedure type using the IHTMLEventObj as parameter. 要首先分配事件处理程序,您必须使用IHTMLEventObj作为参数来创建过程类型。

  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 . 然后必须从InterfacedObjectIDispatch创建一个派生类以传递和处理事件。

finally you can process the intercepted key in the onkeydown event in this way 最后,您可以通过这种方式在onkeydown事件中处理截获的密钥

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.

I did not find an easy way to do this. 我没有找到简单的方法来做到这一点。 I could not find any event or anything similar on TWebBrowser, that would dissable refresh. 我在TWebBrowser上找不到任何事件或任何类似事件,会禁用刷新。 Maybe you should check TEmbededWB as it has more events and is more capable than the default TWebBrowser. 也许您应该检查TEmbededWB,因为它比默认的TWebBrowser具有更多的事件和更强大的功能。 Otherwise they are very similar. 否则它们非常相似。

But I found a way to prevent refresh. 但是我找到了一种防止刷新的方法。 Now it is funny that even with KeyPreview set to "True" on the main form I could not recieve key notifications. 现在,很有趣的是,即使在主窗体上将KeyPreview设置为“ True”,我也无法收到关键通知。 It seems that TWebBrowser eats them up somehow. 似乎TWebBrowser以某种方式吞噬了它们。 But this worked: 但这有效:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := OnAppMessage;
end;

procedure TForm1.OnAppMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if Msg.message = WM_KEYDOWN then
    if Msg.wParam = VK_F5 then
      Handled := True;
end;

Not the most elegant way but at least it works. 这不是最优雅的方法,但至少可以奏效。 I have not found a better solution yet. 我还没有找到更好的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在“TWebbrowser”上禁用javascript错误? - How can I disable javascript errors on “TWebbrowser”? 如何从 TWebBrowser 获取 HTML 源代码 - How can I get HTML source code from TWebBrowser Delphi - 如何将 select 从 twebbrowser 获取到数组中? - Delphi - How can I get a select from a twebbrowser into an array? 如何将HTML字符串加载到Firemonkey TWebBrowser中? - How can I load an HTML string into a Firemonkey TWebBrowser? 如何找到用于TWebBrowser异步可插入协议的ComServer - How can I find the ComServer for a TWebBrowser Asynchronous Pluggable Protocol 我如何在 TWebBrowser 中以 HTML 格式显示 RSS 提要的 output? - How i can display the output of a rss feed in HTML format in a TWebBrowser? 如何在没有TWebBrowser的情况下在我的Delphi程序中执行Javascript? - How can I execute Javascript in my Delphi program without TWebBrowser? 如何阻止 TWebBrowser 闪烁? - How do I stop TWebBrowser from flickering? 更新的TWebBrowser现在从一开始就实现了IDocUIHandler,如何继续使用我的自定义实现? - Updated TWebBrowser now implements IDocUIHandler from the start, how can I keep using my custom implementation? 如何在Delphi7中使用TWebbrowser将URL中的PDF保存为PDF文件? - How can I save a PDF from an URL with TWebbrowser in Delphi7 to a PDF FILE?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM