title: WebBrowser (MSIE) - Capture JS Errors using Exec of IOleCommandTarget
body: <p>I need to capture script errors in MS IE activex control (dubbed as WebBrowser).</p>
  
  <p>As I see it, this is done by <a href="http://support.microsoft.com/kb/261003" rel="nofollow">implementing the IOleCommandTarget interface in my application and listening for OLECMDID_SHOWSCRIPTERROR</a>.</p>
  
  <p>I did the above and I know it works since my Exec method is called, but here's the problem; it is only called once with <code>nCmdID</code> being set to <code>$00000037</code> (<code>OLECMDID_PAGEACTIONBLOCKED</code>), but never <code>$00000028</code> (<code>OLECMDID_SHOWSCRIPTERROR</code>).</p>
  
  <p>In order to trigger that error, I've been using this code:</p>
  
  <pre><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
      &lt;head&gt;
          &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
          &lt;title&gt;TEST SCRIPT&lt;/title&gt;
      &lt;/head&gt;&lt;body&gt;
          &lt;script type="text/javascript"&gt;
              document.body.style.background='yellow';
              setTimeout(function(){
                  document.body.style.background='red';
                  causeERROR(); // purposefully undefined function
                  document.body.style.background='green';
              },500);
          &lt;/script&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>The code above shows a yellow page, then after a few milliseconds, a red one and if script execution continues (after the error occurs) it should be green.</p>
  
  <p>Right after turning red, I get MSIE's script error dialog, which is all fine. But my Exec method is not triggered.</p>
  
  <p><strong>Note:</strong> The delayed error above is to ensure a runtime error as opposed to a page load error, just in case it does a difference.</p>
  
  <p>My <code>IOleCommandTarget</code> implementation is as follows (Delphi):</p>
  
  <pre><code>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.
  </code></pre>
  
  <p>I'm running this stuff on Windows 7 Ult 64bit. I have MS Script Debugger installed and MSIE's "Disable script debugging for nnn" turned off for both options. MSIE is <em>v9.0.8112.16421</em>.</p>
  
  <p><strong>Note:</strong> I didn't tag this under Delphi since all native languages out there can be easily translated to Delphi, even some managed languages such as VB or C#.</p>
  
  <hr>
  
  <p><strong>Related Links:</strong></p>
  
  <ul>
  <li><a href="http://support.microsoft.com/kb/261003" rel="nofollow">http://support.microsoft.com/kb/261003</a></li>
  <li><a href="http://www.codeproject.com/KB/shell/popupblocker.aspx" rel="nofollow">http://www.codeproject.com/KB/shell/popupblocker.aspx</a></li>
  <li><a href="http://www.tech-archive.net/Archive/VC/microsoft.public.vc.atl/2007-10/msg00158.html" rel="nofollow">http://www.tech-archive.net/Archive/VC/microsoft.public.vc.atl/2007-10/msg00158.html</a> - This is kind of cryptic, I didn't understand (2), (4) and (5).</li>
  </ul>