![]()
今回は前に紹介した「IEコントロールのスクリプトエラー表示を消す」の方法を用いて、javascriptなどにエラーがあってもエラーダイアログが表示されないようにする。
まず、前に作成したクラスをタブブラウザーのプロジェクトに取り込む。「プロジェクト」メニューから「既存項目の追加」を選択する。

そして「DnpDocHostUIHandlerImpl.h」をプロジェクトに追加する。
#include "DnpDocHostUIHandlerImpl.h" //■追加
//■追加
//スクリプトエラーを消すためのUIHandler
class CHideScriptError :
public CComObjectRootEx<CComSingleThreadModel>
,public IDnpDocHostUIHandlerImpl
,public IDispatchImpl<IDispatch>
,public IOleCommandTarget
{
public:
BEGIN_COM_MAP(CHideScriptError)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IDocHostUIHandler)
COM_INTERFACE_ENTRY(IOleCommandTarget)
END_COM_MAP()
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;
return S_OK;
}
return E_NOTIMPL;
}
};
CComPtr<IDocHostUIHandler> _pHideScriptError; //■追加
//■追加
//UIHandlerの変更。本当はもともと入っていたUIhandlerを取得/保持してそれも併せて使うようにすべき
bool ChangeUIHandler(void)
{
HRESULT hr = E_FAIL;
CComPtr<IDispatch> pIDispatch;
CComPtr<ICustomDoc> pICustomDoc;
if(_pHideScriptError == NULL)
_pHideScriptError = new CComObject<CHideScriptError>;
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;
}
//HTMLページが読み終わったときに呼ばれる処理
void _stdcall OnDocumentComplete(IDispatch* pDisp, VARIANT* vURL)
{
if(pDisp != _pIWebBrowser2)
return; //フレームなどの読み込み終了は無視
ChangeUIHandler(); //■追加 UIHandlerを変更する
HICON hIcon;
CAtlString strFile;
//テンポラリファイルパス取得
{
DWORD dwRet;
TCHAR pszPath[MAX_PATH + 1024];
TCHAR pszFile[MAX_PATH + 1024];
dwRet = ::GetTempPath(MAX_PATH + 1024,pszPath); //テンポラリフォルダ取得
if(dwRet)
dwRet = ::GetTempFileName(pszPath,NULL,0,pszFile); //テンポラリファイル名自動生成
if(dwRet)
strFile = pszFile;
if(strFile == _T(""))
return;
}
//インターネットショートカットファイル作成
{
bool ret;
strFile += _T(".url");
ret = CreateInternetShortcut((CAtlString)vURL->bstrVal,strFile);
if(ret == false)
return;
//インターネットショートカットにアイコンが適用されるのを待つ(//■■これだとダメ?要調査)
::SHChangeNotify(SHCNE_CREATE,SHCNF_PATH | SHCNF_FLUSH,(LPCTSTR)strFile,NULL);
}
//ファイルからHICONを取得
{
SHFILEINFO sShFileInfo;
HIMAGELIST hImageList;
//パスからアイコン取得
hImageList = (HIMAGELIST)::SHGetFileInfo(strFile,0,&sShFileInfo,sizeof(SHFILEINFO),SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
hIcon = ::ImageList_GetIcon(hImageList,sShFileInfo.iIcon,ILD_NORMAL);
::ImageList_Destroy(hImageList);
}
::remove((CAtlStringA)strFile); //ファイル削除
if(hIcon == NULL)
return;
//タブにHICONを割り当てる
{
int nPage;
int nImage;
CImageList cImageList;
nPage = _pTabView->PageIndexFromHwnd(m_hWnd);
cImageList = _pTabView->GetImageList(); //タブのイメージリスト取得
nImage = _pTabView->GetPageImage(nPage); //現在のイメージ番号取得
if(nImage < 0)
{
//タブに画像がなければ新しく追加して使う
nImage = cImageList.AddIcon(hIcon);
}
else
{
//タブに画像があればそれと置き換える
cImageList.ReplaceIcon(nImage,hIcon);
}
_pTabView->SetPageImage(nPage,nImage); //nImageが変わらなくても再描画のためにセットしなおす
}
::DestroyIcon(hIcon);
}
//タブの選択変更があったときメインウインドウから呼ばれる
bool OnTabPageChange(bool bActivated)
{
if(_pIDeskBand == NULL)
return false;
if(bActivated)
_pIDeskBand->ShowDW(TRUE); //IEツールバーを表示
else
_pIDeskBand->ShowDW(FALSE); //IEツールバーを消す
//■追加
//GoogleツールバーはShowDWで?UIハンドラーを変更するのでここで上書き。
//ShowWindowで表示/非表示を切り替えれば解決するのかな?要調査
if(bActivated)
ChangeUIHandler(); //UIHandlerを変更する
return true;
}
![]()
これでビルド/実行すると、そのページにエラーがあってもエラーダイアログがでなくなった。
しかし逆にエラーがあってもユーザーにはエラーがあったことが分からなくなってしまった。次回はユーザーが分かるようにエラーがあった場合には通知する処理を追加する。
※ちなみに「このリンク」をクリックするとスクリプトエラーが発生する。
