Мне нужно перехватить ошибки сценария в элементе управления ActiveX MS IE (дублирован как WebBrowser).
На мой взгляд, это достигается путем реализации интерфейса IOleCommandTarget в моем приложении и прослушивания 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 64bit.У меня установлен MS Script Debugger и MSIE «Отключить отладку сценариев для nnn» отключен для обеих опций.MSIE: v9.0.8112.16421 .
Примечание: Я не пометил это под Delphi, поскольку все родные языки можно легко перевести на Delphi, даженекоторые управляемые языки, такие как VB или C #.
Ссылки по теме: