我现在在几个地方看到了下面的 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/