Delphi 2010 WebBrowserでjavascriptエラー処理に問題があります。エラーの後にJavaScriptを実行し続けるにはどうすればよいですか?
有効なサイレントプロパティでWebBrowserを使用しています。 OKと思われますが、バグのあるサイトには1つの問題があります。エラーが発生してもスクリプトの一部のように見えます。いくつかのスクリプトの結果はIEと少し異なります。
この問題をどのように解決できますか?
Delphi 2010 WebBrowserでjavascriptエラー処理に問題があります。エラーの後にJavaScriptを実行し続けるにはどうすればよいですか?
有効なサイレントプロパティでWebBrowserを使用しています。 OKと思われますが、バグのあるサイトには1つの問題があります。エラーが発生してもスクリプトの一部のように見えます。いくつかのスクリプトの結果はIEと少し異なります。
この問題をどのように解決できますか?
IOleCommandTarget
を使用し、そのIOleCommandTarget.Exec
メソッドでは、OLECMDID_SHOWSCRIPTERROR
コマンドをキャッチすることができます。
次の例では介在クラスを使用していますので、このコードをユニットに配置すると、フォーム上の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;
"vaOut:= InterpretScript;"少なくともこれは貴重なヒントです。私はmsdnを何度も読んでいます、私はあなたに同意します、これらの戻り値は* S_OKでなければなりません。しかし、実際のアプリケーションでの私の経験によると、OLECMDERR_E_NOTSUPPORTEDに設定する必要があります。そうしないと、予期しない動作が発生します。 – stanleyxu2005
あなたのコードを見直し、私の投稿を他のものと比較するためにあなたが言う前にあなたが言うことを知っていることを確認してください、私は何か貴重なものを持っています*あなたは 'vaOut'現在実行されているコマンドの結果がブール値になり、実行するにはTrueを意味することをどのように知っていますか?次に、結果値を混合しています。私は前に言ったことがあります。IOleCommandTarget :: QueryStatusには結果値OLECMDERR_E_NOTSUPPORTEDはありません。次に、ポインタへのポインタのイベントハンドラをテストしていますか? 'On Assignment(OnNotifyScriptError)then OnNotifyScriptError(...)'をテストするだけです。 – TLama
... VCLがどのように書かれているかを見てください。 'IsEqualGUID'の行はまったく得られません。私の個人的な結論は、もしあなたがこの文書をもっと慎重に読んでみてください。誰かが自分の投稿を見直して私に自分の意見を伝えればうれしいですが、そうではありません。あなた自身のコードを見直す必要がある場合は、私にコメントを残しておいてください。電子メールを介して。 – TLama
このメソッドは、すべてのjavascriptポップアップを抑制します。 – TipTop
このように動作するサンプルページはありますか? ['this'](http://support.microsoft.com/kb/261003)の記事を参照してください。ポップアップが表示される前にエラーがないことは確かですか? IMHOはエラーだけを抑制する必要がありますが、私は一見することができます... – TLama
@TipTopは、一般的に言えば、コードはJavaScript呼び出しのポップアップとは関係ありません。コードに問題がある場合は、デフォルトの戻り値はS_OKではなく、OLECMDERR_E_NOTSUPPORTEDであるべきだと思います。 – stanleyxu2005