如何获取TWebBrowser错误信息

时间:2016-09-21 09:14:02

标签: delphi interface delphi-xe ole twebbrowser

我正在基于this回答实现TWebBrowser的Exec方法。每当发生脚本错误时都会触发此方法。现在我需要获取错误信息。

我首先掌握了TWebBrowser的事件对象。

var
 Doc: IHTMLDocument2;
 HTMLWindow: IHTMLWindow2;
 Event: IHTMLEventObj;
 MethodName: String;
 MethodResult: OleVariant;
 DispatchId: Integer;
 Param: array of OleVariant;

begin

//Avoid non-error calls
if nCmdID != OLECMDID_SHOWSCRIPTERROR then 
   Exit;

//Get hold of the event object
Doc := MapForm.WebBrowser.Document as IHTMLDocument2;
if not Assigned(Doc) then
  Exit;


HTMLWindow := Doc.parentWindow;
if not Assigned(HTMLWindow) then
  Exit;


//Get the current event
Event := HTMLWindow.event;

然后我尝试使用接口的GetIDsOfNamesInvoke函数获取我需要的信息(如this链接中所示)。使用这些方法的工作Delphi代码位于this文档链接中。

以下是我在Event对象上使用这些函数的方法。

MethodName := 'errorMessage';
Result := Event.GetIDsOfNames(GUID_NULL, @MethodName, 1,     SysLocale.DefaultLCID, @DispatchId);

Result := Event.Invoke(DispatchId, GUID_NULL, SysLocale.DefaultLCID, DISPATCH_METHOD, Param, @MethodResult, nil, nil);

GetIDsOfNames fuGetIDsOfNames函数正确执行,输出一个可接受的整数DispatchId并返回S_OK

Invoke函数失败了。它返回一些负整数HRESULT,并且不向MethodResult输出任何内容。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

您尝试访问的错误值不是对象方法,而是属性,因此Invoke()因使用DISPATCH_METHOD而失败。请改用DISPATCH_PROPERTYGET

但是,OleVariant(和Variant)内置了对IDispatch.Invoke()的支持,因此您根本不需要手动处理它。您可以正常调用对象方法和读/写对象属性,编译器将为您生成必要的IDispatch调用。

尝试更像这样的事情:

function TWebBrowser.Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD; 
  const vaIn: OleVariant; var vaOut: OleVariant): HRESULT; stdcall;
var
  Event: OleVariant;
  ErrorLine: Integer;
  ErrorChar: Char;
  ErrorCode: Integer;
  ErrorMsg: String;
  ErrorUrl: String;
begin
  if (CmdGroup = nil) or not IsEqualGUID(CmdGroup^, CGID_DocHostCommandHandler) then
  begin
    Result := OLECMDERR_E_UNKNOWNGROUP;
    Exit;
  end;

  if nCmdID <> OLECMDID_SHOWSCRIPTERROR then
  begin
    Result := OLECMDERR_E_NOTSUPPORTED;
    Exit;
  end;

  Event := (IUnknown(vaIn) as IHTMLDocument2).parentWindow.event;

  ErrorLine := Event.errorLine;
  ErrorChar := Event.errorCharacter;
  ErrorCode := Event.errorCode;
  ErrorMsg := Event.errorMessage;
  ErrorUrl := Event.errorUrl;

  ...

  if (should continue running scripts) then
  begin
    vaOut := True;
  end else
  begin
    vaOut := False;
  end;

  Result := S_OK;
end;