WebBrowser コントロール の AmbientDispatch の実装メモ

WebBrowser コンポーネントの dwControlFlags (DISPID_AMBIENT_DLCONTROL) の実装(簡単に説明すると、Internet Explorer コンポーネントにJavaScript実行禁止/画像表示禁止/Java実行禁止/オフラインモード/ActiveX実行禁止などのフラグを設定する機能)。いろいろなサイトに質問はあるものの、 VC++に実装するためのコードがどこにもなくて苦労したのでメモ ・ω・

結局ロシアの人のコードを参考に書き換えました

class CMyAmbientDispatch : public IDispatch
{
  const int c_dwControlFlags;
public:
// コンストラクタで Flag初期化してる
  CMyAmbientDispatch()
  : c_dwControlFlags( DLCTL_DLIMAGES  | DLCTL_BGSOUNDS|  DLCTL_VIDEOS  | DLCTL_NO_JAVA | DLCTL_NO_RUNACTIVEXCTLS | DLCTL_NO_DLACTIVEXCTLS)
  {
  }
  STDMETHOD(QueryInterface)(REFIID iid, void** ppvObj) { return E_NOTIMPL ; }
  STDMETHOD_(ULONG, AddRef)() { return 1; }
  STDMETHOD_(ULONG, Release)() { return 1; }
  STDMETHOD(GetTypeInfoCount)(UINT* pctinfo) { return E_NOTIMPL ; }
  STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) { return E_NOTIMPL ; }
  STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames,
    LCID lcid, DISPID* rgdispid) { return E_NOTIMPL ; }
  STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid,
    LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
    EXCEPINFO* pexcepinfo, UINT* puArgErr)
  {
    if( dispidMember == DISPID_AMBIENT_DLCONTROL )
    {
      ::VariantInit( pvarResult ) ;
      CComVariant var( c_dwControlFlags, VT_I4 ) ;
      return var.Detach( pvarResult ) ;
    }
    return DISP_E_MEMBERNOTFOUND ;
  }
};

まず、クラスの生成

 const DWORD DLCTL_DLIMAGES                          = 0x00000010,
 DLCTL_VIDEOS                            = 0x00000020,
 DLCTL_BGSOUNDS                          = 0x00000040,
 DLCTL_NO_SCRIPTS                        = 0x00000080,
 DLCTL_NO_JAVA                           = 0x00000100,
 DLCTL_NO_RUNACTIVEXCTLS                 = 0x00000200,
 DLCTL_NO_DLACTIVEXCTLS                  = 0x00000400,
 DLCTL_DOWNLOADONLY                      = 0x00000800,
 DLCTL_NO_FRAMEDOWNLOAD                  = 0x00001000,
 DLCTL_RESYNCHRONIZE                     = 0x00002000,
 DLCTL_PRAGMA_NO_CACHE                   = 0x00004000,
 DLCTL_NO_BEHAVIORS                      = 0x00008000,
 DLCTL_NO_METACHARSET                    = 0x00010000,
 DLCTL_URL_ENCODING_DISABLE_UTF8         = 0x00020000,
 DLCTL_URL_ENCODING_ENABLE_UTF8          = 0x00040000,
 DLCTL_NOFRAMES                          = 0x00080000,
 DLCTL_FORCEOFFLINE                      = 0x10000000,
 DLCTL_NO_CLIENTPULL                     = 0x20000000,
 DLCTL_SILENT                            = 0x40000000,
 DLCTL_OFFLINEIFNOTCONNECTED             = 0x80000000,
 DLCTL_OFFLINE                           = 0x80000000;

#define DISPID_AMBIENT_DLCONTROL (-5512)
CMyAmbientDispatch m_MyAmbientDispatch;

定義とか。

    BEGIN_MSG_MAP(CMainFrame)
        MESSAGE_HANDLER(WM_CREATE, OnCreate)
    END_MSG_MAP()

LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
        RECT rect;
        GetClientRect(&rect);
        m_hWndClient = m_ax.Create(m_hWnd, rcDefault,
            _T("Shell.Explorer.2"),
        WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE, IDC_IE);
        m_ax.QueryControl(&punkIE);
//UserAgent 変更
        char USERAGENT[512]="Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)";
        UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, USERAGENT, lstrlenA(USERAGENT), 0);
        CComPtr<IAxWinAmbientDispatchEx> adex;
        m_ax.QueryHost(&adex);
        CComQIPtr<IAxWinAmbientDispatch> spWinAmb(adex);
//右クリック禁止
        spWinAmb->put_AllowContextMenu(VARIANT_FALSE);
        adex->SetAmbientDispatch(&m_MyAmbientDispatch);

        AtlAdviseSinkMap(this, true);
        if(pFrameDisp){
            pFrameDisp->Release();
        }
        pFrameDisp=NULL;
        if(punkIE){
            IOleControl *pOC;
//書き換えたことを一応通知
      &
nbsp;     punkIE->QueryInterface( IID_IOleControl, (LPVOID*)&pOC );
            if(pOC){
                pOC->OnAmbientPropertyChange(DISPID_AMBIENT_DLCONTROL);
            }
        }       
        CMessageLoop* pLoop = _Module.GetMessageLoop();
        if(pLoop){
            pLoop->AddMessageFilter(this);
            pLoop->AddIdleHandler(this);
        }
        return 0;
    }

CONTEXTMENU (右クリック) の禁止だけなら実は簡単に実装できた・ω・;

