青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

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

如何對webbrowser和IE編程(九)

接收事件的途徑

依靠開發工具你創建客戶應用程序,你可以接收事件通過不同的途徑. 顯然, 在Vb中接收事件同在VC中接收事件相比是如此不同和容易.在 C++ 應用中,你可以用不同的技術,通過使用 ATL, MFC, 或者標準C++.

Visual Basic 中接收事件

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

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

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

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

Dim WithEvents InternetExplorer1 As InternetExplorer

下一步,采用new或者其他 關鍵字創建實例變量 ,如下:

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

或者:

Set InternetExplorer1 = New InternetExplorer

當你采用以上途徑生成實例接收事件, Visual Basic 自動為你初始化和管理事件接收.你不必擔心連接點問題,VB為你處理它們.

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

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

當你不再想接收來自服務器的事件,簡單設置變量為Nothing:

Set InternetExplorer1 = Nothing

 

C++中接收事件

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

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

2.        調用 IconnectionPointContainer 的方法 FindConnectionPoint 找出你想接收的事件。對 Internet Explorer 來講 , 你應當為 DWebBrowserEvents2 連接點接口實現事件 . ( 作為可選 , 你可以調用 EnumConnectionPoints 以枚舉服務器支持的全部連接點 )

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

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

5.        當你不再接受事件,調用 Unadvise , 并且傳遞 cookie.

以上步驟如果采用VB和MFC \ATL等可能不很明顯,但是當你采用標準C++創建應用程序的時候就應當很明顯了.

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

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

    
if (SUCCEEDED(hr))
    
{
        
// m_pConnectionPoint is defined like this:
        
// IConnectionPoint* m_pConnectionPoint;
        
        
// Step 2: 選找連接點.
        
//
        hr = pCPContainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &m_pConnectionPoint);
        
if (SUCCEEDED(hr))
        
{
            
// Step 3: 實現連接點地事件接收
            
//
            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 應當在CSomeClass的析構函數中釋放
    
//
    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 方法實現. 我將很快討論此點. 每一次服務器激發事件會調用此. 當事件被激發,服務器傳遞事件的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

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

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

pDispParams 輸入參數是指向容器結構的指針, 存儲事件激發時的其他項. 傳遞到事件句柄的參數存儲在pDispParams->rgvarg ,逆序存放. 舉例來說, Internet Explorer 激發NavigateComplete2 事件如下所示:

NavigateComplete2(pDisp, URL)

Invoke 被調用, pDispParams->cArgs 將包含兩個值, URL 參數在 pDispParams->rgvarg[0] 以及pDisp 參數存儲在 pDispParams->rgvarg[1]. 這些就是COM次序傳遞參數給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中接收事件

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

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

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

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

四個參數傳遞給AtlAdvise. 第一個參數是指向可連接對象的IUnknown 接口的指針. m_spInetExplorer 數據成員是一個經過我們自動化當前運行的Internet Explorer實例的指針. 因為m_spInetExplorer 指向的對象直接或者間接繼承自IUnknown, 編譯器自動轉換m_spInetExplorer 為當前運行的 IE實例的IUnknown 接口指針.

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

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

最后一個參數指向DWORD的指針,該DWORD接收返回的Cookie. 該 cookie 將用于調用 AtlUnadvise.

客戶必須實現 IDispatch::Invoke 以控制Internet Explorer 激發的事件. 當你的應用程序完成從IE接收事件, 只需要調用 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 調用以接收事件, 如下:

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

CIEEvtObj 類繼承自IDispatch,所以 CIEEvtObj 類可以作為事件接收對象. Invoke 實現控制事件. 每當Internet Explorer 激發一個事件, 在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;
														
												
										
												
														}
												
										

請注意此使用了標準C++ 庫的 strstream 類來建立字符串.這么做是因為ATL 不提供像Cstring的類. 每一次從IE接收到事件,建立一個包含事件的名稱和參數的字符串. 然后顯示在列表框中.

退出時候調用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提供了數個宏使得你可以接收從自動化的對象或者宿主的控件的事件。在兩種情況中, 接收事件的類必須直接或者間接繼承自CCmdTarget. CCmdTarget 實現接收事件的IDispatch 接口. 另外, 你必須在你的應用中調用EnableAutomation 初始化包含在CCmdTarget 中的IDispatch.

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

mfc中接收事件很容易.全部要做的就是在代碼中調用AfxConnectionAdvise 函數以通告連接點客戶需要接收事件.當客戶不許要接收事件,調用AfxConnectionUnadvise.  AfxConnectionAdvise AfxConnectionUnadvise 函數定義于afxctl.h 頭文件。

AfxConnectionAdvise 函數查詢連接點容器, 尋找可連接點,并且通告連接點. 函數的5個參數如下:

