delphi - 不能在多个 twebbrowser 中按 Enter

标签 delphi twebbrowser

我现在在几个地方看到了下面的 msghandler 代码,作为无法在 twebbrowser 中按 Enter 的解决方案。只要您只处理一个 twebbrowser,此解决方案就可以工作。我在这里提供了一个完整的单元供讨论。如果您使用两个 twebbrowsers 并将其中一个设置为“事件”浏览器(参见代码)并将它们分别导航到具有用户名、密码和按钮的站点,您可以在“事件”浏览器中输入数据并按 Enter成功地。如果您尝试使用非“事件”浏览器,您不仅不能按 Enter,而且使用选项卡也会失败。无论您首先在哪个浏览器中按 Enter 都会继续工作,因此它似乎与浏览器的创建顺序无关。

如何使我的其他浏览器正常工作?

unit Main_Form;

interface

uses
    Winapi.Windows, Winapi.Messages, Vcl.Controls, Vcl.Forms,
    ActiveX, Vcl.OleCtrls, SHDocVw, System.Classes, Vcl.StdCtrls;

type
    TForm1 = class(TForm)
        NavigateBrowsers: TButton;
        WebBrowser1: TWebBrowser;
        WebBrowser2: TWebBrowser;
        MakeBrowser1Active: TButton;
        MakeBrowser2Active: TButton;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure FormDeactivate(Sender: TObject);
        procedure NavigateBrowsersClick(Sender: TObject);
        procedure MakeBrowser1ActiveClick(Sender: TObject);
        procedure MakeBrowser2ActiveClick(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
         procedure MsgHandler(var Msg: TMsg; var Handled: Boolean);
      end;

var
  Form1: TForm1;
  ActiveBrowser: TWebBrowser;
  FOleInPlaceActiveObject: IOleInPlaceActiveObject;
  SaveMessageHandler: TMessageEvent;

implementation

{$R *.dfm}

procedure TForm1.MakeBrowser1ActiveClick(Sender: TObject);
begin
  ActiveBrowser := WebBrowser1;
end;

procedure TForm1.MakeBrowser2ActiveClick(Sender: TObject);
begin
  ActiveBrowser := WebBrowser2;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Application.OnMessage := SaveMessageHandler;
  FOleInPlaceActiveObject := nil;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //Handle messages
  SaveMessageHandler := Application.OnMessage;
  Application.OnMessage := MsgHandler;
end;

procedure TForm1.FormDeactivate(Sender: TObject);
begin
  Application.OnMessage := SaveMessageHandler;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FOleInPlaceActiveObject := nil;
end;

procedure TForm1.NavigateBrowsersClick(Sender: TObject);
begin
  WebBrowser1.Navigate(''); //supply own
  WebBrowser2.Navigate(''); //supply own
end;

procedure TForm1.MsgHandler(var Msg: TMsg; var Handled: Boolean);
const
  StdKeys = [VK_BACK, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT];
var
  IOIPAO: IOleInPlaceActiveObject;
  Dispatch: IDispatch;
begin
  //Exit if webbrowser object is nil
  if ActiveBrowser = nil then
    begin
      Handled := False;
      Exit;
    end;
  Handled:=(IsDialogMessage(ActiveBrowser.Handle, Msg) = True);
  if (Handled) and (not ActiveBrowser.Busy) then
    begin
      if FOleInPlaceActiveObject = nil then
        begin
          Dispatch := ActiveBrowser.Application;
          if Dispatch <>nil then
            begin
              Dispatch.QueryInterface(IOleInPlaceActiveObject, iOIPAO);
              if iOIPAO <>nil then
                FOleInPlaceActiveObject := iOIPAO;
            end;
        end;
        if FOleInPlaceActiveObject <>nil then
          if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and
            (Msg.wParam in StdKeys) then
              //nothing - do not pass on StdKeys
          else
            FOleInPlaceActiveObject.TranslateAccelerator(Msg);
    end;
end;

initialization
OleInitialize(nil);

finalization
OleUninitialize;

end.

最佳答案

我遇到了和你一样的问题,我使用了一个类似的消息处理程序,FOleInPlaceActiveObject不是真的需要:

procedure TForm1.MsgHandler(var Msg: TMsg; var Handled: Boolean);
const
  StdKeys = [VK_BACK, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT];
var
  IOIPAO: IOleInPlaceActiveObject;

begin
 try  
  if Assigned(ActiveBrowser) then
  begin
   Handled:=(IsDialogMessage(ActiveBrowser.Handle, Msg) = True);
   if Handled then
    begin
     if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and (Msg.wParam in StdKeys) then
      begin
       //nothing  -  do not pass on Backspace, Left, Right, Up, Down arrows
      end
     else
      begin
       IOIPAO := (ActiveBrowser.Application as IOleInPlaceActiveObject);
       if Assigned(IOIPAO)then
        IOIPAO.TranslateAccelerator(Msg)
      end;               
    end;
  end;
 except
  Handled := False;
 end;    
end;

关于delphi - 不能在多个 twebbrowser 中按 Enter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20964334/

相关文章:

windows - TWebbrowser 中的点击声音

delphi - case..of 与函数

Delphi:TOleControl 将 ActiveControl 置于错误状态?

delphi - Delphi无法检索进程内存使用情况

delphi获取文件夹路径

android - 如何在TWebBrowser中聚焦输入时显示Android的虚拟键盘?

delphi 按回车键

html - 使用 Delphi 中的 TWebbrowser 组件向网站发送数据和从网站接收数据

delphi - KaZip for C++Builder2009/Delphi

mysql - 可以 select ... into outfile 而不是将其保存到文件中,而是将其保存在 blob 中