![]()
前回はツールバーにリンククリック時に鳴る音をON/OFFするためのボタンを追加した。今回は同じように「スクリプトの実行」「画像の表示」「AvtiveXコントロールの実行」「BGMの再生」の各項目をON/OFFするため機能を実装する。
「スクリプトの実行」や「ActiveXコントロールの実行」を今回のような手法で制御することはセキュリティ上の弱点となる。セキュリティ的に少しは弱みとならないような切り替え方法を少し考えてみたのだがどうも複雑になりそう。もともとステータスバーやアドレスバーの実装方法などセキュリティ的に最悪な部分がたくさんあるので細かいことは気にせずに単純にON/OFFを切り替えるに留める。
まずツールバーに4つのボタンを追加する。スクリプト実行のON/OFF用の「ID_SCRIPT」、画像表示用の「ID_IMAGE」、ActiveXコントロール実行用の「ID_ACTIVEX」、BGM再生用の「ID_BGM」を用意した。
virtual BOOL OnIdle()
{
CTabBrowser100View* pView;
pView = GetActivePageView();
//「戻る」「進む」ボタンの状態設定
{
bool bBack = false;
bool bNext = false;
if(pView)
pView->IsButtonEnable(bBack,bNext);
UIEnable(ID_IE_BACK,bBack ? TRUE : FALSE);
UIEnable(ID_IE_NEXT,bNext ? TRUE : FALSE);
}
//「編集」メニュー項目更新
{
bool bCopy = false;
bool bCut = false;
bool bPaste = false;
bool bSelectAll = false;
if(pView)
pView->IsEnable_EditCommand(bCopy,bCut,bPaste,bSelectAll);
UIEnable(ID_EDIT_COPY ,bCopy ? TRUE : FALSE);
UIEnable(ID_EDIT_CUT ,bCut ? TRUE : FALSE);
UIEnable(ID_EDIT_PASTE ,bPaste ? TRUE : FALSE);
UIEnable(ID_EDIT_SELECT_ALL ,bSelectAll ? TRUE : FALSE);
}
//未実装メニュー項目を全部無効に設定
{
UIEnable(ID_FILE_COPY_TAB, FALSE);
UIEnable(ID_FILE_NEW_WINDOW, FALSE);
UIEnable(ID_FILE_NEW_SESSION, FALSE);
UIEnable(ID_FILE_OPEN, FALSE);
UIEnable(ID_FILE_EDIT, FALSE);
// UIEnable(ID_FILE_SAVE, FALSE); //有効/無効設定必要
// UIEnable(ID_FILE_SAVE_AS, FALSE); //有効/無効設定必要
UIEnable(ID_FILE_SEND_PAGE, FALSE);
UIEnable(ID_FILE_SEND_LINK, FALSE);
// UIEnable(ID_FILE_CREATE_SHORTCUT, FALSE); //有効/無効設定必要
UIEnable(ID_FILE_INPORT_EXPORT, FALSE);
// UIEnable(ID_FILE_PROPERTY, FALSE); //有効/無効設定必要
UIEnable(ID_FILE_OFFLINE, FALSE);
// UIEnable(ID_EDIT_FIND, FALSE); //有効/無効設定必要
UIEnable(ID_VIEW_FIXED, FALSE);
UIEnable(ID_VIEW_QUICKTAB, FALSE);
UIEnable(ID_VIEW_FAVORITE, FALSE);
UIEnable(ID_VIEW_HISTORY, FALSE);
UIEnable(ID_VIEW_FEED, FALSE);
(...省略...)
UIEnable(ID_TOOL_DEVELOP, FALSE);
UIEnable(ID_TOOL_INTERNET_OPTION, FALSE);
}
//ツールバーボタン。クリック音を鳴らす
{
bool bDisable;
bDisable = IsFeatureEnabled(FEATURE_DISABLE_NAVIGATION_SOUNDS);
UISetCheck(ID_CLICK_SOUND,! bDisable);
}
//■追加
//ダウンロードコントロール
if(pView)
{
bool bEnable;
//何度もフラグを読み出してるので効率が悪いが気にしない
bEnable = pView->IsEnableAmbientDownloadControl(DLCTL_DLIMAGES);
UISetCheck(ID_IMAGE,bEnable);
bEnable = pView->IsEnableAmbientDownloadControl(DLCTL_BGSOUNDS);
UISetCheck(ID_BGM,bEnable);
bEnable = pView->IsEnableAmbientDownloadControl(DLCTL_NO_SCRIPTS);
UISetCheck(ID_SCRIPT,! bEnable); //反転
bEnable = pView->IsEnableAmbientDownloadControl(DLCTL_NO_RUNACTIVEXCTLS);
UISetCheck(ID_ACTIVEX,! bEnable); //反転
}
UIUpdateToolBar();
return FALSE;
}
bool IsFeatureEnabled(INTERNETFEATURELIST FeatureEntry)
{
HRESULT hr;
hr = ::CoInternetIsFeatureEnabled(FeatureEntry,SET_FEATURE_ON_PROCESS);
if(hr == S_OK)
return true;
return false;
}
BEGIN_UPDATE_UI_MAP(CMainFrame)
UPDATE_ELEMENT(ID_SCRIPT, UPDUI_TOOLBAR) //■追加
UPDATE_ELEMENT(ID_IMAGE, UPDUI_TOOLBAR) //■追加
UPDATE_ELEMENT(ID_ACTIVEX, UPDUI_TOOLBAR) //■追加
UPDATE_ELEMENT(ID_BGM, UPDUI_TOOLBAR) //■追加
UPDATE_ELEMENT(ID_CLICK_SOUND, UPDUI_TOOLBAR)
UPDATE_ELEMENT(ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP)
UPDATE_ELEMENT(ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP)
UPDATE_ELEMENT(ID_IE_BACK, UPDUI_TOOLBAR)
UPDATE_ELEMENT(ID_IE_NEXT, UPDUI_TOOLBAR)
UPDATE_ELEMENT(ID_EDIT_COPY, UPDUI_TOOLBAR | UPDUI_MENUPOPUP)
BEGIN_MSG_MAP(CMainFrame)
MESSAGE_HANDLER(WM_DNP_CREATENEWTAB, OnDnpCreateNewTab)
MESSAGE_HANDLER(WM_DNP_CHANGEFOCUS, OnDnpChangeFocus)
MESSAGE_HANDLER(WM_DNP_CHANGEADDRESS, OnDnpChangeAddress)
NOTIFY_CODE_HANDLER(CBEN_ENDEDIT, OnAddressbarEnter)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew)
COMMAND_ID_HANDLER(ID_VIEW_TOOLBAR, OnViewToolBar)
COMMAND_ID_HANDLER(ID_VIEW_STATUS_BAR, OnViewStatusBar)
COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
COMMAND_ID_HANDLER(ID_WINDOW_CLOSE, OnWindowClose)
COMMAND_ID_HANDLER(ID_WINDOW_CLOSE_ALL, OnWindowCloseAll)
COMMAND_ID_HANDLER(ID_FILE_PRINT, OnFileCommand)
COMMAND_ID_HANDLER(ID_FILE_PRINT_PREVIEW, OnFileCommand)
COMMAND_ID_HANDLER(ID_FILE_PRINT_SETUP, OnFileCommand)
COMMAND_ID_HANDLER(ID_EDIT_COPY, OnFileCommand)
COMMAND_ID_HANDLER(ID_EDIT_CUT, OnFileCommand)
COMMAND_ID_HANDLER(ID_EDIT_PASTE, OnFileCommand)
COMMAND_ID_HANDLER(ID_EDIT_SELECT_ALL, OnFileCommand)
COMMAND_ID_HANDLER(ID_FILE_SAVE, OnFileCommand)
COMMAND_ID_HANDLER(ID_FILE_SAVE_AS, OnFileCommand)
COMMAND_ID_HANDLER(ID_FILE_CREATE_SHORTCUT, OnFileCommand)
COMMAND_ID_HANDLER(ID_FILE_PROPERTY, OnFileCommand)
COMMAND_ID_HANDLER(ID_EDIT_FIND, OnFileCommand)
COMMAND_ID_HANDLER(ID_CLICK_SOUND, OnFileCommand)
COMMAND_ID_HANDLER(ID_IMAGE, OnFileCommand) //■追加
COMMAND_ID_HANDLER(ID_BGM, OnFileCommand) //■追加
COMMAND_ID_HANDLER(ID_SCRIPT, OnFileCommand) //■追加
COMMAND_ID_HANDLER(ID_ACTIVEX, OnFileCommand) //■追加
COMMAND_RANGE_HANDLER(ID_WINDOW_TABFIRST, ID_WINDOW_TABLAST, OnWindowActivate)
COMMAND_ID_HANDLER(ID_IE_BACK, OnIECommand)
COMMAND_ID_HANDLER(ID_IE_NEXT, OnIECommand)
COMMAND_ID_HANDLER(ID_IE_STOP, OnIECommand)
COMMAND_ID_HANDLER(ID_IE_REFRESH, OnIECommand)
COMMAND_ID_HANDLER(ID_IE_ADDFAVORITE, OnIEAddFavorite)
COMMAND_ID_HANDLER(ID_IE_ORGANIZE_FAVORITE, OnIEOrganizeFavorite)
NOTIFY_CODE_HANDLER(TBVN_CONTEXTMENU, OnTabContextMenu)
NOTIFY_CODE_HANDLER(TBVN_PAGEACTIVATED, OnTabPageActivated)
MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
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 OnFileCommand(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled)
{
CTabBrowser100View* pView;
pView = GetActivePageView();
if(pView == NULL)
{
bHandled = FALSE;
return 0;
}
bHandled = TRUE;
switch(wID)
{
//■追加
case ID_IMAGE: //画像表示
case ID_BGM: //BGM再生
case ID_SCRIPT: //スクリプト実行
case ID_ACTIVEX: //ActiveXコントロール実行
{
bool bEnable;
long nFlag;
nFlag = 0;
switch(wID)
{
case ID_IMAGE: nFlag = DLCTL_DLIMAGES; break;
case ID_BGM: nFlag = DLCTL_BGSOUNDS; break;
case ID_SCRIPT: nFlag = DLCTL_NO_SCRIPTS; break;
case ID_ACTIVEX: nFlag = DLCTL_NO_RUNACTIVEXCTLS; break;
}
bEnable = pView->IsEnableAmbientDownloadControl(nFlag);
pView->SetAmbientDownloadControl(nFlag,! bEnable);
break;
}
case ID_CLICK_SOUND: //クリック音を再生するかどうかの設定
{
bool bDisable;
bDisable = IsFeatureEnabled(FEATURE_DISABLE_NAVIGATION_SOUNDS);
::CoInternetSetFeatureEnabled(FEATURE_DISABLE_NAVIGATION_SOUNDS,SET_FEATURE_ON_PROCESS,bDisable ? FALSE : TRUE);
}
break;
case ID_FILE_SAVE: //上書き保存
pView->Save();
break;
case ID_FILE_SAVE_AS: //名前を付けて保存
pView->SaveAs();
break;
case ID_FILE_CREATE_SHORTCUT: //デスクトップにリンク作成
pView->CreateShortcut();
break;
case ID_FILE_PROPERTY: //プロパティ
pView->ShowProperty();
break;
case ID_EDIT_FIND: //検索
pView->ShowFind();
break;
case ID_EDIT_COPY: //コピー
pView->Copy();
break;
case ID_EDIT_CUT: //切り取り
pView->Cut();
break;
case ID_EDIT_PASTE: //貼り付け
pView->Paste();
break;
case ID_EDIT_SELECT_ALL: //全てを選択
pView->SelectAll();
break;
case ID_FILE_PRINT: //印刷
pView->PrintOrPreview(true);
break;
case ID_FILE_PRINT_PREVIEW: //印刷プレビュー
pView->PrintOrPreview(false);
break;
case ID_FILE_PRINT_SETUP: //印刷セットアップ
pView->PrintSetup();
break;
default:
bHandled = FALSE;
break;
}
return 0;
}
#include "mshtmdid.h"
//■追加
MIDL_INTERFACE("A419B9D4-2940-44c9-B0E0-A0B0FC61046F")
IAmbientControl : public IUnknown
{
public:
STDMETHOD (put_nAmbient)(long newVal) = 0;
STDMETHOD (get_nAmbient)(long* pnVal) = 0;
};
//■追加
class CAmbientControl :
public CComObjectRootEx<CComSingleThreadModel>
,public IDispatchImpl<IDispatch>
,public IOleClientSite
,public IAmbientControl
{
long _nAmbient;
public:
CAmbientControl()
{
_nAmbient = DLCTL_DLIMAGES | DLCTL_VIDEOS | DLCTL_BGSOUNDS;
}
BEGIN_COM_MAP(CAmbientControl)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IAmbientControl)
COM_INTERFACE_ENTRY(IOleClientSite)
END_COM_MAP()
STDMETHOD(Invoke)(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr)
{
if(dispIdMember == DISPID_AMBIENT_DLCONTROL)
{
//ダウンロードコントロール設定
V_VT(pVarResult) = VT_I4;
V_I4(pVarResult) = _nAmbient;
return S_OK;
}
//if(dispIdMember == DISPID_AMBIENT_USERAGENT)
//{
// //pvar->vt = VT_BSTR;
// //pvar->bstrVal = ::SysAllocString(T2OLE(strUserAgent));
//}
return E_NOTIMPL;
}
STDMETHOD(put_nAmbient)(long newVal)
{
_nAmbient = newVal;
return S_OK;
}
STDMETHOD(get_nAmbient)(long* pnVal)
{
if(pnVal == NULL)
return E_POINTER;
*pnVal = _nAmbient;
return S_OK;
}
STDMETHOD(SaveObject)(void)
{
return E_NOTIMPL;
}
STDMETHOD(GetMoniker)(DWORD dwAssign,DWORD dwWhichMoniker,IMoniker **ppmk)
{
return E_NOTIMPL;
}
STDMETHOD(GetContainer)(IOleContainer **ppContainer)
{
return E_NOTIMPL;
}
STDMETHOD(ShowObject)(void)
{
return E_NOTIMPL;
}
STDMETHOD(OnShowWindow)(BOOL fShow)
{
return E_NOTIMPL;
}
STDMETHOD(RequestNewObjectLayout)(void)
{
return E_NOTIMPL;
}
};
![]()
ビューウインドウ内にAmbientDownloadのフラグを取得/設定するための関数を追加する。
CComPtr<IAmbientControl> _pIAmbientControl; //■追加
//■追加
//ダウンロードコントロール設定
//nFlagsは DLCTL_DLIMAGES | DLCTL_VIDEOS | DLCTL_BGSOUNDS などを渡す
bool SetAmbientDownloadControl(long nFlags)
{
if(_pIAmbientControl == NULL)
return false;
//設定
_pIAmbientControl->put_nAmbient(nFlags);
//変更の適用
HRESULT hr;
CComPtr<IOleControl> pIOleControl;
hr = _pIWebBrowser2->QueryInterface(&pIOleControl);
if(pIOleControl)
hr = pIOleControl->OnAmbientPropertyChange(DISPID_AMBIENT_DLCONTROL);
return SUCCEEDED(hr) ? true : false;
}
//■追加
//ダウンロードコントロール取得
//nFlagsは DLCTL_DLIMAGES | DLCTL_VIDEOS | DLCTL_BGSOUNDS などが返る
bool GetAmbientDownloadControl(long& nFlags)
{
nFlags = 0;
if(_pIAmbientControl == NULL)
return false;
return SUCCEEDED(_pIAmbientControl->get_nAmbient(&nFlags)) ? true : false;
}
//■追加
//指定したダウンロードコントロールフラグが現在有効化どうか
//nFlagはDLCTL_DLIMAGESやDLCTL_NO_SCRIPTSなどを1つだけ渡す
bool IsEnableAmbientDownloadControl(long nFlag)
{
long nAmbient;
GetAmbientDownloadControl(nAmbient);
return (nAmbient & nFlag) ? true : false;
}
//■追加
//指定したダウンロードコントロールフラグの設定/解除
//nFlagはDLCTL_DLIMAGESやDLCTL_NO_SCRIPTSなどを1つだけ渡す
//bEnable=trueならそのフラグを設定、falseなら解除する
bool SetAmbientDownloadControl(long nFlag,bool bEnable)
{
bool ret;
long nAmbient;
ret = GetAmbientDownloadControl(nAmbient);
if(ret == false)
return false;
if(bEnable)
nAmbient |= nFlag;
else
nAmbient &= ~nFlag;
return SetAmbientDownloadControl(nAmbient);
}
//Create関数のオーバーライド。内部でIEの取得、接続などを行う
HWND Create(HWND hWndParent, _U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
DWORD dwStyle = 0, DWORD dwExStyle = 0,
_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
{
HWND hWnd;
hWnd = __super::Create(hWndParent,rect,szWindowName,dwStyle,dwExStyle,MenuOrID,lpCreateParam);
if(hWnd == NULL)
return NULL; //Create失敗
QueryControl(&_pIWebBrowser2); //_pIWebBrowser2にこのビューに関連づいているIEをセットする
if(_pIWebBrowser2 == NULL)
return hWnd; //WebBrowser取得失敗
Advise(_pIWebBrowser2); //IEとの接続
//■追加
//jacascriptや画像ダウンロードのコントロール設定
{
CComPtr<IOleObject> pIOleObject;
CComObject<CAmbientControl>* pCAmbientControl;
CComPtr<IAxWinAmbientDispatchEx> pIAxWinAmbientDispatchEx;
//ダウンロードコントロールの準備
CComObject<CAmbientControl>::CreateInstance(&pCAmbientControl);
if(pCAmbientControl)
pCAmbientControl->QueryInterface(&_pIAmbientControl);
//IEコントロールへのセット
_pIWebBrowser2->QueryInterface(&pIOleObject);
if(pIOleObject && pCAmbientControl)
pIOleObject->SetClientSite(pCAmbientControl);
//デフォルトのダウンロードコントロールを設定
//本来ならゾーン変化をチェックしてゾーンに応じて決定すべき?
SetAmbientDownloadControl(DLCTL_DLIMAGES | DLCTL_VIDEOS | DLCTL_BGSOUNDS);
}
//Googleツールバーを生成する
{
HRESULT hr;
GUID rclsid;
WCHAR pszGUID[] = {L"{2318C2B1-4965-11d4-9B18-009027A5CD4F}"}; //GoogleツールバーのGUID
::CLSIDFromString(pszGUID,&rclsid);
_pIDeskBand = NULL;
hr = ::CoCreateInstance(rclsid,NULL,CLSCTX_INPROC_SERVER,IID_IDeskBand,(void**)&_pIDeskBand);
if(_pIDeskBand)
{
CComPtr<IObjectWithSite> pIObjectWithSite;
_pIDeskBand->QueryInterface(IID_IObjectWithSite,(void**)&pIObjectWithSite);
DESKBANDINFO sDeskBandInfo;
//別に必要ないが情報をたくさん取得
::ZeroMemory(&sDeskBandInfo,sizeof(DESKBANDINFO));
sDeskBandInfo.dwMask = DBIM_MINSIZE | DBIM_MAXSIZE | DBIM_INTEGRAL | DBIM_ACTUAL | DBIM_TITLE | DBIM_MODEFLAGS | DBIM_BKCOLOR;
hr = _pIDeskBand->GetBandInfo(0,DBIF_VIEWMODE_NORMAL,&sDeskBandInfo);
//■■本当はきちんと調整しないとだめ!!
CRect rect(0,0,2000,sDeskBandInfo.ptMinSize.y); //横サイズは十分大きいサイズを確保(//■■2000px固定)
//デスクバンドをホスト用クラスに割り当てる
{
CComPtr<IIEToolbar> pIIEToolbar;
pIIEToolbar = new CComObject<CIEToolbar>;
pIIEToolbar->put_hwnd(_hWndRebarIE);
if(_pIWebBrowser2)
pIIEToolbar->put_IWebBrowser2(_pIWebBrowser2);
if(pIObjectWithSite)
hr = pIObjectWithSite->SetSite(pIIEToolbar);
if(SUCCEEDED(hr))
hr = _pIDeskBand->ShowDW(TRUE);
}
//位置調整
{
HWND hWnd;
_pIDeskBand->GetWindow(&hWnd);
if(::IsWindow(hWnd))
::MoveWindow(hWnd,0,0,rect.Width(),rect.Height(),TRUE);
}
}
}
return hWnd;
}
![]()
これでビルド/実行し「画像表示」をOFFにして「更新」したところ、画像が表示されなくなった。
Googleツールバー6が公開されていたのでインストールしたところ、このタブブラウザ上でGoogleツールバーの下部が少し欠けて表示されるようになってしまった。次回はこれを機会にGoogleツールバー表示部分を少し見直す。