Table 7-3 Parameters of the AfxConnectionAdvise Function

Parameter

 

 

Description

 

 

pUnkSrc

 

 

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

 

 

pUnkSink

 

 

指向事件接收的 IUnknown 接口

 

 

iid

 

 

連接點的 IID. 例如對 IE 來說,是 DIID_DWebBrowserEvents2 .

 

 

bRefCount

 

 

傳遞 TRUE 表示建立連接點將導致 pUnkSink 的引用將增加。 FALSE 表示不會增加 .

 

 

pdwCookie

 

 

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

 

 

 

 

 

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

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

												
														BEGIN_DISPATCH_MAP(CEventSink, CCmdTarget)
												
										

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

Table 7-4 Parameters of the DISP_FUNCTION_ID Macro

Parameter

 

 

Description

 

 

theClass

 

 

事件類的名稱

 

 

szExternalName

 

 

函數的名字 .

 

 

dispid

 

 

事件的 DISPID

 

 

pfnMember

 

 

指向處理事件的成員函數 .

 

 

vtRetval

 

 

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

 

 

vtsParams

 

 

空格分隔的參數類型的列表 .

 

 

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

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

最終采用 END_DISPATCH_MAP宏關閉.完整如下:

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

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

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

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

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

												
														BEGIN_EVENTSINK_MAP(CMyDlg, CDialog)
												
										

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

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

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

Table 7-5 Parameters of the ON_EVENT Macro

Parameter

 

 

Description

 

 

theClass

 

 

在那個類中接收事件

 

 

id

 

 

控件的資源 ID

 

 

dispid

 

 

有控件激活的事件的 ID.

 

 

pfnHandler

 

 

事件的成員函數,用來處理事件句柄 . 此函數應當有 BOOL 來型的返回值以及匹配事件的參數。當事件函數被處理則返回 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 事件,你應當如下聲明:

												
														// 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.

WebBrowser 控件基于對話框應用,你通常不需要插入默認的宏, 因為 ClassWizard 可為你做這一切.而在SDI或者MDI工程中,需要加上此宏。

現在事件接收映射已經聲明, 每當WebBrowser 控件激發了DocumentComplete 事件, OnDocumentComplete 方法將被調用.在CMFCIEEvtSpyDlgOnDocumentComplete 方法中, 包含URL和事件名稱的字符串被創建。之后字符串加入到列表框中展示WebBrowser 控件的事件.

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

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

 

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

 

												
														
																
																		   AddEventToList(WBListBox, strEvt);
														
												
										
												
														}
												
										

當啟動后,采用CoCreateInstance 創建的ie實例傳遞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 的事件,你應當聲明派遣接口且在實現文中:

												
														// 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()
												
										

現在無論如何接收到的自動化 Internet Explorer 的事件 DocumentComplete, OnDocumentComplete方法將被調用. OnDocumentComplete 方法創建一個包含事件名稱和URL的字符串,且加入到列表框通告Internet Explorer事件發生.同樣期它事件發生也會如此處理.此處為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 楊粼波 閱讀(2170) 評論(1)  編輯 收藏 引用 所屬分類: Windows編程

評論

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

