Link to home
Start Free TrialLog in
Avatar of trung85gn
trung85gn

asked on

Could you help me to create an Internet Explorer Toolbar using BHO (Browser Helper Object)

First, I try to search all over codeproject and msdn. I found:
codeproject.com:
deskband;
rdeskband;
montley fool toolbar;

msdn:
kbbar => error in UrlEscape
newkbbar => cannot cmpile and it is not a Unmanaged C++

But, none of that using only ATL, I wanna to develope a project in ATL (unmanaged C++) in VC++ 2005.
Anyone help me with sampe source code? Thanks so much
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Read this...

http://msdn2.microsoft.com/en-us/library/bb250436.aspx

Everything you'll every need to know about writing Browser Helper Objects! Knowing a little COM wouldn't hurt either!
Avatar of trung85gn
trung85gn

ASKER

I used to try it. But how can I add a button and menu to it. It hasn't got a GUI.
The major problems is:
1. Creat a toolbar with some button and menu on it
2. when i click a button, it'll call a function
3. Toolbar must a BHO.
ASKER CERTIFIED SOLUTION
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
OKIE, Thanks a lot!!
Best regard.
You are very welcome :)
Some problems are:

I create the BHODemo like that: http://msdn2.microsoft.com/en-us/library/Bb250489.aspx

After i have a worked BHO, i add the toolbar on it by using:
http://msdn2.microsoft.com/en-gb/library/bb776819.aspx
and do following steps:
1.Implement the functions needed by the DLL.
2. Implement the required COM interfaces.
3.Implement any desired optional COM interfaces.

class ATL_NO_VTABLE CMyBHO :
      public CComObjectRootEx<CComSingleThreadModel>,
      public CComCoClass<CMyBHO, &CLSID_MyBHO>,
      
public IDeskBand,
public IPersistStream,
public IObjectWithSiteImpl<CMyBHO>,
      public IDispatchImpl<IMyBHO, &IID_IMyBHO, &LIBID_BHODemoLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
      public IDispEventImpl<1, CMyBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>


AND: add to the header

BEGIN_COM_MAP(CMyBHO)
      COM_INTERFACE_ENTRY(IMyBHO)
      COM_INTERFACE_ENTRY(IDispatch)
      COM_INTERFACE_ENTRY(IObjectWithSite)
      
      COM_INTERFACE_ENTRY_IID(IID_IDockingWindow, IDockingWindow)
      COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
      COM_INTERFACE_ENTRY(IOleWindow)
      COM_INTERFACE_ENTRY(IPersist)
      COM_INTERFACE_ENTRY(IPersistStream)

END_COM_MAP()

after that, implement all function in that interface: (follow http://msdn2.microsoft.com/en-gb/library/bb776819.aspx)

but I can display my toolbar, how can i fix that, please help me, evilrix!  thanks so much...
// MyBHO.h : Declaration of the CMyBHO
#pragma once
#include "resource.h"       // main symbols

#include "shobjidl.h"
#include "shlobj.h"

#include "BHODemo.h"
// Step1: Must include
#include <shlguid.h>     // IID_IWebBrowser2, DIID_DWebBrowserEvents2, etc.
// Step8: Xu ly event
#include <exdispid.h> // DISPID_DOCUMENTCOMPLETE, etc.
// Step 14: xu ly cac event DOM
#include <mshtml.h>         // DOM interfaces



#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif



// CMyBHO

class ATL_NO_VTABLE CMyBHO :
      public CComObjectRootEx<CComSingleThreadModel>,
      public CComCoClass<CMyBHO, &CLSID_MyBHO>,
      public IDeskBand,
      public IPersistStream,
      public IObjectWithSiteImpl<CMyBHO>,
      public IDispatchImpl<IMyBHO, &IID_IMyBHO, &LIBID_BHODemoLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
      // Step 9: Xu ly skien IDispatch
      public IDispEventImpl<1, CMyBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>

{
public:
      CMyBHO()
      {
      }


DECLARE_REGISTRY_RESOURCEID(IDR_MYBHO)

DECLARE_NOT_AGGREGATABLE(CMyBHO)

BEGIN_COM_MAP(CMyBHO)
      COM_INTERFACE_ENTRY(IMyBHO)
      COM_INTERFACE_ENTRY(IDispatch)
      COM_INTERFACE_ENTRY(IObjectWithSite)
      
      COM_INTERFACE_ENTRY_IID(IID_IDockingWindow, IDockingWindow)
      COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
      COM_INTERFACE_ENTRY(IOleWindow)
      COM_INTERFACE_ENTRY(IPersist)
      COM_INTERFACE_ENTRY(IPersistStream)

END_COM_MAP()



      DECLARE_PROTECT_FINAL_CONSTRUCT()

      HRESULT FinalConstruct()
      {
            return S_OK;
      }

      void FinalRelease()
      {
      }
//////////////////////////////////////////////////////////////////////////
      // IDeskBand
public:
      STDMETHOD(GetBandInfo)(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi);

      // IOleWindow
public:
      STDMETHOD(GetWindow)(HWND* phwnd);
      STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode);

      // IDockingWindow
public:
      STDMETHOD(CloseDW)(unsigned long dwReserved);
      STDMETHOD(ResizeBorderDW)(const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved);
      STDMETHOD(ShowDW)(BOOL fShow);

      // IPersist
public:
      STDMETHOD(GetClassID)(CLSID *pClassID);

      // IPersistStream
public:
      STDMETHOD(IsDirty)(void);
      STDMETHOD(Load)(IStream *pStm);
      STDMETHOD(Save)(IStream *pStm, BOOL fClearDirty);
      STDMETHOD(GetSizeMax)(ULARGE_INTEGER *pcbSize);

//////////////////////////////////////////////////////////////////////////
public:
//Step2: Declare Setsite
STDMETHOD(SetSite)(IUnknown *pUnkSite);
STDMETHOD(GetSite)(REFIID riid, void **ppvSite);

// Step 10:Them xu ly skien OnDocumentComplete
BEGIN_SINK_MAP(CMyBHO)
    SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
END_SINK_MAP()

    // DWebBrowserEvents2
    void STDMETHODCALLTYPE OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL);


