Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使TWebBrowser在出现错误后继续运行JavaScript?_Javascript_Delphi_Browser - Fatal编程技术网

如何使TWebBrowser在出现错误后继续运行JavaScript?

如何使TWebBrowser在出现错误后继续运行JavaScript?,javascript,delphi,browser,Javascript,Delphi,Browser,我在Delphi2010的WebBrowser中处理javascript错误时遇到了一些问题 我正在使用启用了静默属性的WebBrowser。看起来还可以,但在有错误脚本的站点上有一个问题:错误后脚本的一部分似乎不会执行。某些脚本的结果与IE略有不同 您知道如何解决此问题吗?您可以使用,并在其方法中捕获命令 在下面的示例中,我使用了interposed类,因此如果将此代码放入单元中,则只有表单上的web浏览器或在此单元中动态创建的web浏览器才会获得此行为 uses SHDocVw, Act

我在Delphi2010的WebBrowser中处理javascript错误时遇到了一些问题

我正在使用启用了静默属性的WebBrowser。看起来还可以,但在有错误脚本的站点上有一个问题:错误后脚本的一部分似乎不会执行。某些脚本的结果与IE略有不同

您知道如何解决此问题吗?

您可以使用,并在其方法中捕获命令

在下面的示例中,我使用了interposed类,因此如果将此代码放入单元中,则只有表单上的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;

以下是我的实施建议

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;

此方法还禁止所有javascript弹出窗口。您有这样的示例页面吗?见文章。您确定在弹出窗口显示之前没有错误吗?我想它应该只抑制错误,但我可以看看…@TipTop,一般来说,代码与JavaScript调用的弹出窗口无关。如果您确实对代码有问题,我认为默认返回值不应该是S_OK,而应该是OLECMDERR_E_NOTSUPPORTED。@TLama,这两个方法的默认返回值应该是OLECMDERR_E_NOTSUPPORTED。相信我,至少这是一个有价值的暗示。我多次阅读msdn,我同意你的观点,这些返回值应该是S_OK。但根据我在实际应用程序中的经验,我必须将它们设置为OLECMDERR_E_NOTSUPPORTED,否则它的行为会出人意料。请检查您的代码,并确保在将我的帖子与其他帖子进行比较之前知道您所说的内容,我有一些有价值的东西。您在哪里发现
vaOut
值是布尔值?您如何知道当前执行的命令的结果将是布尔值,并且将意味着执行True?接下来,您将混合结果值,我之前已经告诉过您,
IOleCommandTarget::QueryStatus
没有
OLECMDERR\u E\u NOTSUPPORTED
结果值。。。接下来,为什么要测试指针到指针的事件处理程序?只需测试
如果已分配(OnNotifyScriptError),然后测试OnNotifyScriptError(…)
…看看VCL是如何编写的,它是您可以获得的最佳源代码。带有
的行是相等的
我一点也不明白。我个人的结论是,如果你认真对待这个问题,那么试着更仔细地阅读文档(如果你是从另一个非官方文档中获得的,那么就留下它)。如果有人评论我的帖子并告诉我自己的观点,我很高兴,但不是这样。如果您只需要查看自己的代码,那么您可以给我留言,我可以通过电子邮件等方式帮助您。(1)nCmdID不是唯一的。不同的命令组可能具有相同的nCmdID。这就是为什么我们必须首先使用IsEqualGUID()检测命令组的原因。(2) vaOut是一个变种。它可以是字符串、布尔值、整数或其他类型。(这里有一些例子:)它取决于命令本身,不幸的是,vaOut的类型和值通常没有正式的完整文档记录。我已经验证了这个命令,vaOut代表布尔值。