【发布时间】:2011-12-19 19:49:30
【问题描述】:
我在 Delphi 2010 上的 WebBrowser 中处理 javascript 错误时遇到了一些问题。
我正在使用启用了静默属性的 WebBrowser。似乎没问题,但是在带有错误脚本的站点上存在一个问题:错误未执行后似乎是脚本的一部分。部分脚本的结果与 IE 略有不同。
您知道如何解决这个问题吗?
【问题讨论】:
标签: javascript delphi browser
我在 Delphi 2010 上的 WebBrowser 中处理 javascript 错误时遇到了一些问题。
我正在使用启用了静默属性的 WebBrowser。似乎没问题,但是在带有错误脚本的站点上存在一个问题:错误未执行后似乎是脚本的一部分。部分脚本的结果与 IE 略有不同。
您知道如何解决这个问题吗?
【问题讨论】:
标签: javascript delphi browser
您可以使用IOleCommandTarget 并在其IOleCommandTarget.Exec 方法中捕获OLECMDID_SHOWSCRIPTERROR 命令。
在下面的示例中,我使用了插入类,因此如果您将此代码放入您的单元中,则只有表单上的那些 Web 浏览器或在此单元中动态创建的那些 Web 浏览器会获得此行为。
uses
SHDocVw, ActiveX;
type
TWebBrowser = class(SHDocVw.TWebBrowser, IOleCommandTarget)
private
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
function TWebBrowser.QueryStatus(CmdGroup: PGUID; cCmds: Cardinal;
prgCmds: POleCmd; CmdText: POleCmdText): HRESULT; stdcall;
begin
Result := S_OK;
end;
function TWebBrowser.Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
const vaIn: OleVariant; var vaOut: OleVariant): HRESULT; stdcall;
begin
// presume that all commands can be executed; for list of available commands
// see SHDocVw.pas unit, using this event you can suppress or create custom
// events for more than just script error dialogs, there are commands like
// undo, redo, refresh, open, save, print etc. etc.
// be careful, because not all command results are meaningful, like the one
// with script error message boxes, I would expect that if you return S_OK,
// the error dialog will be displayed, but it's vice-versa
Result := S_OK;
// there's a script error in the currently executed script, so
if nCmdID = OLECMDID_SHOWSCRIPTERROR then
begin
// if you return S_FALSE, the script error dialog is shown
Result := S_FALSE;
// if you return S_OK, the script error dialog is suppressed
Result := S_OK;
end;
end;
【讨论】:
this 文章。您确定在显示弹出窗口之前没有错误吗?恕我直言,它应该只抑制错误,但我可以看看......
这是我的实施建议。
uses
SHDocVw, ActiveX;
type
TWebBrowser = class(SHDocVw.TWebBrowser, IOleCommandTarget)
private
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
function TWebBrowser.QueryStatus(CmdGroup: PGUID; cCmds: Cardinal;
prgCmds: POleCmd; CmdText: POleCmdText): HRESULT; stdcall;
begin
// MSDN notes that a command target must implement this function; E_NOTIMPL is not a
// valid return value. Be careful to return S_OK, because we notice that context menu
// of Web page "Add to Favorites..." becomes disabled. Another MSDN document shows an
// example with default return value OLECMDERR_E_NOTSUPPORTED.
// http://msdn.microsoft.com/en-us/library/bb165923(v=vs.80).aspx
Result := OLECMDERR_E_NOTSUPPORTED;
end;
function TWebBrowser.Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
const vaIn: OleVariant; var vaOut: OleVariant): HRESULT; stdcall;
var
ShowDialog, InterpretScript: Boolean;
begin
if CmdGroup = nil then
begin
Result := OLECMDERR_E_UNKNOWNGROUP;
Exit;
end;
// MSDN notes that a command target must implement this function; E_NOTIMPL is not a
// valid return value. Be careful to return S_OK, because we notice some unhandled
// commands behave unexpected with S_OK. We assumed that a return value
// OLECMDERR_E_NOTSUPPORTED means to use the default behavior.
Result := OLECMDERR_E_NOTSUPPORTED;
if IsEqualGUID(CmdGroup^, CGID_DocHostCommandHandler) then
begin
// there's a script error in the currently executed script, so
if nCmdID = OLECMDID_SHOWSCRIPTERROR then
begin
ShowDialog := True;
InterpretScript := False;
// Implements an event if you want, so that your application is able to choose the way of handling script errors at runtime.
if Assigned(OnNotifyScriptError) then
OnNotifyScriptError(Self, ShowDialog, InterpretScript);
if ShowDialog then
Result := S_FALSE
else
Result := S_OK;
vaOut := InterpretScript; // Without setting the variable to true, further script execution will be cancelled.
end;
end;
end;
【讨论】:
IOleCommandTarget::QueryStatus 没有OLECMDERR_E_NOTSUPPORTED 结果值...接下来,您为什么要测试指向指针的事件处理程序?只需测试if Assigned(OnNotifyScriptError) then OnNotifyScriptError(...)
IsEqualGUID 的行我根本不明白。我个人的结论是,如果您认真对待,那么请尝试更仔细地阅读文档(如果您是从另一个非官方文档中获得的,那么就离开吧)。如果有人评论我的帖子并告诉我自己的意见,我很高兴,但不是这样。如果您只需要查看自己的代码,那么您可以给我留言,我可以帮助您,例如通过电子邮件。