//Step3: add private
private:
    CComPtr<IWebBrowser2>  m_spWebBrowser;

      // Step 11:
      BOOL m_fAdvised;

      // Step 15:
      void RemoveImages(IHTMLDocument2 *pDocument);

//////////////////////////////////////////////////////////////////////////
protected:
      BOOL RegisterAndCreateWindow();
protected:
      DWORD m_dwBandID;
      DWORD m_dwViewMode;
      BOOL m_bShow;
      BOOL m_bEnterHelpMode;
      HWND m_hWndParent;
      HWND m_hWnd;
      IInputObjectSite *m_pSite;

//////////////////////////////////////////////////////////////////////////
};

OBJECT_ENTRY_AUTO(__uuidof(MyBHO), CMyBHO)
// MyBHO.cpp : Implementation of CMyBHO

#include "stdafx.h"
#include "MyBHO.h"
#include <string.h>
#include <wchar.h>
const WCHAR TITLE_CWkToolBand[] = L"CWkToolBand";
//////////////////////////////////////////////////////////////////////////
///
//Tao thanh cong cu
BOOL CMyBHO::RegisterAndCreateWindow()
{
      RECT rect;
      ::GetClientRect(m_hWndParent, &rect);

      //
      // TODO: Replace with your implementation
      //

      m_hWnd = ::CreateWindow(TEXT("STATIC"),
            TEXT("The CWkToolBand DeskBand"),
            WS_CHILD | WS_VISIBLE | SS_CENTER,
            rect.left, rect.top,
            rect.right - rect.left,
            rect.bottom - rect.top,
            m_hWndParent,
            NULL,
            NULL,
            NULL);
      return ::IsWindow(m_hWnd);
}

//////////////////////////////////////////////////////////////////////////
// HAM LAY TU MSDN
//STDMETHODIMP CExplorerBar::GetBandInfo(DWORD dwBandID, DWORD dwViewMode,
//                                                         DESKBANDINFO *pdbi)
//{
//      if(pdbi)
//      {
//            m_dwBandID = dwBandID;
//            m_dwViewMode = dwViewMode;
//
//            if(pdbi->dwMask & DBIM_MINSIZE)
//            {
//                  pdbi->ptMinSize.x = MIN_SIZE_X;
//                  pdbi->ptMinSize.y = MIN_SIZE_Y;
//            }
//
//            if(pdbi->dwMask & DBIM_MAXSIZE)
//            {
//                  pdbi->ptMaxSize.x = -1;
//                  pdbi->ptMaxSize.y = -1;
//            }
//
//            if(pdbi->dwMask & DBIM_INTEGRAL)
//            {
//                  pdbi->ptIntegral.x = 1;
//                  pdbi->ptIntegral.y = 1;
//            }
//
//            if(pdbi->dwMask & DBIM_ACTUAL)
//            {
//                  pdbi->ptActual.x = 0;
//                  pdbi->ptActual.y = 0;
//            }
//
//            if(pdbi->dwMask & DBIM_TITLE)
//            {
//                  hr = StringCbCopyW(pdbi->wszTitle, sizeof(pdbi->wszTitle), L"Sample Explorer Bar");
//                  // TODO: Add error handling code here to check the hr return value.
//            }
//
//            if(pdbi->dwMask & DBIM_MODEFLAGS)
//            {
//                  pdbi->dwModeFlags = DBIMF_VARIABLEHEIGHT;
//            }
//
//            if(pdbi->dwMask & DBIM_BKCOLOR)
//            {
//                  //Use the default background color by removing this flag.
//                  pdbi->dwMask &= ~DBIM_BKCOLOR;
//            }
//
//            return S_OK;
//      }
//
//      return E_INVALIDARG;
//}

