• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            旅途

            如果想飛得高,就該把地平線忘掉

            Internet Explorer 編程簡述(十)響應來自HTML Element的事件通知——幾個好用的類

            鍵字:HTML Element, Sink
             
            1、概述
            實現了對Webbrowser的resuing之后我們便會發現有時候我們還需要處理瀏覽器中的元素(HTML Element)。這種處理包括主動和被動兩個方面,像《FAQ:如何訪問WebBrowser的滾動條、《FAQ:操縱下拉列表、《FAQ:兩種方法訪問多層嵌套的frame等 文章所演示的就是主動的處理。通常我們從Webbrowser獲得一個Web文檔接口(IHTMLDocumentx),從它出發便可訪問到瀏覽器所包含 的一切HTML元素。而被動的處理則是在COM技術中稱為Sink的技術,我更喜歡的說法是事件通知。當文檔的下載進度發生變化時,我們可以獲得 ProgressChange通知,當Webbrowser下載完HTML文檔時,我們可以獲得DocumentComplete的通知,而當鏈接被點 擊,或圖片被拖動時,我們如何獲得通知呢?本文希望能夠給出部分的答案。
             
            2、HtmlObj Template
            如何Sink一個HTML Element并不是本文的重點,其理論我不是太了解,也懶得去搞透徹,所以使用現成的庫來實現。CodeProject上的一篇文章《CHtmlObj Template》給出的一個模板類CHtmlObj就非常好用。下面的例子是針對Html Anchor Element的一個實例化。
             
            #include "HtmlObj.h"
             
            class CHtmlAnchorElement : public CHtmlObj<IHTMLAnchorElement,
            &DIID_HTMLAnchorEvents> 
            {
            public:
            CHtmlAnchorElement(CHtmlDocument2* pParentDoc2);
            virtual ~CHtmlAnchorElement();
             
            virtual HRESULT OnInvoke(DISPID dispidMember,REFIID riid,
            LCID lcid, WORD wFlags,
            DISPPARAMS * pdispparams, VARIANT * pvarResult,
            EXCEPINFO * pexcepinfo,
            UINT * puArgErr);
            };

            HRESULT CHtmlAnchorElement::OnInvoke(DISPID dispidMember,
            REFIID riid, LCID lcid, WORD wFlags,
            DISPPARAMS * pdispparams, VARIANT * pvarResult,
            EXCEPINFO * pexcepinfo,
            UINT * puArgErr)
            {
            HRESULT hr = E_NOTIMPL;
            switch(dispidMember)
            {
            case DISPID_HTMLELEMENTEVENTS_ONMOUSEOVER :
            {//當鼠標經過鏈接時,我們在這里獲得通知
            hr = S_OK;
                  // TODO: add code to handle on mouse over events
            break;
            }
            case DISPID_HTMLELEMENTEVENTS_ONMOUSEOUT :
            {//當鼠標從鏈接上移開時,我們在這里獲得通知,其它的Dispatch ID可根據需要添加
            hr = S_OK;
                  // TODO: add code to handle on mouse out events
            break;
            }
            default:
            {
            break;
            }
            }
             
            return hr;
            }
             
            當 我們得到某個鏈接的HTML接口指針,便可調用CHtmlAnchorElement繼承自CHtmlObj的SetSite(IUnknown *pUnkSite)成員函數傳入該接口指針。在CHtmlObj類內部用一個智能指針m_spHtmlObj來保存相應的HTML Element接口指針,所以當上面的ONMOUSEHOVER和ONMOUSEOUT兩個事件通知到達時,從m_spHtmlObj就可以訪問 IHTMLAnchorElement的所有成員,如從href獲得鏈接的Url等,此處不再贅述。
             
            3、CHtmlElements類
            有 了CHtmlObj之后我們又會發現實踐中常常會需要多個相同類型的CHtmlObj。比如包含Frame的網頁中每個Frame的HTML Document都需要一個CHtmlObj來Sink其事件。所以我們還需要有效地管理這些相同類型的CHtmlObj。下面是我寫的一個簡單的模板類 CHtmlElements,它通過CMap來管理多個CHtmlObj對象。
             
            template<class THtmlElement> class CHtmlElements
            {
            typedef CMap<LPDISPATCH, LPDISPATCH, THtmlElement*, THtmlElement*> CMapDispToHtmlElement;
            CMapDispToHtmlElement m_htmlElements;
            BOOL IsSiteConnected( LPDISPATCH pDisp )
            {
            THtmlElement *pElement;
            return m_htmlElements.Lookup( pDisp, pElement );
            }
            public :
            CHtmlElements( void )
            {
            }
            ~CHtmlElements( void )
            {
            }
            public :
            void SetSite( LPDISPATCH pDisp )
            {
            if ( IsSiteConnected( pDisp ) ) //檢查以避免多余的Sink
            {
            return ;
            }
            THtmlElement *pElement = new THtmlElement; //通過模板類型創建相應的類的實例進行連接
            pElement->SetSite( pDisp );
            m_htmlElements.SetAt( pDisp, pElement );
            }
             

            //在合適的地方調用Clear釋放所管理的內存

            void Clear(void)

            {

            POSITION pos = m_htmlElements.GetStartPosition();

            THtmlElement *pElement = NULL;

            LPDISPATCH pDisp = NULL;

            while (pos != NULL)

            {

            m_htmlElements.GetNextAssoc( pos, pDisp, pElement );

            m_htmlElements.RemoveKey( pDisp );

            delete pElement;

            }

            }

            };
             
            假設我們有一個象CHtmlAnchorElement那樣派生自CHtmlObj的類CHtmlDocument2,使用CHtmlElements時這樣聲明:
             
            typedef CHtmlElements<CHtmlDocument2> CHtmlDocuments;
            typedef CHtmlElements<CHtmlAnchorElement> CHtmlAnchors;
             
            class CMyView : public CHtmlView
            {
            private :
            CHtmlDocuments m_htmlDocs;
            CHtmlAnchors m_htmlAnchors;
            }
             
            在DocumentComplete時就可以這樣連接到瀏覽器的文檔對象:
            void CMyView ::OnDocumentComplete(LPDISPATCH pDisp, LPCTSTR lpszURL)
            {
            m_htmlDocs.SetSite(pDisp);
            }
             
            如 果想一次性連接上文檔中所有的Anchor Element,可以通過IHTMLDocument2::get_anchors獲得包含所有IHTMLAnchorElement接口指針的 IHTMLElementCollection,再遍歷其中的每個元素,分別調用m_htmlAnchors.SetSite即可。當然,一次性的 Sink全部鏈接可能并不是個好注意,我更愿意在CHtmlDocument2中響應事件再通過其它手段來訪問當前位置的HTML Element。
             
            4、結論
            響 應HTML Element的事件通知對于瀏覽器編程來說是一個非常強大的手段,它可以更深入細化地控制瀏覽器中的文檔及其HTML元素,實現更為高級的功能,比如所 謂的“超級拖放”(許多多窗口瀏覽器都提供了該功能,但實際上沒有哪個瀏覽器完美地實現了對URL、文字及圖片的拖放)。
             
            5、參考資料
            Codeproject: HtmlObj Template
             
            引用地址:《Internet Explorer 編程簡述(十)響應來自HTML Element的事件通知——幾個好用的類


            Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=621961


            posted on 2007-07-29 15:37 旅途 閱讀(876) 評論(0)  編輯 收藏 引用 所屬分類: BHO

            草草久久久无码国产专区| 国内精品久久久久久99| 久久久久国产成人精品亚洲午夜| 欧美久久亚洲精品| 久久66热人妻偷产精品9| 国产成人久久激情91| 狠狠色综合网站久久久久久久高清| 久久99精品久久久久久| 性高湖久久久久久久久| 日韩十八禁一区二区久久| 色天使久久综合网天天| 久久久久国产一区二区三区| 一本久久a久久精品vr综合| 狠狠色丁香婷综合久久| 97精品国产97久久久久久免费 | 精品伊人久久大线蕉色首页| 久久婷婷五月综合97色直播| 久久久久久国产精品美女| 久久综合给合久久狠狠狠97色| 囯产精品久久久久久久久蜜桃| 国产成人精品久久综合| 久久精品国产亚洲AV嫖农村妇女| 久久久久亚洲AV无码网站| 久久综合九色综合久99| 热久久这里只有精品| 国内精品伊人久久久久影院对白| 久久亚洲国产中v天仙www| 亚洲精品无码久久久久去q| 久久天天日天天操综合伊人av| 91精品观看91久久久久久| 精品国产热久久久福利| 久久99精品国产一区二区三区| 久久久久久国产精品无码超碰| 久久国语露脸国产精品电影| 久久久久久久91精品免费观看| 2021国内久久精品| 亚洲Av无码国产情品久久| 久久久久一级精品亚洲国产成人综合AV区 | 国产精品va久久久久久久| 精品久久久久久| 99久久免费国产精品|