Новичок
Профиль
Группа: Участник
Сообщений: 12
Регистрация: 1.8.2007
Репутация: нет Всего: нет
|
Проблема решена. К CPPWebBrowser цепляется обработчик событий onScroll. Который отслеживает положение полос прокрутки, положение и размер тегов img на html-форме Код | (<img src="none.jpg" width="xxx" height="xxx">) |
. Изображение выводится на TImage (сам TImage расположен на TPanel для отображения поверх CPPWebBrowser). Обработчик события прокрутки устанавливает расположение TPanel согласно полосе прокрутки. Весь код приводить не буду, покажу только как цеплять обработчик и как получать параметры img и позицию скрола. WEBBrowser.h Код | #ifndef UWEBBrowserH #define UWEBBrowserH //---------------------------------------------------------------------------
#include "Utils.h" // Собственная библиотека с элементарными функциями
#include <string.h> #include <string> #include <comutil.h>
#include <Forms.hpp> #include "SHDocVw_OCX.h" #include <Menus.hpp> #include <OleCtrls.hpp> #include <HTTPApp.hpp> #include "mshtmhst.h" #include "mshtml.h" //---------------------------------------------------------------------------
using namespace std; //---------------------------------------------------------------------------
//! Определение функции для обрабутки события прокрутки окна typedef void (*cOnScroll)(); //---------------------------------------------------------------------------
//! Класс для обработки событий броузера class THtmlEventSink : public IDispatch { protected: static long m_cRef; //! Количество активных ссылок
public: cOnScroll OnScroll; //! Функция для обрабутки события прокрутки окна
//! Выделяет память под com-объект /*! \param [in] riid - id-требуемого объекта \param [in, out] ppvObject - указатель на возвращаемый объект \return HRESULT - результат выполнения операции */ HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) { *ppvObject = NULL;
if (IsEqualGUID(riid, IID_IUnknown)) *ppvObject = reinterpret_cast<void**>(this);
if (IsEqualGUID(riid, IID_IDispatch)) *ppvObject = reinterpret_cast<void**>(this);
if (*ppvObject) { ((IUnknown*)*ppvObject)->AddRef(); return S_OK; } else return E_NOINTERFACE; }
//! Учет копирования указателя на объект /*! Увеличивает счетчик объектов \return DWORD - количество объектов */ DWORD __stdcall AddRef() { return InterlockedIncrement(&m_cRef); }
//! Учет копирования указателя на объект /*! Уменьшает счетчик объектов \return DWORD - количество объектов */ DWORD __stdcall Release() { if (InterlockedDecrement(&m_cRef) == 0) { delete this; return 0; } return m_cRef; }
STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pctinfo) { return E_NOTIMPL; }
STDMETHOD(GetTypeInfo)(unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo) { return E_NOTIMPL; }
STDMETHOD(GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgDispId) { return S_OK; }
STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr) { if (OnScroll != NULL) OnScroll(); return S_OK; } }; //---------------------------------------------------------------------------
//! Определение указателя на фунцию, обрабатывающую запрос из Web-броузера /*! Возвращает html-код страницы на основе данных из CGI-запроса Web-броузера \param [in] sCGI - CGI-запрос \return string - html-код страницы */ typedef string (__closure *pGetHtmlByCGI) (string sCGI);
class cDebug;
//! Класс для работы с броузером class cWEBBrowser :public IDocHostUIHandler { long lRefCount; //!< Количество открытых ссылок string sHtml; //!< Html-код загружаемой страницы TCppWebBrowser* CPPWebBrowser; //!< Web-броузер pGetHtmlByCGI GetHtmlByCGI; //!< Указатель на фунцию, обрабатывающую запрос из Web-броузера THtmlEventSink HtmlEventSink; //!< Объект, обрабатывающий события броузера cOnScroll OnScroll; //! Функция для обрабутки события прокрутки окна
//! Привязка скрола к элементу html-страницы enum { tsUndefine, //!< Не определено tsHtml, //!< Привязка к тегу Html tsBody //!< Привязка к тегу Body } TypeScroll; bool bHTMLScroll; //!< Флаг проверки скрола у элемента
//! Возвращает данные введенные пользователем /*! Возвращает данные введенные пользователем в виде CGI-строки \return string - CGI-строка с данными введеными пользователем */ string GetData ();
//! Загружает html-код страницы в броузер /*! \param [in] _sHtml - html-код страницы */ LoadHtml (string _sHtml);
//! Устанавливает значение элемента /*! \param [in] sNameEl - имя элемента \param [in] sValueEl - значение элемента */ SetData (string sNameEl, string sValueEl);
public: friend cDebug;
//! Устанавливает функцию обработки события прокрутки /*! \param [in] onScroll - функция обработки события прокрутки */ SetOnScroll (cOnScroll _OnScroll);
//! Возвращает координаты скролов /*! \param [in, out] iLeft, iTop - координаты скрола по горизонтали и вертикали */ GetScrollPos (int *iLeft, int *iTop);
//! Возвращает параметры картинки /*! \param [in] sID - идентификатор картинки \param [in, out] iLeft, iTop - положение картинки \param [in, out] iWidth, iHeight - размеры картинки \warning - Если картинка не найдена на форме html, то все величины равны -1 */ GetImgParams (string sID, int *iLeft, int *iTop, int *iWidth, int *iHeight);
//! Конструктор инициализирующий все члены класса /*! Инициализация lRefCount, CPPWebBrowser, GetHtmlByCGI \param [in] _CPPWebBrowser - броузер типа TCppWebBrowser \param [in] _ButtonClick - указатель на фунцию, обрабатывающую запрос из Web-броузера */ cWEBBrowser (TCppWebBrowser* _CPPWebBrowser, pGetHtmlByCGI _GetHtmlByCGI);
//! Обработка запроса пользователя /*! Запрос пользователя отправляется во внешннюю функцию, которая возвращает html-код следующей страницы */ virtual HRESULT STDMETHODCALLTYPE TranslateUrl( /* [in] */ DWORD dwTranslate, /* [in] */ OLECHAR __RPC_FAR *pchURLIn, /* [out] */ OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut) { sHtml=GetHtmlByCGI(GetData().c_str()); return E_NOTIMPL; }
//! Отображение новой страницы virtual HRESULT STDMETHODCALLTYPE UpdateUI( void) { if (sHtml!="") { LoadHtml(sHtml); sHtml=""; SetOnScroll (OnScroll); OnScroll(); } return E_NOTIMPL; }
//! Обработка popup-меню virtual HRESULT STDMETHODCALLTYPE ShowContextMenu( /* [in] */ DWORD dwID, /* [in] */ POINT __RPC_FAR *ppt, /* [in] */ IUnknown __RPC_FAR *pcmdtReserved, /* [in] */ IDispatch __RPC_FAR *pdispReserved) { return S_OK; }
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID classid, void** intf) { if (classid == IID_IUnknown) *intf = (IUnknown*)this; else if (classid == IID_IDocHostUIHandler) *intf = (IDocHostUIHandler*)this; else return E_NOINTERFACE; return S_OK; }
virtual ULONG STDMETHODCALLTYPE AddRef() { InterlockedIncrement(&lRefCount); return lRefCount; }
virtual ULONG STDMETHODCALLTYPE Release() { InterlockedDecrement(&lRefCount); if (lRefCount == 0) delete this; return lRefCount; }
virtual HRESULT STDMETHODCALLTYPE GetHostInfo( /* [out][in] */ DOCHOSTUIINFO __RPC_FAR *pInfo) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE ShowUI( /* [in] */ DWORD dwID, /* [in] */ IOleInPlaceActiveObject __RPC_FAR *pActiveObject, /* [in] */ IOleCommandTarget __RPC_FAR *pCommandTarget, /* [in] */ IOleInPlaceFrame __RPC_FAR *pFrame, /* [in] */ IOleInPlaceUIWindow __RPC_FAR *pDoc) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE HideUI( void) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE EnableModeless( /* [in] */ BOOL fEnable) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE OnDocWindowActivate( /* [in] */ BOOL fActivate) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivate( /* [in] */ BOOL fActivate) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE ResizeBorder( /* [in] */ LPCRECT prcBorder, /* [in] */ IOleInPlaceUIWindow __RPC_FAR *pUIWindow, /* [in] */ BOOL fRameWindow) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator( /* [in] */ LPMSG lpMsg, /* [in] */ const GUID __RPC_FAR *pguidCmdGroup, /* [in] */ DWORD nCmdID) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE GetOptionKeyPath( /* [out] */ LPOLESTR __RPC_FAR *pchKey, /* [in] */ DWORD dw) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE GetDropTarget( /* [in] */ IDropTarget __RPC_FAR *pDropTarget, /* [out] */ IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE GetExternal( /* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDispatch) { return E_NOTIMPL; }
virtual HRESULT STDMETHODCALLTYPE FilterDataObject( /* [in] */ IDataObject __RPC_FAR *pDO, /* [out] */ IDataObject __RPC_FAR *__RPC_FAR *ppDORet) { return E_NOTIMPL; } }; //---------------------------------------------------------------------------
#endif
|
WEBBrowser.cpp Код | #include "WEBBrowser.h" //---------------------------------------------------------------------------
long THtmlEventSink::m_cRef=0; //---------------------------------------------------------------------------
cWEBBrowser::cWEBBrowser (TCppWebBrowser* _CPPWebBrowser, pGetHtmlByCGI _GetHtmlByCGI) { lRefCount = 1; CPPWebBrowser=_CPPWebBrowser; GetHtmlByCGI=_GetHtmlByCGI; TypeScroll=tsUndefine; OnScroll=NULL; } //---------------------------------------------------------------------------
cWEBBrowser::SetData (string sNameEl, string sValueEl) { LPDISPATCH pDisp=CPPWebBrowser->DefaultDispatch; IWebBrowser2* webBrowser = NULL; // Web-броузер if ( SUCCEEDED(pDisp->QueryInterface(IID_IWebBrowser2, (void**)&webBrowser))&& webBrowser ) { IHTMLDocument2* htmlDocument = NULL; // Страница в Web-броузере if (SUCCEEDED(CPPWebBrowser->Document->QueryInterface(IID_IHTMLDocument2, (void**)&htmlDocument)) && htmlDocument ) { IHTMLElementCollection *pAll = NULL; // Коллекция элементов на странице htmlDocument if ( SUCCEEDED ( htmlDocument -> get_all ( &pAll ) ) && pAll ) { long lCount; // Количество элементов в коллекции pAll pAll->get_length(&lCount); BSTR bstr; for (long i=0; i<lCount; i++) { VARIANT varIndex; varIndex.vt = VT_UINT; varIndex.lVal = i; VARIANT var2; VariantInit( &var2 ); IDispatch* pDisp; if (SUCCEEDED (pAll->item(varIndex, var2, &pDisp)) && pDisp) { IHTMLInputElement* pInputElem=NULL; // Элемент из коллекции pAll if (SUCCEEDED (pDisp->QueryInterface(IID_IHTMLInputElement,(void **)&pInputElem)) && pInputElem) { VARIANT check; check.vt=VT_BOOL; check.boolVal=FALSE; pInputElem->get_type(&bstr); string sType=BSTR2String(bstr); // Тип элемента pInputElem->get_name(&bstr); string sName=BSTR2String(bstr); // Имя элемента if (sName==sNameEl) { if(sType=="checkbox") if (sValueEl=="Select") pInputElem->put_checked(true); else pInputElem->put_checked(false); else pInputElem->put_value(String2BSTR (sValueEl)); break; } pInputElem->Release(); } pDisp -> Release (); } } pAll-> Release (); } htmlDocument -> Release (); } webBrowser->Release(); } } //---------------------------------------------------------------------------
string cWEBBrowser::GetData() { string sRetVal; // Возвращаемое значение
LPDISPATCH pDisp=CPPWebBrowser->DefaultDispatch; IWebBrowser2* webBrowser = NULL; // Web-броузер if ( SUCCEEDED(pDisp->QueryInterface(IID_IWebBrowser2, (void**)&webBrowser))&& webBrowser ) { IHTMLDocument2* htmlDocument = NULL; // Страница в Web-броузере if (SUCCEEDED(CPPWebBrowser->Document->QueryInterface(IID_IHTMLDocument2, (void**)&htmlDocument)) && htmlDocument ) { IHTMLElementCollection *pAll = NULL; // Коллекция элементов на странице htmlDocument if ( SUCCEEDED ( htmlDocument -> get_all ( &pAll ) ) && pAll ) { long lCount; // Количество элементов в коллекции pAll pAll->get_length(&lCount); BSTR bstr; for (long i=0; i<lCount; i++) { VARIANT varIndex; varIndex.vt = VT_UINT; varIndex.lVal = i; VARIANT var2; VariantInit( &var2 ); IDispatch* pDisp; if (SUCCEEDED (pAll->item(varIndex, var2, &pDisp)) && pDisp) { IHTMLInputElement* pInputElem=NULL; // Элемент из коллекции pAll if (SUCCEEDED (pDisp->QueryInterface(IID_IHTMLInputElement,(void **)&pInputElem)) && pInputElem) { VARIANT check; check.vt=VT_BOOL; check.boolVal=FALSE; pInputElem->get_type(&bstr); string sType=BSTR2String(bstr); // Тип элемента pInputElem->get_name(&bstr); string sName=BSTR2String(bstr); // Имя элемента if (sName=="TimeDigits") continue; pInputElem->get_value(&bstr); string sValue=BSTR2String(bstr); // Значение элемента pInputElem->get_checked(&check.boolVal); if(sType=="checkbox") { if (check.boolVal) sRetVal+=sName+"=Select&"; } else sRetVal+=sName+"="+sValue+"&"; pInputElem->Release(); } pDisp -> Release (); } } pAll-> Release (); } htmlDocument -> Release (); } webBrowser->Release(); } if (sRetVal.length()>1) sRetVal.erase(sRetVal.length()-1, 1); // Удаление последнего символа '&' return sRetVal; } //---------------------------------------------------------------------------
cWEBBrowser::LoadHtml (string _sHtml) { string sHtml2=_sHtml; // Затирка мусора long len=sHtml2.length(); long lPos=sHtml2.find("</html>"); if (lPos!=-1) sHtml2=sHtml2.substr(0, lPos+7); len=sHtml2.length();
IHTMLDocument2 *pHTMLDocument = NULL; if (SUCCEEDED(CPPWebBrowser->Document->QueryInterface(IID_IHTMLDocument2,(LPVOID*)&pHTMLDocument))) { if(pHTMLDocument!= NULL ) { int Bounds[2] = {0,0}; IHTMLElementCollection *pAll = NULL; Variant v = VarArrayCreate(Bounds, 1, varVariant); v.PutElement(sHtml2.c_str(), 0); len=sHtml2.length(); pHTMLDocument->clear(); pHTMLDocument->write(PSafeArray(v.VArray)); pHTMLDocument->close(); pHTMLDocument->Release(); } } } //---------------------------------------------------------------------------
cWEBBrowser::SetOnScroll (cOnScroll _OnScroll) { if (_OnScroll==NULL) return 0;
OnScroll=_OnScroll; IHTMLDocument2* pDoc; IHTMLWindow2* pWin;
if (SUCCEEDED(CPPWebBrowser->Document->QueryInterface(IID_IHTMLDocument2, (void**)&pDoc)) && pDoc) { HtmlEventSink.OnScroll = OnScroll;
VARIANT vIn; V_VT(&vIn) = VT_DISPATCH; V_DISPATCH(&vIn) = &HtmlEventSink; pDoc->get_parentWindow(&pWin);
if(SUCCEEDED(pWin->put_onscroll(vIn))); //pDoc->Release(); } } //---------------------------------------------------------------------------
cWEBBrowser::GetImgParams (string sID, int *iLeft, int *iTop, int *iWidth, int *iHeight) { IHTMLDocument3* pDoc=NULL; IHTMLElement* pElem=NULL; long lWidth=-1, lHeight=-1, lLeft=-1, lTop=-1, lTemp;
if (SUCCEEDED(CPPWebBrowser->Document->QueryInterface(IID_IHTMLDocument3, (void**)&pDoc)) && pDoc) { pDoc->getElementById(WideString(sID.c_str()), &pElem); if (pElem) { pElem->get_offsetWidth(&lWidth); pElem->get_offsetHeight(&lHeight); pElem->get_offsetLeft(&lLeft); pElem->get_offsetTop(&lTop);
// Рекурсивный обход контейнеров while (SUCCEEDED(pElem->get_offsetParent(&pElem)) && pElem) { pElem->get_offsetLeft(&lTemp); lLeft += lTemp; pElem->get_offsetTop(&lTemp); lTop += lTemp; } } } *iLeft=(int) lLeft; *iTop=(int) lTop; *iWidth=(int) lWidth; *iHeight=(int) lHeight; } //---------------------------------------------------------------------------
cWEBBrowser::GetScrollPos (int *iLeft, int *iTop) { IHTMLDocument3 *pHTMLDocument3 = NULL; IHTMLElementCollection *pElemCol = NULL; IHTMLElement *pHtmlElement=NULL; VARIANT AttributeValue; long lTop=0, lLeft=0;
IHTMLDocument2 *pHTMLDocument2 = NULL; IHTMLElement *pElem = NULL; IHTMLElement2 *pElem2 = NULL;
if (TypeScroll==tsUndefine || TypeScroll==tsHtml) { // Проверка позиции скролла у тега html (для IE>=5.0) if (SUCCEEDED(CPPWebBrowser->Document->QueryInterface(IID_IHTMLDocument3, (void**)&pHTMLDocument3)) && pHTMLDocument3) { pHTMLDocument3->getElementsByTagName(WideString("HTML"), &pElemCol); VARIANT varIndex; varIndex.vt = VT_UINT; varIndex.lVal = 0; VARIANT var2; VariantInit( &var2 ); IDispatch* pDisp; pElemCol->item(varIndex, var2, &pDisp);
if (SUCCEEDED (pDisp->QueryInterface(IID_IHTMLElement,(void **)&pHtmlElement)) && pHtmlElement) { pHtmlElement->getAttribute(WideString("scrollTop"), 0, &AttributeValue); lTop=AttributeValue.lVal; pHtmlElement->getAttribute(WideString("scrollLeft"), 0, &AttributeValue); lLeft=AttributeValue.lVal; } if (lLeft>0 || lTop>0) TypeScroll=tsHtml; } } if (TypeScroll==tsUndefine || TypeScroll==tsBody) { // Проверка позиции скролла у тега body (для IE<5.0) if (SUCCEEDED(CPPWebBrowser->Document->QueryInterface(IID_IHTMLDocument2, (void**)&pHTMLDocument2)) && pHTMLDocument2) { pHTMLDocument2->get_body(&pElem); pElem->QueryInterface(IID_IHTMLElement2,(void**)&pElem2); pElem2->get_scrollTop(&lTop); pElem2->get_scrollLeft(&lLeft); } if (lLeft>0 || lTop>0) TypeScroll=tsBody; } *iLeft=(int) lLeft; *iTop=(int) lTop; } //---------------------------------------------------------------------------
|
|