Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

BHO (Browser Helper Objects)

17K
07 октября 2006 года
sax0n
6 / / 07.10.2006
Привет, All.
У меня возникла проблема при написании сабжа (Browser Helper Objects), которую нужно решить в кратчайшие сроки.
Цель — написать плагин для IExplorer'a, который отслеживал бы события браузера (а именно событие BeforeNavigate).
К сожелению, опыта в разработке COM очень мало. Материала в интернете не очень много, а примеров еще меньше (
Основной материал — МСДН (http://msdn.microsoft.com/library/en-us/IETechCol/dnwebgen/bho.asp?frame=true).
Ниже будет приведено содержание модулей. Хотелось бы, чтобы ЗНАЮЩИЕ оценили и сделали замечания.
На данном этапе главная проблема — при создании класса CIEClass, 1) вызывается AddRef, 2) Release, 1) вызывается Release() CIEClassFactory, после чего модуль вызывает сбой браузера.

Теоретически, после шага 1 должен вызываться метод SetSite, в котором я получаю указатель на элемент браузера и активирую прослушивание его событий.
А теперь внимание вопросы
1. почему не вызывается метод SetSite
2. почему при выгружении модуля браузер "падает"
3. как проследить за освобождением памяти.

Заранее ОГРОМНОЕ спасибо.

*Условие задачи — не использовать дополнительных библиотек (STL, ATL), Visual Studio 6.
Вот содержание модулей:
Код:
//MainModule.cpp — главный модуль

#include <windows.h>
#include "IEClassFactory.h"

#include "debug.h"

extern WORD g_nSrvRefCount=0;


bool CanUnload = true;

BOOL WINAPI DllMain(HINSTANCE instance, DWORD fdwReason, LPVOID lpvReserved)
{
return TRUE;
}

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
debug("DllGetClassObject");

if (!ppv)
return E_INVALIDARG;

*ppv=NULL;
HRESULT hr=E_FAIL;

CIEClassFactory *pObj=new CIEClassFactory;
if (!pObj)
return E_OUTOFMEMORY;

hr=pObj->QueryInterface(riid, ppv);

if (FAILED(hr))
{
debug("getclass error");
delete pObj;
return CLASS_E_CLASSNOTAVAILABLE;
}
return S_OK;
}

STDAPI DllCanUnloadNow(void)
{
debug("DllCanUnloadNow");
if(g_nSrvRefCount)
return S_FALSE;
else
return S_OK;
}
//////////////////-----------------------------------------


Код:
//IEClassFactory.h
#include "unknwn.h"

class CIEClassFactory: public IClassFactory
{
protected:
long m_lRef;
public:
CIEClassFactory();
~CIEClassFactory();

HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void** ppv);
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
HRESULT STDMETHODCALLTYPE CreateInstance(LPUNKNOWN pUnk, REFIID riid, void** ppv);
HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock) ;
};
//////////////////-----------------------------------------

Код:
//IEClassFactory.cpp
#include "IEClassFactory.h"
#include "debug.h"
#include "IEClass.h"

extern WORD g_nSrvRefCount;

CIEClassFactory::CIEClassFactory()
{
m_lRef = 0;
}

CIEClassFactory::~CIEClassFactory()
{
debug("IEClassFactory ~");

}

HRESULT STDMETHODCALLTYPE CIEClassFactory::QueryInterface (REFIID riid, void** ppv)
{
debug("IEClassFactory QueryInterface");
if (!ppv)
return E_INVALIDARG;

*ppv=NULL;

if (riid == IID_IUnknown)
*ppv=(IUnknown*)this;
else if (riid == IID_IClassFactory)
*ppv=(IClassFactory*)this;

if (*ppv)
{
debug("IEClassFactory QueryInterface AddRef");
AddRef();
return S_OK;
}

debug("IEClassFactory QueryInterface error");
return E_NOINTERFACE;
}

ULONG STDMETHODCALLTYPE CIEClassFactory::AddRef()
{
debug("IEClassFactory AddRef");
g_nSrvRefCount++;
return ++m_lRef;
}

ULONG STDMETHODCALLTYPE CIEClassFactory::Release()
{
debug("IEClassFactory Release");
g_nSrvRefCount--;
if (!--m_lRef)
{
delete this;
return 0;
}
else return m_lRef;
}

