我需要捕获 MS IE activex 控件(称为 WebBrowser)中的脚本错误。
据我所知,这是由 implementing the IOleCommandTarget interface in my application and listening for OLECMDID_SHOWSCRIPTERROR 完成的.
我执行了上述操作,并且我知道它可以工作,因为调用了我的 Exec 方法,但问题在于;仅在将 nCmdID
设置为 $00000037
(OLECMDID_PAGEACTIONBLOCKED
) 的情况下调用一次,但绝不会调用 $00000028
( OLECMDID_SHOWSCRIPTERROR
)。
为了触发该错误,我一直在使用以下代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>TEST SCRIPT</title>
</head><body>
<script type="text/javascript">
document.body.style.background='yellow';
setTimeout(function(){
document.body.style.background='red';
causeERROR(); // purposefully undefined function
document.body.style.background='green';
},500);
</script>
</body>
</html>
上面的代码显示一个黄页,几毫秒后,显示一个红色页,如果脚本继续执行(发生错误后),它应该是绿色的。
在变红后,我立即看到 MSIE 的脚本错误对话框,这一切都很好。但我的 Exec 方法没有被触发。
注意:上面的延迟错误是为了确保运行时错误而不是页面加载错误,以防万一它产生差异。
我的IOleCommandTarget
实现如下(Delphi):
type
TNulWBContainer = class(TWebBrowser, IUnknown, IOleClientSite,
IDocHostUIHandler, IDispatch, IOleCommandTarget)
protected
{ OTHER STUFF }
{IOleCommandTarget Interface}
function QueryStatus(CmdGroup: PGUID; cCmds: Cardinal;
prgCmds: POleCmd; CmdText: POleCmdText): HResult; stdcall;
function Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
const vaIn: OleVariant; var vaOut: OleVariant): HResult; stdcall;
end;
implementation
{ OTHER STUFF }
function TNulWBContainer.QueryStatus(CmdGroup: PGUID; cCmds: Cardinal;
prgCmds: POleCmd; CmdText: POleCmdText): HResult; stdcall;
begin
prgCmds.cmdf := OLECMDF_ENABLED;
Result := S_OK; //inherited QueryStatus(CmdGroup,cCmds,prgCmds,CmdText);
end;
function TNulWBContainer.Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
const vaIn: OleVariant; var vaOut: OleVariant): HResult; stdcall;
begin
ShowMessage('nCmdID=$'+IntToHex(nCmdID,8));
Result:=OLECMDERR_E_UNKNOWNGROUP;
end;
end.
我在 Windows 7 Ult 64 位上运行这个东西。我安装了 MS 脚本调试器,并且为这两个选项关闭了 MSIE 的“禁用 nnn 的脚本调试”。 MSIE 是 v9.0.8112.16421。
注意:我没有在 Delphi 下标记它,因为所有本地语言都可以轻松翻译为 Delphi,甚至是一些托管语言,例如 VB 或 C#。
<小时/>相关链接:
最佳答案
这是多年来最愚蠢的错误!不认真!
MS,你真的很烂这个;)
我成功了,我的代码实际上从一开始就是正确的(即两天前;))
正如文章所述,您需要 禁用脚本调试 (Internet Explorer)
取消选中。
但是 禁用脚本调试(其他)
必须选中(在“Internet 选项”>“高级”中)。
奇怪吧?我从这里得到提示:http://www.delphigroups.info/2/9/938468.html (2005-04-29 09:42:48 下午)。
是的,那是 6 年前的事了。我很惊讶,不,很惊讶,这样的事情是可能发生的,而且没有任何记录。
编辑:程序化修复:
uses Registry;
// ...
with TRegistry.Create do
try
RootKey:=HKEY_CURRENT_USER;
if OpenKey('\Software\Microsoft\Internet Explorer\Main',False) then begin
WriteString('DisableScriptDebuggerIE','no');
WriteString('Disable Script Debugger','yes');
CloseKey;
end;
finally
Free;
end;
// ...
关于delphi - WebBrowser (MSIE) - 使用 IOleCommandTarget 的 Exec 捕获 JS 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5450514/