如何获取TWebBrowser错误信息
How to get TWebBrowser error information
我正在根据 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;
然后我尝试获取我需要的信息(如 this link) using GetIDsOfNames
and Invoke
functions of the interface. A working Delphi code for using these methods are in this 文档 link 中所示。
以下是我如何在 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
和returns S_OK
.
但是 Invoke
功能失败了。它 returns 一些负整数作为 HRESULT
并且不输出任何东西到 MethodResult
.
我该如何解决这个问题?
您尝试访问的错误值不是对象方法,它们是属性,因此 Invoke()
将因您使用 DISPATCH_METHOD
而失败。请改用 DISPATCH_PROPERTYGET
。
然而,OleVariant
(和 Variant
)内置了对 IDispatch.Invoke()
的支持,因此您根本不需要手动操作它。您可以正常调用对象方法和 read/write 对象属性,编译器将为您生成必要的 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;
我正在根据 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;
然后我尝试获取我需要的信息(如 this link) using GetIDsOfNames
and Invoke
functions of the interface. A working Delphi code for using these methods are in this 文档 link 中所示。
以下是我如何在 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
和returns S_OK
.
但是 Invoke
功能失败了。它 returns 一些负整数作为 HRESULT
并且不输出任何东西到 MethodResult
.
我该如何解决这个问题?
您尝试访问的错误值不是对象方法,它们是属性,因此 Invoke()
将因您使用 DISPATCH_METHOD
而失败。请改用 DISPATCH_PROPERTYGET
。
然而,OleVariant
(和 Variant
)内置了对 IDispatch.Invoke()
的支持,因此您根本不需要手动操作它。您可以正常调用对象方法和 read/write 对象属性,编译器将为您生成必要的 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;