HRESULT STDMETHODCALLTYPE CIEClassFactory::CreateInstance(LPUNKNOWN pUnk, REFIID riid, void** ppv)
{
debug("IEClassFactory CreateInstance");

if (!ppv)
{
debug("IEClassFactory CreateInstance E_INVALIDARG");
return E_INVALIDARG;
}
if (pUnk)
{
debug("IEClassFactory CreateInstance CLASS_E_NOAGGREGATION");
return CLASS_E_NOAGGREGATION;
}

*ppv=NULL;
HRESULT hr=E_NOINTERFACE;

CIEClass *pExt=new CIEClass;
if (!pExt)
return E_OUTOFMEMORY;

hr=pExt->QueryInterface(riid, ppv);
if (SUCCEEDED(hr))
{
debug("IEClassFactory CreateInstance OK");
return S_OK;
}

debug("IEClassFactory CreateInstance delete");
delete pExt;
return hr;
}

HRESULT STDMETHODCALLTYPE CIEClassFactory::LockServer(BOOL fLock)
{
debug("IEClassFactory LockServer");
if (fLock)
g_nSrvRefCount++;
else
g_nSrvRefCount--;
return S_OK;

}
//-----------------------------------------------

Код:
//IEClass.h
#include "exdisp.h"

class CIEClass: public IObjectWithSite, public IDispatch
{

int m_nRefCount;
public:
CIEClass();
~CIEClass();
HRESULT Connect();

ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, //Identifier of the requested interface
void ** ppvObject);

HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void** ppvSite);
HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite);

HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int FAR* pctinfo);
HRESULT STDMETHODCALLTYPE GetTypeInfo(unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo);
HRESULT STDMETHODCALLTYPE GetIDsOfNames(
REFIID riid,
OLECHAR FAR* FAR* rgszNames,
unsigned int cNames,
LCID lcid,
DISPID FAR* rgDispId
);
HRESULT STDMETHODCALLTYPE Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS FAR* pDispParams,
VARIANT FAR* pVarResult,
EXCEPINFO FAR* pExcepInfo,
unsigned int FAR* puArgErr
);



private:
IDispatch* document_;
IWebBrowser2* webBrowser;
IConnectionPointContainer* connectionPointContainer;
unsigned long cookie;


};
//------------------------------------------------

Код:
//IEClass.cpp
#include "IEClass.h"
#include "debug.h"

extern WORD g_nSrvRefCount;

CIEClass::CIEClass()
{
m_nRefCount = 0;
}

CIEClass::~CIEClass()
{
debug("CIEClass ~");

}

STDMETHODIMP CIEClass::GetSite(REFIID riid, void** ppvSite)
{
debug("CIEClass GetSite");
return 0;
}

STDMETHODIMP CIEClass::SetSite(IUnknown *pUnkSite)
{
debug("CIEClass SetSite");
//до вызова дело даже не доходит
return S_OK;
}

ULONG STDMETHODCALLTYPE CIEClass::AddRef()
{
debug("CIEClass AddRef");
g_nSrvRefCount++;
return ++m_nRefCount;
}


ULONG STDMETHODCALLTYPE CIEClass::Release()
{
debug("CIEClass Release");
g_nSrvRefCount--;
if (!--m_nRefCount)
{
debug("CIEClass Release delete");
delete this;
return 0;
}
else return m_nRefCount;
}

STDMETHODIMP CIEClass::QueryInterface(REFIID iid, void ** ppvObject)
{
debug("CIEClass QueryInterface");

if(IID_IWebBrowser2 == iid)
{
debug("IID_IWebBrowser2");
*ppvObject = (IWebBrowser2*)this;
}
else if(IID_IObjectWithSite == iid)
{
debug("IID_IObjectWithSite");
*ppvObject = (IObjectWithSite*)this;
} else
if(IID_IClassFactory == iid)
{
debug("IID_IClassFactory");
*ppvObject = (IClassFactory*)this;
}
else
{
debug("E_NOINTERFACE");
return E_NOINTERFACE;
}

return 0;
}

STDMETHODIMP CIEClass::GetTypeInfoCount(unsigned int FAR* pctinfo)
{
debug("CIEClass GetTypeInfoCount");
return 0;
}

STDMETHODIMP CIEClass::GetTypeInfo(unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo)
{
debug("CIEClass GetTypeInfo");
return 0;
}

STDMETHODIMP CIEClass::GetIDsOfNames(
REFIID riid,
OLECHAR FAR* FAR* rgszNames,
unsigned int cNames,
LCID lcid,
DISPID FAR* rgDispId
)
{
debug("CIEClass GetIDsOfNames");
return 0;
}

STDMETHODIMP CIEClass::Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS FAR* pDispParams,
VARIANT FAR* pVarResult,
EXCEPINFO FAR* pExcepInfo,
unsigned int FAR* puArgErr
)
{
debug("CIEClass Invoke");
return 0;
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог