• <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>

            牽著老婆滿街逛

            嚴(yán)以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            如何對webbrowser和IE編程(九)

            接收事件的途徑

            依靠開發(fā)工具你創(chuàng)建客戶應(yīng)用程序,你可以接收事件通過不同的途徑. 顯然, 在Vb中接收事件同在VC中接收事件相比是如此不同和容易.在 C++ 應(yīng)用中,你可以用不同的技術(shù),通過使用 ATL, MFC, 或者標(biāo)準(zhǔn)C++.

            Visual Basic 中接收事件

            Visual Basic是創(chuàng)建大多數(shù)類型應(yīng)用的最輕松的工具, 所以我告訴你VB是處理事件最溶的工具時也不要驚奇. ATL 和 Visual Basic 示例我們同樣的工作,但是ATL花費(fèi)了我4個小時, 而 Visual Basic 例子僅僅只花20 分鐘.別說我錯了—我是ATL, 和 MFC, C++的忠實(shí)信徒,  尤其是你建立一個接口的時候.但是 Visual Basic當(dāng)建立客戶應(yīng)用程序從類似IE這樣的服務(wù)器接收事件時是偉大的工具.

            OK,如何從Visual Basic 應(yīng)用程序中接收事件?當(dāng)宿主WebBrowser 控件,你不必做任何特別的事. Visual Basic 在form上為WebBrowser 控件接收事件.你所需要做的全部事情就是未你要接收的任何事件創(chuàng)建一個事件處理句柄.

            你象創(chuàng)建其他事件句柄一樣創(chuàng)建句柄 (例如Form_Load event). 從Procedure下拉列表框中選擇你象控制的句柄, 在事件句柄中,加入任何你型在事件激發(fā)時執(zhí)行的任何代碼.

            當(dāng)自動化服務(wù)器時候接收事件, 例如在VB應(yīng)用中的Internet Explorer,過程直截了當(dāng).首先設(shè)置對服務(wù)器的類型庫的引用, 你可以訪問Project/References 菜單.之后,采用WithEvents 關(guān)鍵字聲明服務(wù)器對象的變量.舉例, 如果你自動化Internet Explorer, 你將聲明變量如下:

            Dim WithEvents InternetExplorer1 As InternetExplorer

            下一步,采用new或者其他 關(guān)鍵字創(chuàng)建實(shí)例變量 ,如下:

            Set InternetExplorer1 = CreateObject("InternetExplorer.Application.1")

            或者:

            Set InternetExplorer1 = New InternetExplorer

            當(dāng)你采用以上途徑生成實(shí)例接收事件, Visual Basic 自動為你初始化和管理事件接收.你不必?fù)?dān)心連接點(diǎn)問題,VB為你處理它們.

            在你輸入建立服務(wù)器的代碼之后,你插入符合服務(wù)器事件的方法調(diào)用.   舉例來說, 如果你想控制由IE激活的DownloadBegin event, 你應(yīng)當(dāng)聲明類似如下的方法聲明:

            Private Sub InternetExplorer1_DownloadBegin()
                
            ' Insert your best Visual Basic code here.
            End Sub                                        

            當(dāng)你不再想接收來自服務(wù)器的事件,簡單設(shè)置變量為Nothing:

            Set InternetExplorer1 = Nothing

             

            C++中接收事件

            C++ 應(yīng)用程序中接收事件比Vb中多一些工作.但如果你在MFC對話框程序中宿主過WebBrowser控件, 你可以在classwizard中選擇你想控制的事件.使用C++的其他應(yīng)用程序宿主WebBrowser 或者自動化Internet Explorer 需要多一點(diǎn)的工作,但是仍然不需要更多的工作.在C++客戶接收事件,僅僅需要以下5個步驟:

            1.     獲取連接點(diǎn)容器的指針 (IConnectionPointContainer).

            2.        調(diào)用 IconnectionPointContainer 的方法 FindConnectionPoint 找出你想接收的事件。對 Internet Explorer 來講 , 你應(yīng)當(dāng)為 DWebBrowserEvents2 連接點(diǎn)接口實(shí)現(xiàn)事件 . ( 作為可選 , 你可以調(diào)用 EnumConnectionPoints 以枚舉服務(wù)器支持的全部連接點(diǎn) )

            3.        實(shí)現(xiàn)接入你想接收事件的連接點(diǎn)的通報( Advise )。 當(dāng)實(shí)現(xiàn)通告時 , 傳遞一個事件接收槽的 Iunknown 接口的指針。 記住,事件接收槽必須實(shí)現(xiàn) IDispatch 接口以接收來自 WebBrowser 的事件。 Advise 方法將返回一個 cookie ,該 Cookie 在你調(diào)用 Unadvise 方法的時候攜帶上。

            4.        實(shí)現(xiàn) IDispatch::Invoke 以控制任何激發(fā)的事件。 . ( 開發(fā)工具如 MFC ATL 能夠容易為你做到 .)

            5.        當(dāng)你不再接受事件,調(diào)用 Unadvise , 并且傳遞 cookie.

            以上步驟如果采用VB和MFC \ATL等可能不很明顯,但是當(dāng)你采用標(biāo)準(zhǔn)C++創(chuàng)建應(yīng)用程序的時候就應(yīng)當(dāng)很明顯了.

            以下 C++ 代碼允許你在自動化IE的時候接收事件. 留意注釋代碼實(shí)現(xiàn)了哪一個步驟. 假定當(dāng)你想連接事件時ConnectEvents 方法被調(diào)用,且當(dāng)應(yīng)用程序退出時候Exit 方法被調(diào)用. 同樣的,類 CSomeClass 繼承自IDispatch,m_pIE 數(shù)據(jù)成員為通過CoCreateInstance 方法創(chuàng)建的IE的實(shí)例

            void CSomeClass::ConnectEvents()
            {
                IConnectionPointContainer
            * pCPContainer;// Step 1: 獲取連接點(diǎn)的指針.
                HRESULT hr = m_pIE->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPContainer);

                
            if (SUCCEEDED(hr))
                
            {
                    
            // m_pConnectionPoint is defined like this:
                    
            // IConnectionPoint* m_pConnectionPoint;
                    
                    
            // Step 2: 選找連接點(diǎn).
                    
            //
                    hr = pCPContainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &m_pConnectionPoint);
                    
            if (SUCCEEDED(hr))
                    
            {
                        
            // Step 3: 實(shí)現(xiàn)連接點(diǎn)地事件接收
                        
            //
                        hr = m_pConnectionPoint->Advise(this&m_dwCookie);
                        
            if (FAILED(hr))
                        
            {
                            ::MessageBox(NULL, 
            "Failed to Advise""C++ Event Sink", MB_OK);
                        }

                    }

                    pCPContainer
            ->Release();
                }

            }


            void CSomeClass::Exit()
            {
                
            // Step 5: Unadvise. 注意m_pConnectionPoint 應(yīng)當(dāng)在CSomeClass的析構(gòu)函數(shù)中釋放
                
            //
                if (m_pConnectionPoint)
                
            {
                    HRESULT hr 
            = m_pConnectionPoint->Unadvise(m_dwCookie);
                    
            if (FAILED(hr))
                    
            {
                        ::MessageBox(NULL, 
            "Failed to Unadvise""C++ Event Sink", MB_OK);
                    }

                }

            }


            注意此處少了step4:客戶端的 IDispatch::Invoke 方法實(shí)現(xiàn). 我將很快討論此點(diǎn). 每一次服務(wù)器激發(fā)事件會調(diào)用此. 當(dāng)事件被激發(fā),服務(wù)器傳遞事件的DISPID 到Invoke. 對于 Internet Explorer 5, 以下DISPIDs 定義于ExDispID.h 頭文件.

            ·         DISPID_BEFORENAVIGATE2

            • DISPID_COMMANDSTATECHANGE
            • DISPID_DOCUMENTCOMPLETE
            • DISPID_DOWNLOADBEGIN
            • DISPID_DOWNLOADCOMPLETE
            • DISPID_NAVIGATECOMPLETE2
            • DISPID_NEWWINDOW2
            • DISPID_ONFULLSCREEN
            • DISPID_ONMENUBAR
            • DISPID_ONQUIT
            • DISPID_ONSTATUSBAR
            • DISPID_ONTHEATERMODE
            • DISPID_ONTOOLBAR
            • DISPID_ONVISIBLE
            • DISPID_PROGRESSCHANGE
            • DISPID_PROPERTYCHANGE
            • DISPID_STATUSTEXTCHANGE
            • DISPID_TITLECHANGE

            現(xiàn)在我們返回討論Invoke. 該方法有8個參數(shù), 但我們將僅僅討論其中的兩個: dispidMemberpDispParams. (其余的參見MSDN中的IDispatch::Invoke.)

            dispidMember 參數(shù)將告訴你哪一個事件被激發(fā).如果客戶應(yīng)用程序接收來自Internet Explorer的事件, dispidMember 參數(shù)的值應(yīng)當(dāng)是DISPIDs 列表中的某個.

            pDispParams 輸入?yún)?shù)是指向容器結(jié)構(gòu)的指針, 存儲事件激發(fā)時的其他項(xiàng). 傳遞到事件句柄的參數(shù)存儲在pDispParams->rgvarg ,逆序存放. 舉例來說, Internet Explorer 激發(fā)NavigateComplete2 事件如下所示:

            NavigateComplete2(pDisp, URL)

            當(dāng) Invoke 被調(diào)用, pDispParams->cArgs 將包含兩個值, URL 參數(shù)在 pDispParams->rgvarg[0] 以及pDisp 參數(shù)存儲在 pDispParams->rgvarg[1]. 這些就是COM次序傳遞參數(shù)給Invoke 方法的方式.

            以下為 NavigateComplete2 事件的處理.注意采用ATL的CComVariant 處理從 VARIANTBSTR包裝.

            #include <strstrea.h>
            STDMETHODIMP CSomeClass::Invoke(DISPID dispidMember,
                            REFIID riid,
                            LCID lcid,
                            WORD wFlags,
                            DISPPARAMS
            * pDispParams,
                            VARIANT
            * pvarResult,
                            EXCEPINFO
            *  pExcepInfo,
                            UINT
            * puArgErr)
            {
                USES_CONVERSION;
                strstream strEventInfo;
                
                
            if (!pDispParams)
                    
            return E_INVALIDARG;

                
            switch (dispidMember)
                
            {
                    
            // The parameters for this DISPID:
                    
            // [0]: URL navigated to - VT_BYREF|VT_VARIANT
                    
            // [1]: An object that evaluates to the top-level or frame
                    
            //      WebBrowser object corresponding to the event.
                    
            //
                    case DISPID_NAVIGATECOMPLETE2:
                        
            // Check the argument's type.
                        if (pDispParams->rgvarg[0].vt == (VT_BYREF|VT_VARIANT))
                        
            {
                            CComVariant varURL(
            *pDispParams->rgvarg[0].pvarVal);
                            varURL.ChangeType(VT_BSTR);
                            
            // strEventInfo is an object of type strstream.
                            
            //
                            strEventInfo << "NavigateComplete2: " << OLE2T(vtURL.bstrVal) << ends;
                            
                            ::MessageBox(NULL, strEventInfo.str(), 
            "Invoke", MB_OK);
                        }

                    
            break;

                    
            default:
                        
            break;
                }


                
            return S_OK;
            }



            ATL中接收事件

            連同實(shí)現(xiàn)了缺省的COM 接口實(shí)現(xiàn), ATL提供了兩個函數(shù)—AtlAdviseAtlUnadvise—使得任何課連接對象的事件接收簡單化.

            AtlAdvise 函數(shù)告訴一個可連接對象客戶想從此可連接對象接收事件.該函數(shù)封裝實(shí)現(xiàn)接收事件的步驟1到3. AtlAdvise 理所當(dāng)然省了大量的時間.就像IConnectionPoint::Advise 方法, AtlAdvise 返回一個cookie供你稍后調(diào)用 AtlUnadvise. AtlUnadvise 告訴可連接對象客戶不再接收事件.

            讓我們行說吧, 舉個例子, ATL應(yīng)用程序自動化Internet Explorer, 所以你想知道任何IE激發(fā)的事件. 為了告知Internet Explorer客戶想接收事件,發(fā)出對AtlAdvise的以下調(diào)用:

            												
            														HRESULT hr = AtlAdvise(m_spInetExplorer, GetUnknown(),
            												
            										
            												
            														
            																
            																		                       DIID_DWebBrowserEvents2, &m_dwCookie);
            														
            												
            										

            四個參數(shù)傳遞給AtlAdvise. 第一個參數(shù)是指向可連接對象的IUnknown 接口的指針. m_spInetExplorer 數(shù)據(jù)成員是一個經(jīng)過我們自動化當(dāng)前運(yùn)行的Internet Explorer實(shí)例的指針. 因?yàn)?em>m_spInetExplorer 指向的對象直接或者間接繼承自IUnknown, 編譯器自動轉(zhuǎn)換m_spInetExplorer 為當(dāng)前運(yùn)行的 IE實(shí)例的IUnknown 接口指針.

            AtlAdvise 第二個參數(shù)必須指向提供事件的對象的IUnknown 接口. GetUnknown 函數(shù)返回此接口.記住,提供事件的類必須通過某種途徑實(shí)現(xiàn) IDispatch in.在此例子中,該類繼承自 IDispatch.

            第三個參數(shù)為你象接收的事件的IID, Internet Explorer 事件的可連接對象的IIS是 DIID_DWebBrowserEvents2.

            最后一個參數(shù)指向DWORD的指針,該DWORD接收返回的Cookie. 該 cookie 將用于調(diào)用 AtlUnadvise.

            客戶必須實(shí)現(xiàn) IDispatch::Invoke 以控制Internet Explorer 激發(fā)的事件. 當(dāng)你的應(yīng)用程序完成從IE接收事件, 只需要調(diào)用 call AtlUnadvise, 如下:

            												
            														HRESULT hr = AtlUnadvise(m_spInetExplorer,
            												
            										
            												
            														
            																
            																		                         DIID_DWebBrowserEvents2, 
            														
            												
            										
            												
            														
            																
            																		                         m_dwCookie);
            														
            												
            										

            Figure 7-3. ATLIEEvtSpy.

            以下展示如何自動化IE:

            												
            														hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, 
            												
            										
            												
            														
            																
            																		                      IID_IWebBrowser2, (void**)&m_spInetExplorer);
            														
            												
            										
            												
            														if (SUCCEEDED(hr))
            												
            										
            												
            														{
            												
            										
            												
            														
            																
            																		   m_spInetExplorer->put_Visible(TRUE);
            														
            												
            										
            												
            														
            																
            																		   m_spInetExplorer->GoHome();        
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																
            														
            												
            										

            接下來, AtlAdvise 調(diào)用以接收事件, 如下:

            												
            														hr = AtlAdvise(m_spInetExplorer, GetUnknown(),
            												
            										
            												
            														
            																
            																		               DIID_DWebBrowserEvents2, &m_dwCookie);
            														
            												
            										

            CIEEvtObj 類繼承自IDispatch,所以 CIEEvtObj 類可以作為事件接收對象. Invoke 實(shí)現(xiàn)控制事件. 每當(dāng)Internet Explorer 激發(fā)一個事件, 在listBox中顯示一個消息.以西為invoke的代碼:

            												
            														STDMETHODIMP CIEEvtObj::Invoke(DISPID dispidMember, 
            												
            										
            												
            														
            																
            																		                               REFIID riid, 
            														
            												
            										
            												
            														
            																
            																		                               LCID lcid, 
            														
            												
            										
            												
            														
            																
            																		                               WORD wFlags, 
            														
            												
            										
            												
            														
            																
            																		                               DISPPARAMS* pDispParams, 
            														
            												
            										
            												
            														
            																
            																		               
            																		                VARIANT* pvarResult,
            														
            												
            										
            												
            														
            																
            																		                               EXCEPINFO* pExcepInfo,  
            														
            												
            										
            												
            														
            																
            																		                               UINT* puArgErr)
            														
            												
            										
            												
            														{
            												
            										
            												
            														
            																
            																		   _ASSERT(m_spInetExplorer);
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		   USES_CONVERSION;
            														
            												
            										
            												
            														
            																
            																		   strstream strEventInfo;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		   if (!pDispParams)
            														
            												
            										
            												
            														
            																
            																		      return E_INVALIDARG;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		   switch (dispidMember)
            														
            												
            										
            												
            														
            																
            																		   {
            														
            												
            										
            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      // The parameters for this DISPID are as follows:
            														
            												
            										
            												
            														
            																
            																		      // [0]: Cancel flag  - VT_BYREF|VT_BOOL
            														
            												
            										
            												
            														
            																
            																		      // [1]: HTTP headers - VT_BYREF|VT_VARIANT
            														
            												
            										
            												
            														
            																
            																		      // [2]: Address of HTTP POST data  - VT_BYREF|VT_VARIANT 
            														
            												
            										
            												
            														
            																
            																		      // [3]: Target frame name - VT_BYREF|VT_VARIANT 
            														
            												
            										
            												
            														
            																
            																		      // [4]: Option flags - VT_BYREF|VT_VARIANT
            														
            												
            										
            												
            														
            																
            																		      // [5]: URL to navigate to - VT_BYREF|VT_VARIANT
            														
            												
            										
            												
            														
            																
            																		      // [6]: An object that evaluates to the top-level or frame
            														
            												
            										
            												
            														
            																
            																		      //      WebBrowser object corresponding to the event 
            														
            												
            										
            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      case DISPID_BEFORENAVIGATE2:
            														
            												
            										
            												
            														
            																
            																		         strEventInfo << "BeforeNavigate2: ";
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         if (pDispParams->cArgs >= 5
            														
            												
            										
            												
            														
            																
            																		            && pDispParams->rgvarg[5].vt == (VT_BYREF|VT_VARIANT))
            														
            												
            										
            												
            														
            																
            																		         {
            														
            												
            										
            												
            														
            																
            																		          
            																		  CComVariant vtURL(*pDispParams->rgvarg[5].pvarVal);
            														
            												
            										
            												
            														
            																
            																		            vtURL.ChangeType(VT_BSTR);
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		            strEventInfo << OLE2T(vtURL.bstrVal);
            														
            												
            										
            												
            														
            																
            																		         }
            														
            												
            										
            												
            														
            																
            																		         else
            														
            												
            										
            												
            														
            																
            																		            strEventInfo << "NULL";
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         strEventInfo << ends;
            														
            												
            										
            												
            														
            																
            																		         break;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		  
            																		    //
            														
            												
            										
            												
            														
            																
            																		      // The parameters for this DISPID:
            														
            												
            										
            												
            														
            																
            																		      // [0]: Enabled state - VT_BOOL
            														
            												
            										
            												
            														
            																
            																		      // [1]: Command identifier - VT_I4
            														
            												
            										
            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      case DISPID_COMMANDSTATECHANGE:
            														
            												
            										
            												
            														
            																
            																		         strEventInfo << "CommandStateChange: ";
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         if (pDispParams->cArgs == 0)
            														
            												
            										
            												
            														
            																
            																		            strEventInfo << "NULL";
            														
            												
            										
            												
            														
            																
            																		         else
            														
            												
            										
            												
            														
            																
            																		         {
            														
            												
            										
            												
            														
            																
            																		            if (pDispParams->cArgs > 1 
            														
            												
            										
            												
            														
            																
            																		               && pDispParams->rgvarg[1].vt == VT_I4)
            														
            												
            										
            												
            														
            																
            																		            {
            														
            												
            										
            												
            														
            																
            																		               strEventInfo << "Command = " 
            														
            												
            										
            												
            														
            																
            																		                            << pDispParams->rgvarg[1].lVal;
            														
            												
            										
            												
            														
            																
            																		            }
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		            if (pDispParams->rgvarg[0].vt == VT_BOOL)
            														
            												
            										
            												
            														
            																
            																		            {
            														
            												
            										
            												
            														
            																
            																		               strEventInfo << ", Enabled = "
            														
            												
            										
            												
            														
            																
            																		                      << ((pDispParams->rgvarg[0].boolVal == VARIANT_TRUE) 
            														
            												
            										
            												
            														
            																
            																		                           ? "True" : "False");
            														
            												
            										
            												
            														
            																
            																		            }
            														
            												
            										
            												
            														
            																
            																		         }
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         strEventInfo << ends;
            														
            												
            										
            												
            														
            																
            																		         break;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		      case DISPID_DOCUMENTCOMPLETE:
            														
            												
            										
            												
            														
            																
            																		         strEventInfo << "DocumentComplete" << ends;
            														
            												
            										
            												
            														
            																
            																		         break;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		      case DISPID_DOWNLOADBEGIN:
            														
            												
            										
            												
            														
            																
            																		         strEventInfo << "DownloadBegin" << ends;
            														
            												
            										
            												
            														
            																
            																		         break;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		      case DISPID_DOWNLOADCOMPLETE:
            														
            												
            										
            												
            														
            																
            																		         strEventInfo << "DownloadComplete" << ends;
            														
            												
            										
            												
            														
            																
            																		         break;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      // The parameters for this DISPID:
            														
            												
            										
            												
            														
            																
            																		      // [0]: URL navigated to - VT_BYREF|VT_VARIANT
            														
            												
            										
            												
            														
            																
            																		  
            																		    // [1]: An object that evaluates to the top-level or frame
            														
            												
            										
            												
            														
            																
            																		      //      WebBrowser object corresponding to the event 
            														
            												
            										
            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      case DISPID_NAVIGATECOMPLETE2:
            														
            												
            										
            												
            														
            																
            																		         if (pDispParams->rgvarg[0].vt == (VT_BYREF|VT_VARIANT))
            														
            												
            										
            												
            														
            																
            																		         {
            														
            												
            										
            												
            														
            																
            																		           
            																		 CComVariant vtURL(*pDispParams->rgvarg[0].pvarVal);
            														
            												
            										
            												
            														
            																
            																		            vtURL.ChangeType(VT_BSTR);
            														
            												
            										
            												
            														
            																  
            														
            												
            										
            												
            														
            																
            																		            strEventInfo << "NavigateComplete2: "
            														
            												
            										
            												
            														
            																
            																		                         << OLE2T(vtURL.bstrVal)
            														
            												
            										
            												
            														
            																
            																		                         << ends;
            														
            												
            										
            												
            														
            																
            																		         }
            														
            												
            										
            												
            														
            																
            																		         break;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      // The parameters for this DISPID:
            														
            												
            										
            												
            														
            																
            																		      // [0]: Maximum progress - VT_I4
            														
            												
            										
            												
            														
            																
            																		      // [1]: Amount of total progress - VT_I4
            														
            												
            										
            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      case DISPID_PROGRESSCHANGE:
            														
            												
            										
            												
            														
            																
            																		         strEventInfo << "ProgressChange: ";
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         if (pDispParams->cArgs == 0)
            														
            												
            										
            												
            														
            																
            																		            strEventInfo << "NULL";
            														
            												
            										
            												
            														
            																
            																		         else
            														
            												
            										
            												
            														
            																
            																		         {
            														
            												
            										
            												
            														
            																
            																		            if (pDispParams->cArgs > 1 
            														
            												
            										
            												
            														
            																
            																		               && pDispParams->rgvarg[1].vt == VT_I4)
            														
            												
            										
            												
            														
            																
            																		            {
            														
            												
            										
            												
            														
            																
            																		               strEventInfo << "Progress = " 
            														
            												
            										
            												
            														
            																
            																		                            << pDispParams->rgvarg[1].lVal;
            														
            												
            										
            												
            														
            																
            																		            }
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		            if (pDispParams->rgvarg[0].vt == VT_I4)
            														
            												
            										
            												
            														
            																
            																		               strEventInfo << ", ProgressMax = " 
            														
            												
            										
            												
            														
            																
            																		                            << pDispParams->rgvarg[0].lVal;
            														
            												
            										
            												
            														
            																
            																		         }
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         strEventInfo << ends;
            														
            												
            										
            												
            														
            																
            																		         break;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      // The parameter for this DISPID:
            														
            												
            										
            												
            														
            																
            																		      // [0]: Name of property that changed - VT_BSTR
            														
            												
            										
            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      case DISPID_PROPERTYCHANGE:
            														
            												
            										
            												
            														
            																
            																		         strEventInfo << "PropertyChange: ";
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         if (pDispParams->cArgs > 0 
            														
            												
            										
            												
            														
            																
            																		            && pDispParams->rgvarg[0].vt == VT_BSTR)
            														
            												
            										
            												
            														
            																
            																		         {
            														
            												
            										
            												
            														
            																
            																		            strEventInfo << OLE2T(pDispParams->rgvarg[0].bstrVal);
            														
            												
            										
            												
            														
            																
            																		         }
            														
            												
            										
            												
            														
            																
            																		         else
            														
            												
            										
            												
            														
            																
            																		         {
            														
            												
            										
            												
            														
            																
            																		            strEventInfo << "NULL";
            														
            												
            										
            												
            														
            																
            																		         }
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         strEventInfo << ends;
            														
            												
            										
            												
            														
            																
            																		         break;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		   
            																		   // The parameters for this DISPID:
            														
            												
            										
            												
            														
            																
            																		      // [0]: New status bar text - VT_BSTR
            														
            												
            										
            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      case DISPID_STATUSTEXTCHANGE:
            														
            												
            										
            												
            														
            																
            																		         LPOLESTR lpStatusText;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         m_spInetExplorer->get_StatusText(&lpStatusText);
            														
            												
            										
            												
            														
            																
            																		         strEventInfo << "StatusTextChange: ";
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         if (!strcmp(OLE2T(lpStatusText), ""))
            														
            												
            										
            												
            														
            																
            																		            strEventInfo << "NULL";
            														
            												
            										
            												
            														
            																
            																		         else
            														
            												
            										
            												
            														
            																
            																		            strEventInfo << OLE2T(lpStatusText);
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         strEventInfo << ends;
            														
            												
            										
            												
            														
            																
            																		         break;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		      case DISPID_NEWWINDOW2:
            														
            												
            										
            												
            														
            																
            																		         strEventInfo << "NewWindow2" << ends;
            														
            												
            										
            												
            														
            																
            																		         break;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      // The parameter for this DISPID:
            														
            												
            										
            												
            														
            																
            																		      // [0]: Document title - VT_BSTR
            														
            												
            										
            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      case DISPID_TITLECHANGE:
            														
            												
            										
            												
            														
            																
            																		         strEventInfo << "TitleChange: ";
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         if (pDispParams->cArgs > 0 
            														
            												
            										
            												
            														
            																
            																		     
            																		       && pDispParams->rgvarg[0].vt == VT_BSTR)
            														
            												
            										
            												
            														
            																
            																		         {
            														
            												
            										
            												
            														
            																
            																		            strEventInfo << OLE2T(pDispParams->rgvarg[0].bstrVal);
            														
            												
            										
            												
            														
            																
            																		         }
            														
            												
            										
            												
            														
            																
            																		         else
            														
            												
            										
            												
            														
            																
            																		         {
            														
            												
            										
            												
            														
            																
            																		            strEventInfo << "NULL";
            														
            												
            										
            												
            														
            																
            																		         }
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         strEventInfo << ends;
            														
            												
            										
            												
            														
            																
            																		         break;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		      // The user has told Internet Explorer to close.
            														
            												
            										
            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      case DISPID_ONQUIT:
            														
            												
            										
            												
            														
            																
            																		         return Stop();
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		      default:
            														
            												
            										
            												
            														
            																
            																		         // Note: This class acts only as an event sink, so
            														
            												
            										
            												
            														
            																
            																		         // there's no reason to call the base class version of Invoke.
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         strEventInfo << "Unknown Event" << dispidMember << ends;
            														
            												
            										
            												
            														
            																
            																		         break;
            														
            												
            										
            												
            														
            																
            																		   }
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		   AddEventToList(strEventInfo.str());
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		   return S_OK;
            														
            												
            										
            												
            														}
            												
            										

            請注意此使用了標(biāo)準(zhǔn)C++ 庫的 strstream 類來建立字符串.這么做是因?yàn)锳TL 不提供像Cstring的類. 每一次從IE接收到事件,建立一個包含事件的名稱和參數(shù)的字符串. 然后顯示在列表框中.

            退出時候調(diào)用AtlUnadvise:

            												
            														STDMETHODIMP CIEEvtObj::Stop()
            												
            										
            												
            														{
            												
            										
            												
            														
            																
            																		   if (m_spInetExplorer)
            														
            												
            										
            												
            														
            																
            																		   {
            														
            												
            										
            												
            														
            																
            																		      HRESULT hr = AtlUnadvise(m_spInetExplorer, 
            														
            												
            										
            												
            														
            																
            																		                      
            																		         DIID_DWebBrowserEvents2, 
            														
            												
            										
            												
            														
            																
            																		                               m_dwCookie);
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		      if (FAILED(hr))
            														
            												
            										
            												
            														
            																
            																		         ATLTRACE("Failed to Unadvise\n");
            														
            												
            										
            												
            														
            																
            																		   }
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		   PostQuitMessage(0);
            														
            												
            										
            												
            														
            																
            																		   return S_OK;
            														
            												
            										
            												
            														}
            												
            										

            MFC中接收事件

            MFC提供了數(shù)個宏使得你可以接收從自動化的對象或者宿主的控件的事件。在兩種情況中, 接收事件的類必須直接或者間接繼承自CCmdTarget. CCmdTarget 實(shí)現(xiàn)接收事件的IDispatch 接口. 另外, 你必須在你的應(yīng)用中調(diào)用EnableAutomation 初始化包含在CCmdTarget 中的IDispatch.

            MFC中自動化一個COM 對象時接收事件

            mfc中接收事件很容易.全部要做的就是在代碼中調(diào)用AfxConnectionAdvise 函數(shù)以通告連接點(diǎn)客戶需要接收事件.當(dāng)客戶不許要接收事件,調(diào)用AfxConnectionUnadvise.  AfxConnectionAdvise AfxConnectionUnadvise 函數(shù)定義于afxctl.h 頭文件。

            AfxConnectionAdvise 函數(shù)查詢連接點(diǎn)容器, 尋找可連接點(diǎn),并且通告連接點(diǎn). 函數(shù)的5個參數(shù)如下:

            Table 7-3 Parameters of the AfxConnectionAdvise Function

            Parameter

             

             

            Description

             

             

            pUnkSrc

             

             

            指向激發(fā)事件的 com 對象的 IUnknown 接口的指針 . pUnkSrc 是由 CoCreateInstance . 建立的對象的指針

             

             

            pUnkSink

             

             

            指向事件接收的 IUnknown 接口

             

             

            iid

             

             

            連接點(diǎn)的 IID. 例如對 IE 來說,是 DIID_DWebBrowserEvents2 .

             

             

            bRefCount

             

             

            傳遞 TRUE 表示建立連接點(diǎn)將導(dǎo)致 pUnkSink 的引用將增加。 FALSE 表示不會增加 .

             

             

            pdwCookie

             

             

            表示此連接。由 AfxConnectionAdvise 將傳遞給 AfxConnectionUnadvise

             

             

             

             

             

            處理事件也很容易。記住MFC事件接收類必須繼承自CCmdTarget. CCmdTarget 使用派遣映射檢測當(dāng)接收到事件時調(diào)用處理函數(shù).你必須首先在頭文件中聲明派遣映射 然后再實(shí)現(xiàn)文件中 (.cpp) 實(shí)現(xiàn). 幸運(yùn)地, MFC提供了宏來幫助聲明和處理派遣映射。.

            為了定義派遣映射, 首先在聲明接收事件類的頭文件中簡單定義DECLARE_DISPATCH_MAP. 這些宏聲明派遣映射和CCmdTarget 訪問的函數(shù). 一旦你定義了派遣映射,你應(yīng)當(dāng)在實(shí)現(xiàn)文件中實(shí)現(xiàn)宏. 第一個宏放在BEGIN_DISPATCH_MAP 宏.它指定事件接收類的基礎(chǔ)類.舉例來說,如果事件類是CEventSink 繼承自 CCmdTarget, BEGIN_DISPATCH_MAP 將看起來如下:

            												
            														BEGIN_DISPATCH_MAP(CEventSink, CCmdTarget)
            												
            										

            接下來用DISP_FUNCTION_ID來聲明派遣ID。此宏的六個參數(shù):

            Table 7-4 Parameters of the DISP_FUNCTION_ID Macro

            Parameter

             

             

            Description

             

             

            theClass

             

             

            事件類的名稱

             

             

            szExternalName

             

             

            函數(shù)的名字 .

             

             

            dispid

             

             

            事件的 DISPID

             

             

            pfnMember

             

             

            指向處理事件的成員函數(shù) .

             

             

            vtRetval

             

             

            成員函數(shù)的返回值類型,是 VARENUM 的每局類型,定義于 wtypes.h 頭文件

             

             

            vtsParams

             

             

            空格分隔的參數(shù)類型的列表 .

             

             

            假設(shè)你想控制DownloadComplete 事件. 告訴CCmdTarget 你將控制處理DownloadComplete, 如下使用:

            												
            														DISP_FUNCTION_ID(CIE5Events, "DownloadComplete",
            												
            										
            												
            														
            																
            																		                 DISPID_DOWNLOADCOMPLETE, OnDownloadComplete,
            														
            												
            										
            												
            														
            																
            																		                 VT_EMPTY, VTS_NONE)
            														
            												
            										

            最終采用 END_DISPATCH_MAP宏關(guān)閉.完整如下:

            												
            														BEGIN_DISPATCH_MAP(CEventSink, CCmdTarget)
            												
            										
            												
            														
            																
            																		   DISP_FUNCTION_ID(CIE5Events, "DownloadComplete",
            														
            												
            										
            												
            														
            																
            																		                    DISPID_DOWNLOADCOMPLETE, OnDownloadComplete,
            														
            												
            										
            												
            														
            																
            																		   
            																		                 VT_EMPTY, VTS_NONE)
            														
            												
            										
            												
            														END_DISPATCH_MAP()
            												
            										

            MFC中寄宿 ActiveX 控件時處理事件

            這類似于處理COM對象的事件.主要區(qū)別在于你不需要通告或者解除通告連接點(diǎn). CCmdTarget 未你控制了他.

            在寄宿一個Activex控件情形中, CCmdTarget 使用事件接收宏代理派遣宏.就像你猜想的一樣, MFC 提供初始化事件接收通告映射. 聲明此宏類似聲明派遣宏—派 DECLARE_EVENTSINK_MAP 宏存放在頭文件中.另外的聲明映射,  DECLARE_EVENTSINK_MAP 聲明 CCmdTarget 訪問映射的類

            接下來在類中實(shí)現(xiàn)事件接收.開始于EGIN_EVENTSINK_MAP 宏.指定事件接收類的 和它的基類。舉例,此處為實(shí)例:

            												
            														BEGIN_EVENTSINK_MAP(CMyDlg, CDialog)
            												
            										

            現(xiàn)在實(shí)用ON_EVENT*宏來處理是按接收.。大多數(shù)情形,你將使用帶有5個參數(shù)的ON_EVENT.攜帶的參數(shù)如下:

            												
            														ON_EVENT(CMyDlg, IDC_WEBBROWSER, DISPID_DOWNLOADCOMPLETE, 
            												
            										
            												
            														
            																
            																		         OnDownloadComplete, VTS_NONE)
            														
            												
            										

            如果你象多個成員函數(shù)處理此事件, 使用ON _EVENT_RANGE宏.

            Table 7-5 Parameters of the ON_EVENT Macro

            Parameter

             

             

            Description

             

             

            theClass

             

             

            在那個類中接收事件

             

             

            id

             

             

            控件的資源 ID

             

             

            dispid

             

             

            有控件激活的事件的 ID.

             

             

            pfnHandler

             

             

            事件的成員函數(shù),用來處理事件句柄 . 此函數(shù)應(yīng)當(dāng)有 BOOL 來型的返回值以及匹配事件的參數(shù)。當(dāng)事件函數(shù)被處理則返回 TRUE

             

             

            vtsParams

             

             

              VTS_ constants 的類型

             

             

            你引剛才用 END_EVENTSINK_MAP 宏.完整的定義如下:

            												
            														BEGIN_EVENTSINK_MAP(CMyDlg, CDialog)
            												
            										
            												
            														
            																
            																		   ON_EVENT(CMyDlg, IDC_WEBBROWSER, DISPID_DOWNLOADCOMPLETE, 
            														
            												
            										
            												
            														
            																
            																		            OnDownloadComplete, VTS_NONE)
            														
            												
            										
            												
            														END_EVENTSINK_MAP()
            												
            										

             

             

             

            對于 DocumentComplete 事件,你應(yīng)當(dāng)如下聲明:

            												
            														// Declare the event sink map.  This declaration goes
            												
            										
            												
            														// in the class declaration of CMFCIEEvtSpyDlg in the 
            												
            										
            												
            														// MFCIEEvtSpyDlg.h header file.
            												
            										
            												
            														//
            												
            										
            												
            														DECLARE_EVENTSINK_MAP()
            												
            										
            												
            														
            																 

             

            												
            														// Initialize the event sink map.  These macros
            												
            										
            												
            														// go in the implementation file _ MFCIEEvtSpyDlg.cpp.
            												
            										
            												
            														//
            												
            										
            												
            														BEGIN_EVENTSINK_MAP(CMFCIEEvtSpyDlg, CDialog)
            												
            										
            												
            														
            																
            																		   ON_EVENT(CMFCIEEvtSpyDlg, IDC_WEBBROWSER, DISPID_DOCUMENTCOMPLETE,
            														
            												
            										
            												
            														
            																
            																		            OnDocumentComplete, VTS_DISPATCH VTS_PVARIANT)
            														
            												
            										
            												
            														END_EVENTSINK_MAP()
            												
            										

            Figure 7-4. MFCIEEvtSpy.

            當(dāng)WebBrowser 控件基于對話框應(yīng)用,你通常不需要插入默認(rèn)的宏, 因?yàn)?ClassWizard 可為你做這一切.而在SDI或者M(jìn)DI工程中,需要加上此宏。

            現(xiàn)在事件接收映射已經(jīng)聲明, 每當(dāng)WebBrowser 控件激發(fā)了DocumentComplete 事件, OnDocumentComplete 方法將被調(diào)用.在CMFCIEEvtSpyDlgOnDocumentComplete 方法中, 包含URL和事件名稱的字符串被創(chuàng)建。之后字符串加入到列表框中展示W(wǎng)ebBrowser 控件的事件.

            以下代碼解釋如何接收處理DocumentComplete 事件.:

            												
            														void CMFCIEEvtSpyDlg::OnDocumentComplete(LPDISPATCH pDisp, VARIANT* URL)
            												
            										
            												
            														{
            												
            										
            												
            														
            																
            																		   USES_CONVERSION;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		   CString strEvt("DocumentComplete: ");
            														
            												
            										
            												
            														
            																
            																		   strEvt += OLE2T(URL->bstrVal);
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		   AddEventToList(WBListBox, strEvt);
            														
            												
            										
            												
            														}
            												
            										

            當(dāng)啟動后,采用CoCreateInstance 創(chuàng)建的ie實(shí)例傳遞LSID_InternetExplorer接口..

            以下為代碼:

            												
            														void CMFCIEEvtSpyDlg::OnStartIE() 
            												
            										
            												
            														{
            												
            										
            												
            														
            																
            																		   if (m_pInetExplorer == NULL)  // Can start only one instance
            														
            												
            										
            												
            														
            																
            																		   {
            														
            												
            										
            												
            														
            																
            																		      // Create an instance of Internet Explorer. 
            														
            												
            										
            												
            														
            																
            																		      //
            														
            												
            										
            												
            														
            																
            																		      HRESULT hr = CoCreateInstance(CLSID_InternetExplorer,
            														
            												
            										
            												
            														
            																
            																		                                    NULL,
            														
            												
            										
            												
            														
            																
            																		                                    CLSCTX_LOCAL_SERVER, 
            														
            												
            										
            												
            														
            																
            																		                                    IID_IWebBrowser2, 
            														
            												
            										
            												
            														
            																
            																		                                    (void**)&m_pInetExplorer);
            														
            												
            										
            												
            														
            																
            																		      if (SUCCEEDED(hr))
            														
            												
            										
            												
            														
            																
            																		      {
            														
            												
            										
            												
            														
            																
            																		         // Set up the event sink.
            														
            												
            										
            												
            														
            																
            																		         //
            														
            												
            										
            												
            														
            																
            																		         BOOL bAdvised = AfxConnectionAdvise(m_pInetExplorer, 
            														
            												
            										
            												
            														
            																
            																		                                DIID_DWebBrowserEvents2,
            														
            												
            										
            												
            														
            																
            																		                                m_pIE5Events->GetInterface(&IID_IUnknown),
            														
            												
            										
            												
            														
            																
            																		                                TRUE, &m_dwCookie);
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         // Disable the Start IE5 button so that the 
            														
            												
            										
            												
            														
            																
            																		         // user knows that only one instance of 
            														
            												
            										
            												
            														
            																
            																		         // Internet Explorer can be started at a time.
            														
            												
            										
            												
            														
            																
            																		         //
            														
            												
            										
            												
            														
            																
            																		         m_btnStartIE.EnableWindow(FALSE);
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		         // Make Internet Explorer visible and go home.
            														
            												
            										
            												
            														
            																
            																		         //
            														
            												
            										
            												
            														
            																
            																		         m_pInetExplorer->put_Visible(VARIANT_TRUE);
            														
            												
            										
            												
            														
            																
            																		         m_pInetExplorer->GoHome();
            														
            												
            										
            												
            														
            																
            																		      }
            														
            												
            										
            												
            														
            																
            																		   }
            														
            												
            										
            												
            														}
            												
            										

            為接收Internet Explorer 的事件,你應(yīng)當(dāng)聲明派遣接口且在實(shí)現(xiàn)文中:

            												
            														// Declare the dispatch map. This
            												
            										
            												
            														// declaration is placed in the class declaration
            												
            										
            												
            														// for the CIE5Events class, which is in the
            												
            										
            												
            														// CIE5Events.h header file.
            												
            										
            												
            														//
            												
            										
            												
            														DECLARE_DISPATCH_MAP()
            												
            										
            												
            														
            																 

             

            												
            														// Initialize the dispatch map in the
            												
            										
            												
            														// implementation file for CIE5Events _ CIE5Events.cpp.
            												
            										
            												
            														//
            												
            										
            												
            														BEGIN_DISPATCH_MAP(CIE5Events, CCmdTarget)
            												
            										
            												
            														
            																
            																		   DISP_FUNCTION_ID(CIE5Events, "DocumentComplete", 
            														
            												
            										
            												
            														
            																
            																		                    DISPID_DOCUMENTCOMPLETE, OnDocumentComplete, 
            														
            												
            										
            												
            														
            																
            																		                    VT_EMPTY, VTS_DISPATCH VTS_PVARIANT)
            														
            												
            										
            												
            														END_DISPATCH_MAP()
            												
            										

            現(xiàn)在無論如何接收到的自動化 Internet Explorer 的事件 DocumentComplete, OnDocumentComplete方法將被調(diào)用. OnDocumentComplete 方法創(chuàng)建一個包含事件名稱和URL的字符串,且加入到列表框通告Internet Explorer事件發(fā)生.同樣期它事件發(fā)生也會如此處理.此處為CIE5Events 類的OnDocumentComplete 方法代碼:

            												
            														void CIE5Events::OnDocumentComplete(LPDISPATCH pDisp, VARIANT* URL)
            												
            										
            												
            														{
            												
            										
            												
            														
            																
            																		   USES_CONVERSION;
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		   CString strEvt("DocumentComplete: ");
            														
            												
            										
            												
            														
            																
            																		   strEvt += OLE2T(URL->bstrVal);
            														
            												
            										
            												
            														
            																 

             

            												
            														
            																
            																		   m_pParent->AddEventToList(CMFCIEEvtSpyDlg::IE5ListBox, strEvt);
            														
            												
            										
            												
            														}
            												
            										

            posted on 2006-06-23 21:45 楊粼波 閱讀(2143) 評論(1)  編輯 收藏 引用 所屬分類: Windows編程

            評論

            # re: 如何對webbrowser和IE編程(九) 2009-07-07 19:10

            你排版太惡心了
              回復(fù)  更多評論   

            2021国产精品午夜久久| www.久久热.com| 久久99精品久久久久久hb无码| 国产成人精品免费久久久久| 国产精品青草久久久久福利99| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 亚洲国产成人久久一区WWW| 一本色道久久HEZYO无码| 久久综合丁香激情久久| 色青青草原桃花久久综合| 俺来也俺去啦久久综合网| 久久免费国产精品| 久久精品99久久香蕉国产色戒 | 久久av无码专区亚洲av桃花岛| 2021国产成人精品久久| 久久久久亚洲AV片无码下载蜜桃| 国产精品久久久久…| 亚洲精品第一综合99久久| 国产精品久久久久…| 国内精品综合久久久40p| 国产午夜精品久久久久九九| 亚洲色大成网站www久久九| 久久精品无码免费不卡| 国产精品美女久久久久| 久久伊人精品一区二区三区| 久久香蕉一级毛片| 亚洲AV无码久久寂寞少妇| 少妇久久久久久被弄到高潮| 久久国产精品久久| 亚洲中文字幕无码久久精品1| 久久成人永久免费播放| 国产精品久久午夜夜伦鲁鲁| 久久这里只有精品首页| 久久99精品国产麻豆不卡| 精品国产福利久久久| 亚洲中文字幕无码久久综合网| 热RE99久久精品国产66热| 青青热久久综合网伊人| 国内精品久久久久影院优| 国内精品人妻无码久久久影院导航| 久久无码精品一区二区三区|