你排版太惡心了
  回復  更多評論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲欧美日韩一区在线| 国产综合欧美| 亚洲欧美国产一区二区三区| 日韩一区二区高清| 一区二区欧美日韩视频| 亚洲精品中文字幕在线| 一区二区三区视频在线看| 亚洲视频你懂的| 亚洲特级毛片| 久久久久久伊人| 欧美va天堂va视频va在线| 欧美日韩免费观看一区=区三区| 国产精品av一区二区| 国产亚洲一级| 亚洲国产精品高清久久久| 一本久道综合久久精品| 久久精品国产一区二区三区| 欧美电影免费观看大全| 一区二区高清在线| 久久在线91| 国产精品色网| 亚洲看片网站| 久久久精品国产一区二区三区 | 久久久久久久综合| 欧美激情中文字幕在线| 亚洲欧美在线另类| 欧美精品日韩| 激情综合电影网| 亚洲欧美成人综合| 亚洲激情啪啪| 亚洲欧美综合v| 欧美精品v日韩精品v韩国精品v | 久久精品二区亚洲w码| 母乳一区在线观看| 亚洲欧美日韩精品一区二区| 欧美丰满少妇xxxbbb| 国产主播一区二区三区| 宅男66日本亚洲欧美视频| 久久久久久久久久久一区| 日韩视频免费在线| 亚洲美女色禁图| 国产精品区免费视频| 亚洲黄页视频免费观看| 久久精品二区| 亚洲视频碰碰| 欧美日韩一区三区| 亚洲激情视频| 久久综合九色九九| 亚洲一区二区四区| 国产精品爱啪在线线免费观看| 亚洲高清二区| 久久人人97超碰国产公开结果| 一区二区三区 在线观看视频| 欧美成人久久| 亚洲片区在线| 亚洲国产毛片完整版| 久久精品视频va| 国外成人在线| 麻豆精品网站| 久久久夜精品| 在线观看福利一区| 欧美成人资源网| 蜜臀久久久99精品久久久久久| 伊人久久综合97精品| 麻豆久久精品| 久久永久免费| 亚洲精品一区在线| 亚洲毛片一区二区| 国产精品区一区二区三区| 亚洲在线观看免费视频| 亚洲视频精选| 国产麻豆精品视频| 久久精品亚洲| 久久亚洲国产精品日日av夜夜| 在线观看的日韩av| 亚洲国产清纯| 欧美系列精品| 久久久天天操| 欧美国产日产韩国视频| 99re成人精品视频| 亚洲视频在线观看网站| 国产老肥熟一区二区三区| 久久久www免费人成黑人精品| 久久国产99| 亚洲美女色禁图| 亚洲与欧洲av电影| 在线日韩欧美视频| 亚洲最新中文字幕| 国产一区二区三区久久悠悠色av| 麻豆精品在线观看| 欧美激情亚洲另类| 久久精品视频免费| 欧美日韩人人澡狠狠躁视频| 久久国产日韩| 欧美区国产区| 久久久欧美精品| 欧美四级电影网站| 久久免费高清视频| 国产精品国产三级国产普通话三级| 欧美中在线观看| 免费成人小视频| 性欧美videos另类喷潮| 六月婷婷久久| 久久综合中文| 玖玖综合伊人| 亚洲欧美日韩在线综合| 久久精品日韩欧美| 亚洲欧美日韩中文播放| 蜜臀av一级做a爰片久久 | 91久久在线播放| 亚洲天堂av高清| 亚洲日本成人在线观看| 欧美一区网站| 亚洲午夜国产一区99re久久| 久久性色av| 久久爱www久久做| 欧美日韩人人澡狠狠躁视频| 欧美成人国产| 国产亚洲一区二区三区在线播放| 亚洲国产精品久久91精品| 国产性猛交xxxx免费看久久| 亚洲人精品午夜| 最新亚洲电影| 巨乳诱惑日韩免费av| 麻豆成人在线观看| 好吊视频一区二区三区四区| 亚洲视频每日更新| 亚洲欧美一区二区视频| 欧美午夜不卡视频| 99精品欧美| 亚洲专区一区二区三区| 欧美天天影院| 夜夜精品视频一区二区| 99视频国产精品免费观看| 美女日韩欧美| 欧美高清视频www夜色资源网| 激情欧美国产欧美| 久色成人在线| 亚洲国产欧美精品| 99国产精品久久久久久久久久| 欧美va天堂va视频va在线| 欧美国产亚洲精品久久久8v| 在线观看亚洲精品| 麻豆freexxxx性91精品| 欧美激情一区二区久久久| 亚洲国产婷婷综合在线精品 | 老司机免费视频久久| 国产一区二区精品久久99| 欧美综合国产精品久久丁香| 久久婷婷国产综合精品青草| 国产主播一区二区三区| 久久尤物电影视频在线观看| 91久久国产综合久久91精品网站| 日韩网站在线看片你懂的| 欧美性猛交xxxx免费看久久久| 在线综合亚洲| 久久全球大尺度高清视频| 亚洲国产合集| 欧美午夜欧美| 久久riav二区三区| 亚洲日本视频| 久久国产高清| 在线观看中文字幕不卡| 欧美成人乱码一区二区三区| 宅男噜噜噜66国产日韩在线观看| 性欧美大战久久久久久久免费观看 | 欧美一级精品大片| 一区二区视频在线观看| 欧美成人网在线| 9国产精品视频| 久久综合中文字幕| 宅男在线国产精品| 国产有码一区二区| 欧美日本一道本在线视频| 午夜精品免费在线| 亚洲精品在线观| 麻豆久久久9性大片| 99re6热在线精品视频播放速度| 国产精品亚洲美女av网站| 久久久夜精品| 亚洲欧美日韩成人| 亚洲国产欧美国产综合一区| 欧美一区三区二区在线观看| 亚洲美女在线观看| 国产欧美一区二区精品忘忧草| 免费一区二区三区| 久久精品国产欧美亚洲人人爽| 日韩视频在线免费| 欧美激情自拍| 久久婷婷av| 欧美一二三区在线观看| 日韩西西人体444www| 国产在线视频欧美一区二区三区| 欧美日韩一区二区三区视频| 美女被久久久| 久久精品夜色噜噜亚洲a∨| 亚洲一区二区三区四区在线观看| 亚洲激情图片小说视频| 欧美aⅴ一区二区三区视频| 久久精品国产成人|