WebBrowser コントロール の AmbientDispatch の実装メモ

WebBrowser コンポーネントの dwControlFlags (DISPID_AMBIENT_DLCONTROL) の実装(簡単に説明すると、Internet Explorer コンポーネントにJavaScript実行禁止/画像表示禁止/Java実行禁止/オフラインモード/ActiveX実行禁止などのフラグを設定する機能)。いろいろなサイトに質問はあるものの、 VC++に実装するためのコードがどこにもなくて苦労したのでメモ ・ω・

結局ロシアの人のコードを参考に書き換えました

class CMyAmbientDispatch : public IDispatch
{
  const int c_dwControlFlags;
public:
// コンストラクタで Flag初期化してる
  CMyAmbientDispatch()
  : c_dwControlFlags( DLCTL_DLIMAGES  | DLCTL_BGSOUNDS|  DLCTL_VIDEOS  | DLCTL_NO_JAVA | DLCTL_NO_RUNACTIVEXCTLS | DLCTL_NO_DLACTIVEXCTLS)
  {
  }
  STDMETHOD(QueryInterface)(REFIID iid, void** ppvObj) { return E_NOTIMPL ; }
  STDMETHOD_(ULONG, AddRef)() { return 1; }
  STDMETHOD_(ULONG, Release)() { return 1; }
  STDMETHOD(GetTypeInfoCount)(UINT* pctinfo) { return E_NOTIMPL ; }
  STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) { return E_NOTIMPL ; }
  STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames,
    LCID lcid, DISPID* rgdispid) { return E_NOTIMPL ; }
  STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid,
    LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
    EXCEPINFO* pexcepinfo, UINT* puArgErr)
  {
    if( dispidMember == DISPID_AMBIENT_DLCONTROL )
    {
      ::VariantInit( pvarResult ) ;
      CComVariant var( c_dwControlFlags, VT_I4 ) ;
      return var.Detach( pvarResult ) ;
    }
    return DISP_E_MEMBERNOTFOUND ;
  }
};

まず、クラスの生成

 const DWORD DLCTL_DLIMAGES                          = 0x00000010,
 DLCTL_VIDEOS                            = 0x00000020,
 DLCTL_BGSOUNDS                          = 0x00000040,
 DLCTL_NO_SCRIPTS                        = 0x00000080,
 DLCTL_NO_JAVA                           = 0x00000100,
 DLCTL_NO_RUNACTIVEXCTLS                 = 0x00000200,
 DLCTL_NO_DLACTIVEXCTLS                  = 0x00000400,
 DLCTL_DOWNLOADONLY                      = 0x00000800,
 DLCTL_NO_FRAMEDOWNLOAD                  = 0x00001000,
 DLCTL_RESYNCHRONIZE                     = 0x00002000,
 DLCTL_PRAGMA_NO_CACHE                   = 0x00004000,
 DLCTL_NO_BEHAVIORS                      = 0x00008000,
 DLCTL_NO_METACHARSET                    = 0x00010000,
 DLCTL_URL_ENCODING_DISABLE_UTF8         = 0x00020000,
 DLCTL_URL_ENCODING_ENABLE_UTF8          = 0x00040000,
 DLCTL_NOFRAMES                          = 0x00080000,
 DLCTL_FORCEOFFLINE                      = 0x10000000,
 DLCTL_NO_CLIENTPULL                     = 0x20000000,
 DLCTL_SILENT                            = 0x40000000,
 DLCTL_OFFLINEIFNOTCONNECTED             = 0x80000000,
 DLCTL_OFFLINE                           = 0x80000000;

#define DISPID_AMBIENT_DLCONTROL (-5512)
CMyAmbientDispatch m_MyAmbientDispatch;

定義とか。

    BEGIN_MSG_MAP(CMainFrame)
        MESSAGE_HANDLER(WM_CREATE, OnCreate)
    END_MSG_MAP()

LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
        RECT rect;
        GetClientRect(&rect);
        m_hWndClient = m_ax.Create(m_hWnd, rcDefault,
            _T("Shell.Explorer.2"),
        WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE, IDC_IE);
        m_ax.QueryControl(&punkIE);
//UserAgent 変更
        char USERAGENT[512]="Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)";
        UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, USERAGENT, lstrlenA(USERAGENT), 0);
        CComPtr<IAxWinAmbientDispatchEx> adex;
        m_ax.QueryHost(&adex);
        CComQIPtr<IAxWinAmbientDispatch> spWinAmb(adex);
//右クリック禁止
        spWinAmb->put_AllowContextMenu(VARIANT_FALSE);
        adex->SetAmbientDispatch(&m_MyAmbientDispatch);

        AtlAdviseSinkMap(this, true);
        if(pFrameDisp){
            pFrameDisp->Release();
        }
        pFrameDisp=NULL;
        if(punkIE){
            IOleControl *pOC;
//書き換えたことを一応通知
      &
nbsp;     punkIE->QueryInterface( IID_IOleControl, (LPVOID*)&pOC );
            if(pOC){
                pOC->OnAmbientPropertyChange(DISPID_AMBIENT_DLCONTROL);
            }
        }       
        CMessageLoop* pLoop = _Module.GetMessageLoop();
        if(pLoop){
            pLoop->AddMessageFilter(this);
            pLoop->AddIdleHandler(this);
        }
        return 0;
    }

CONTEXTMENU (右クリック) の禁止だけなら実は簡単に実装できた・ω・;

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です