//////////////////////////////////////////////////////////////////////////


// IDeskBand
STDMETHODIMP CMyBHO::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi)
{
      m_dwBandID = dwBandID;
      m_dwViewMode = dwViewMode;

      if (pdbi)
      {
            if (pdbi->dwMask & DBIM_MINSIZE)
            {
                  pdbi->ptMinSize.x = 250;
                  pdbi->ptMinSize.y = 20;
            }
            if (pdbi->dwMask & DBIM_MAXSIZE)
            {
                  pdbi->ptMaxSize.x = 0; // ignored
                  pdbi->ptMaxSize.y = -1;      // width
            }
            if (pdbi->dwMask & DBIM_INTEGRAL)
            {
                  pdbi->ptIntegral.x = 1; // ignored
                  pdbi->ptIntegral.y = 1; // not sizeable
            }
            if (pdbi->dwMask & DBIM_ACTUAL)
            {
                  pdbi->ptActual.x = 250;
                  pdbi->ptActual.y = 20;
            }
            if (pdbi->dwMask & DBIM_TITLE)
            {
                  wcscpy(pdbi->wszTitle, TITLE_CWkToolBand);
            }
            if (pdbi->dwMask & DBIM_BKCOLOR)
            {
                  //Use the default background color by removing this flag.
                  pdbi->dwMask &= ~DBIM_BKCOLOR;
            }
            if (pdbi->dwMask & DBIM_MODEFLAGS)
            {
                  pdbi->dwModeFlags = DBIMF_VARIABLEHEIGHT;
            }
      }
      return S_OK;
}

// IOleWindow
STDMETHODIMP CMyBHO::GetWindow(HWND* phwnd)
{
      HRESULT hr = S_OK;
      if (NULL == phwnd)
      {
            hr = E_INVALIDARG;
      }
      else
      {
            *phwnd = m_hWnd;
      }
      return hr;
}

STDMETHODIMP CMyBHO::ContextSensitiveHelp(BOOL fEnterMode)
{
      m_bEnterHelpMode = fEnterMode;
      return S_OK;
}

// IDockingWindow
STDMETHODIMP CMyBHO::CloseDW(unsigned long dwReserved)
{
      if (::IsWindow(m_hWnd))
      {
            ::DestroyWindow(m_hWnd);
      }
      return S_OK;
}

STDMETHODIMP CMyBHO::ResizeBorderDW(const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved)
{
      // Not used by any band object.
      return E_NOTIMPL;
}

STDMETHODIMP CMyBHO::ShowDW(BOOL fShow)
{
      HRESULT hr = S_OK;
      m_bShow = fShow;
      ShowWindow(m_hWnd, m_bShow ? SW_SHOW : SW_HIDE);
      return hr;
}

// IPersist
STDMETHODIMP CMyBHO::GetClassID(CLSID *pClassID)
{

      //CHU Y NHO THAY CLSID
      *pClassID = CLSID_MyBHO;
      return S_OK;
}

// IPersistStream
STDMETHODIMP CMyBHO::IsDirty(void)
{
      return S_FALSE;
}

STDMETHODIMP CMyBHO::Load(IStream *pStm)
{
      return S_OK;
}

STDMETHODIMP CMyBHO::Save(IStream *pStm, BOOL fClearDirty)
{
      return S_OK;
}

STDMETHODIMP CMyBHO::GetSizeMax(ULARGE_INTEGER *pcbSize)
{
      return E_NOTIMPL;
}


//////////////////////////////////////////////////////////////////////////
/* OLD SetSite func

STDMETHODIMP CMyBHO::SetSite(IUnknown* pUnkSite)
{
    if (pUnkSite != NULL)
    {
        // Cache the pointer to IWebBrowser2.
        pUnkSite->QueryInterface(IID_IWebBrowser2, (void**)&m_spWebBrowser);
    }
    else
    {
        // Release cached pointers and other resources here.
        m_spWebBrowser.Release();
    }

    // Return the base class implementation
      return IObjectWithSiteImpl<CMyBHO>::SetSite(pUnkSite);
}
*/


