![]()
前回は表示しているページのjavascriptなどでエラーが発生してもエラーダイアログが表示されないようにした。今回はエラーが発生したときにステータスバーにエラーが出た旨のメッセージが表示されるようにする。
#define WM_DNP_SCRIPTERROR (WM_APP + 6) //■追加
#include "DnpDocHostUIHandlerImpl.h"
//■追加
//スクリプトエラーの通知先ウインドウなどを設定するためのインターフェース
MIDL_INTERFACE("2C66181A-27D5-486e-A84A-3B8EDAE1951F")
IScriptErrorSetting : public IUnknown
{
public:
STDMETHOD (put_hWndNotify)(HWND hWnd) = 0; //エラーの通知先HWND(ビューのHWND)を指定
};
//スクリプトエラーを消すためのUIHandler
class CHideScriptError :
public CComObjectRootEx<CComSingleThreadModel>
,public IDnpDocHostUIHandlerImpl
,public IDispatchImpl<IDispatch>
,public IOleCommandTarget
,public IScriptErrorSetting //■追加
{
protected:
HWND _hWndNotify; //■追加
public:
//■追加
CHideScriptError()
{
_hWndNotify = NULL;
}
BEGIN_COM_MAP(CHideScriptError)
COM_INTERFACE_ENTRY(IScriptErrorSetting) //■追加
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IDocHostUIHandler)
COM_INTERFACE_ENTRY(IOleCommandTarget)
END_COM_MAP()
//■追加
//エラーの通知先HWND(ビューのHWND)を指定
STDMETHOD (put_hWndNotify)(HWND hWnd)
{
_hWndNotify = hWnd;
return S_OK;
}
STDMETHODIMP QueryStatus( const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT* pCmdText )
{
return E_NOTIMPL;
}
STDMETHODIMP Exec( const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG* pvaIn, VARIANTARG* pvaOut)
{
//コマンドがスクリプトエラーを示すものなら、エラー表示を無効にする
if(nCmdID == OLECMDID_SHOWSCRIPTERROR)
{
(*pvaOut).vt = VT_BOOL;
(*pvaOut).boolVal = VARIANT_TRUE;
//■追加
if(_hWndNotify && ::IsWindow(_hWndNotify))
::SendMessage(_hWndNotify,WM_DNP_SCRIPTERROR,NULL,NULL);
return S_OK;
}
return E_NOTIMPL;
}
};
![]()
そしてビュー側で送られてきたスクリプトエラーメッセージを受信したらステータスバーに表示するようにする。
BEGIN_MSG_MAP(CTabBrowser100View) MESSAGE_HANDLER(WM_DNP_SCRIPTERROR, OnDnpScriptError) //■追加 MESSAGE_HANDLER(WM_DESTROY, OnDestroy) END_MSG_MAP()
//■追加
//ステータスバーのメッセージ変更をメインウインドウへ通知
void ChangeStatusText(LPCTSTR pszText)
{
_strLastStatusText = pszText; //いつでも参照できるようにクラスのメンバーに保存しておく
if(_pTabView == NULL || _pTabView->GetActivePage() != _pTabView->PageIndexFromHwnd(m_hWnd))
return; //このビューがアクティブでなければこれ以降処理しない
//メインウインドウに変更を通知する
GetTopLevelWindow().SendMessage(WM_DNP_CHANGESTATUSTEXT,(WPARAM)(LPCTSTR)_strLastStatusText);
}
//■内部処理変更
void __stdcall OnStatusTextChange(BSTR bstrText)
{
ChangeStatusText((CAtlString)bstrText);
}
//■追加
LRESULT OnDnpScriptError(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ChangeStatusText(_T("ページでエラーが発生しました。")); //固定文字列を表示している!エラーとそうでないのと見分けがつかない
return 0;
}
//UIHandlerの変更。
//■■本当はもともと入っていたUIhandlerを取得/保持してそれも併せて使うようにすべき
bool ChangeUIHandler(void)
{
HRESULT hr = E_FAIL;
CComPtr<IDispatch> pIDispatch;
CComPtr<ICustomDoc> pICustomDoc;
CComPtr<IScriptErrorSetting> pIScriptErrorSetting; //■追加 独自に作ったインターフェース
if(_pHideScriptError == NULL)
_pHideScriptError = new CComObject<CHideScriptError>;
//■4行追加 スクリプトエラー発生時の通知先としてこのビューウインドウを登録する
if(_pHideScriptError)
_pHideScriptError->QueryInterface(&pIScriptErrorSetting);
if(pIScriptErrorSetting)
pIScriptErrorSetting->put_hWndNotify(m_hWnd);
if(_pIWebBrowser2)
hr = _pIWebBrowser2->get_Document(&pIDispatch);
if(pIDispatch)
hr = pIDispatch->QueryInterface(IID_ICustomDoc,(void **)&pICustomDoc);
if(pICustomDoc)
hr = pICustomDoc->SetUIHandler(_pHideScriptError);
return SUCCEEDED(hr) ? true : false;
}
![]()
これでビルド/実行するとスクリプトエラーが発生したときにステータスバーにメッセージがひょじされるようになった。
とは言うものの、マウスカーソルがリンクの上に乗るなどしてIEコントロールからステータスバーメッセージ更新のイベントが届くとエラーメッセージがすぐに消えてしまう。
次回はエラーメッセージがすぐに消えてしまわないように修正する。
