![]()
前回は開いているページでスクリプトエラーが発生したときにステータスバーにアイコンが表示されるようにした。今回はステータスバーをダブルクリックしたときにエラーに関する情報を表示する。
IEコントロールでは私の知る限りエラーメッセージを後から表示するための機能は備わっていない。Internet Explorer 8などではエラーメッセージを内部で保管しておき、必要に応じてエラー情報をダイアログで表示していると思われる。
そのため今回は内部でエラー情報を保持してステータスバーがダブルクリックされた時にそれを表示することにする。まずスクリプトエラー検出用のインターフェースにエラーメッセージを表示するためのメソッドを追加する。
//スクリプトエラーの通知先ウインドウなどを設定するためのインターフェース
MIDL_INTERFACE("2C66181A-27D5-486e-A84A-3B8EDAE1951F")
IScriptErrorSetting : public IUnknown
{
public:
STDMETHOD (put_hWndNotify)(HWND hWnd) = 0; //エラーの通知先HWND(ビューのHWND)を指定
STDMETHOD (ShowLastScriptError)(HWND hWnd) = 0; //■追加
};
CAtlString _strErrorMessage; //■追加 表示用のエラー情報
//■追加
STDMETHOD (ShowLastScriptError)(HWND hWnd)
{
if(_strErrorMessage == _T(""))
return E_FAIL;
::MessageBox(hWnd,_strErrorMessage,_T("エラー情報"),MB_OK | MB_ICONWARNING);
return S_OK;
}
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,(WPARAM)TRUE,NULL);
//■追加
//エラー情報を保存
//面倒なので表示用に整形して_strErrorMessageに代入している
//本当はURIをチェックして同じならどんどん貯めておいた方がいい
{
_strErrorMessage = _T("");
CComPtr<IHTMLDocument2> pIHTMLDocument2;
CComPtr<IHTMLWindow2> pIHTMLWindow2;
CComPtr<IHTMLEventObj> pIHTMLEventObj;
if(pvaIn && pvaIn->punkVal)
pvaIn->punkVal->QueryInterface(IID_IHTMLDocument2,(void**)&pIHTMLDocument2);
if(pIHTMLDocument2)
pIHTMLDocument2->get_parentWindow(&pIHTMLWindow2);
if(pIHTMLWindow2)
pIHTMLWindow2->get_event(&pIHTMLEventObj);
if(pIHTMLEventObj)
{
int i;
OLECHAR* pwszName[] = {L"errorLine",L"errorCharacter",L"errorCode",L"errorMessage",L"errorUrl"};
TCHAR* pszHeader[] = {_T("ライン:"),_T("文字:"),_T("エラーコード:"),_T(""),_T("URI:")};
for(i = 0; i < 5; i++)
{
DISPID nDispID;
HRESULT hr;
DISPPARAMS sDispParams;
CComVariant vResult;
//エラー情報のDISPID取得
hr = pIHTMLEventObj->GetIDsOfNames(IID_NULL,&pwszName[i],1,LOCALE_SYSTEM_DEFAULT,&nDispID);
if(FAILED(hr))
continue;
//エラー情報取得
::ZeroMemory(&sDispParams,sizeof(DISPPARAMS));
hr = pIHTMLEventObj->Invoke(nDispID,IID_NULL,LOCALE_SYSTEM_DEFAULT,DISPATCH_PROPERTYGET,&sDispParams,&vResult,NULL,NULL);
if(FAILED(hr))
continue;
CAtlString strBuff(vResult);
_strErrorMessage += pszHeader[i];
_strErrorMessage += strBuff;
_strErrorMessage += _T("\n");
}
}
}
return S_OK;
}
return E_NOTIMPL;
}
//■追加
bool ShowScriptError(void)
{
if(_bPageError == false)
return false; //現在エラー中ではない
CComPtr<IScriptErrorSetting> pIScriptErrorSetting; //独自に作ったインターフェース
if(_pHideScriptError)
_pHideScriptError->QueryInterface(&pIScriptErrorSetting);
if(pIScriptErrorSetting)
pIScriptErrorSetting->ShowLastScriptError(m_hWnd); //エラーメッセージの表示
return true;
}
![]()
最後にメインウインドウにステータスバーがダブルクリックされたときの処理を追加する。
COMMAND_ID_HANDLER(ID_IE_ORGANIZE_FAVORITE, OnIEOrganizeFavorite)
NOTIFY_CODE_HANDLER(TBVN_CONTEXTMENU, OnTabContextMenu)
NOTIFY_CODE_HANDLER(TBVN_PAGEACTIVATED, OnTabPageActivated)
NOTIFY_HANDLER(ATL_IDW_STATUS_BAR, NM_DBLCLK, OnStatusBarDblClk) //■追加
MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
MESSAGE_HANDLER(WM_SIZE, OnSize)
COMMAND_RANGE_HANDLER(ID_FAVORITE_FIRST,ID_FAVORITE_LAST,OnFavorite)
CHAIN_MSG_MAP_MEMBER(_cFovMenu)
CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
END_MSG_MAP()
//■追加
//ステータスバーのダブルクリック処理
LRESULT OnStatusBarDblClk(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
{
bHandled = FALSE;
NMMOUSE* pNmMouse = (NMMOUSE*)pnmh;
CTabBrowser100View* pView;
if(pNmMouse == NULL)
return 0;
if(pNmMouse->dwItemSpec == 0)
{
//ゼロ番目のペインがダブルクリックされた
pView = GetActivePageView();
if(pView)
pView->ShowScriptError(); //スクリプトエラー情報を表示する
}
return 0;
}
![]()
これでビルド/実行するとスクリプトエラー発生時にステータスバーをダブルクリックすることでエラーの詳細表示を見れるようになった。
次回はメニューバーにInternet Explorerにあるような項目を追加する。