STDMETHODIMP CMyBHO::SetSite(IUnknown* pUnkSite)
{
      //If a site is being held, release it.
      if(m_pSite)
      {
            m_pSite->Release();
            m_pSite = NULL;
      }

      //If punkSite is not NULL, a new site is being set.
      if(pUnkSite)
      {

            if(SUCCEEDED(pUnkSite->QueryInterface(IID_IInputObjectSite, (LPVOID*)&m_pSite)))
            {
                  return S_OK;
            }  
            return E_FAIL;



            //Get the parent window.
            IOleWindow  *pOleWindow = NULL;

            m_hWndParent = NULL;

            if(SUCCEEDED(pUnkSite->QueryInterface(IID_IOleWindow, (LPVOID*)&pOleWindow)))
            {
                  pOleWindow->GetWindow(&m_hWndParent);
                  pOleWindow->Release();
            }

            if(!::IsWindow(m_hWndParent))
                  return E_FAIL;

            if(!RegisterAndCreateWindow())
                  return E_FAIL;

            //Get and keep the IInputObjectSite pointer.
            if(SUCCEEDED(pUnkSite->QueryInterface(IID_IInputObjectSite, (LPVOID*)&m_pSite)))
            {
                  return S_OK;
            }  
            return E_FAIL;
      }
      return S_OK;
}

//STDMETHODIMP CMyBHO::SetSite(IUnknown* pUnkSite)
//{
//      //If a site is being held, release it.
//
//      if (pUnkSite != NULL)
//    {
//            
//            //////////////////////////////////////////////////////////////////////////
//            
//            //Get the parent window.
//            //TAO TOOL BAR
//            
//            if(SUCCEEDED(pUnkSite->QueryInterface(IID_IInputObjectSite, (LPVOID*)&m_pSite)))
//            {
//                  return S_OK;
//            }  
//            return E_FAIL;
//
//
//            IOleWindow  *pOleWindow = NULL;
//
//            m_hWndParent = NULL;
//            if(SUCCEEDED(pUnkSite->QueryInterface(IID_IOleWindow, (LPVOID*)&pOleWindow)))
//            {
//                  pOleWindow->GetWindow(&m_hWndParent);
//                  pOleWindow->Release();
//            }
//
//            if(!::IsWindow(m_hWndParent))
//                  return E_FAIL;
//
//            if(!RegisterAndCreateWindow())
//                  return E_FAIL;
//            MessageBox(m_hWndParent, L"chay den day roi", L"BHO", MB_OK);
//            //////////////////////////////////////////////////////////////////////////
//        // Cache the pointer to IWebBrowser2.
//        HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void **)&m_spWebBrowser);
//        if (SUCCEEDED(hr))
//        {
//            // Register to sink events from DWebBrowserEvents2.
//            hr = DispEventAdvise(m_spWebBrowser);
//            if (SUCCEEDED(hr))
//            {
//                m_fAdvised = TRUE;
//            }
//        }
//    }
//    else
//    {
//        // Unregister event sink.
//        if (m_fAdvised)
//        {
//            DispEventUnadvise(m_spWebBrowser);
//            m_fAdvised = FALSE;
//        }
//
//        // Release cached pointers and other resources here.
//        m_spWebBrowser.Release();
//    }
//
//    // Call base class implementation.
//    return IObjectWithSiteImpl<CMyBHO>::SetSite(pUnkSite);
//}
//
//
//STDMETHODIMP CMyBHO::GetSite(REFIID riid, void **ppvSite)
//{
//      *ppvSite = NULL;
//
//      if(m_pSite)
//      {
//            return m_pSite->QueryInterface(riid, ppvSite);
//      }
//      return E_FAIL;
//}

void STDMETHODCALLTYPE CMyBHO::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
{
    // Retrieve the top-level window from the site.
    HWND hwnd;
    HRESULT hr = m_spWebBrowser->get_HWND((LONG_PTR*)&hwnd);
    if (SUCCEEDED(hr))
    {
        // Output a message box when page is loaded.
        MessageBox(hwnd, L"Hello MyBHO", L"BHO", MB_OK);
    }
}




Noone there?? 500 points watting for YOU!
Hi,

For this to work all the various COM objects need registering. I take it you have done all the necessary to ensure this happens? Read the section entitled "Band Registration".

TBH: I doubt I can really help much more on this. The is a complex subject and to say "it doesn't work why not" isn't really something I can answer.  If you can refine your questions to be more specific then I can try and help. I'm sorry I can't be more help -- maybe someone else can be?

-Rx.
Thanks, I try to create the toolbar but unsuccessful.
Firstly : I created a BHO: following steps in "Building Browser Helper Objects with Visual Studio 2005" on MSDN. It works fine!

Secondly: I try to create a GUI for this BHO following steps in "Creating Custom Explorer Bars, Tool Bands, and Desk Bands" but it does not appear!
Please help me to create GUI for this BHO (2 buttons on Internet Explorer, when press button it'll call the function in BHO)