问题描述
我有一个包含一些组件的表单,包括一个显示一些网页的 TWebbrowser,我希望能够使用 Tab 键在它们之间移动。
我已经能够在 Web 浏览器中 capture key presses,因此当 Web 浏览器获得焦点并按下 Tab 键时,它会被捕获,并且焦点会跳转到表单中的下一个控件。
这是我的样品单元。这是一个包含三个按钮的简单表单:
unit WebbrowserOnEnter;
interface
uses
Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,OleCtrls,SHDocVw,StdCtrls,MSHTML_TLB;
type
// https://stackoverflow.com/questions/3446440/how-can-i-avoid-refresh-with-twebbrowser/3447422#3447422
//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;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Webbrowser1: TWebbrowser;
Button3: TButton;
procedure FormCreate(Sender: TObject);
procedure Webbrowser1NavigateComplete2(Sender: TObject;
const pdisp: Idispatch; var URL: OleVariant);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Webbrowser1Enter(Sender: TObject);
procedure Webbrowser1Exit(Sender: TObject);
private
FOnKeyDownConnector: THTMLEventLink; //pointer to the event handler
procedure browserIHTMLDocument2OnKeyDown(Sender: TObject; Event: IHTMLEventObj);
public
{ Public declarations }
end;
var
Form1: TForm1;
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,ArgErr: Pointer): HResult;
var
HTMLEventObjIfc: IHTMLEventObj;
begin
Result := S_OK;
if Assigned(FOnEvent) then FOnEvent(Self,HTMLEventObjIfc);
end;
procedure TForm1.browserIHTMLDocument2OnKeyDown(Sender: TObject;
Event: IHTMLEventObj);
var
HTMLDocument2 : IHTMLDocument2;
begin
if Not Assigned(Webbrowser1.Document) then Exit;
HTMLDocument2:=(Webbrowser1.Document AS IHTMLDocument2);
// VK_F5,VK_TAB
if HTMLDocument2.parentwindow.event.keyCode = VK_TAB then
begin
HTMLDocument2.parentwindow.event.cancelBubble:=True; //cancel the key
HTMLDocument2.parentwindow.event.keyCode :=0;
SendMessage(Form1.Handle,WM_NEXTDLGCTL,0);
//SendMessage(GetParentForm(Webbrowser1).Handle,0);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FOnKeyDownConnector := THTMLEventLink.Create(browserIHTMLDocument2OnKeyDown); //assign the address of the event handler
Webbrowser1.Navigate('https://en.wikipedia.org');
end;
procedure TForm1.Webbrowser1NavigateComplete2(Sender: TObject;
const pdisp: Idispatch; var URL: OleVariant);
var
HTMLDocument2 : IHTMLDocument2;
begin
HTMLDocument2:=(Webbrowser1.Document AS IHTMLDocument2);
if (HTMLDocument2 <> nil) and (FOnKeyDownConnector <> nil) then
HTMLDocument2.onkeydown := FOnKeyDownConnector as Idispatch; //assign the event handler
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Button1Click');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage('Button2Click');
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
ShowMessage('Button3Click');
end;
procedure TForm1.Webbrowser1Enter(Sender: TObject);
begin
ShowMessage('Webbrowser1Enter');
end;
procedure TForm1.Webbrowser1Exit(Sender: TObject);
begin
ShowMessage('Webbrowser1Exit');
end;
end.
它使用 MSHTML_TLB unit generated using the Delphi IDE。
我想在进入或退出浏览器时做一些事情。我可以使用 OnEnter 和 OnExit 方法来做到这一点,而且效果很好。我的问题是当我点击 TWebbrowser 时,我没有保持标签流。如果我单击浏览器并然后按 Tab 键,则会触发 OnEnter 方法。
如何模拟 OnEnter 行为,以便单击浏览器,然后在按下 Tab 键时跳转到 Button3?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)