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

牽著老婆滿街逛

嚴以律己,寬以待人. 三思而后行.
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>
            欧美国产日本高清在线| 亚洲电影成人| 国产伦一区二区三区色一情| 欧美午夜精品| 国产精品视频久久| 国产亚洲一本大道中文在线| 国产日韩欧美在线一区| 狠狠色丁香久久婷婷综合丁香| 国外视频精品毛片| 亚洲国产美女久久久久| 亚洲美女一区| 亚洲欧美综合v| 久久久夜夜夜| 亚洲精品自在在线观看| 亚洲欧美日韩区| 久久久久久久尹人综合网亚洲| 男女激情视频一区| 国产精品久久久久一区二区| 国产一区二区三区精品欧美日韩一区二区三区 | 另类图片综合电影| 欧美日韩精品免费看| 国产伦精品一区二区三区视频孕妇 | 亚洲欧美在线视频观看| 久久久久久久999精品视频| 欧美精选一区| 国产亚洲美州欧州综合国| 亚洲精品免费一二三区| 欧美日韩精品中文字幕| 国产乱码精品一区二区三| 伊人久久男人天堂| 亚洲一区二区三区成人在线视频精品 | 一区二区三欧美| 久久精品亚洲一区二区三区浴池| 亚洲第一伊人| 久久久久青草大香线综合精品| 欧美三级韩国三级日本三斤| 在线不卡中文字幕| 欧美一级在线视频| 免费欧美在线| 午夜视频久久久久久| 欧美日韩亚洲91| 亚洲欧洲日韩综合二区| 久久久久一区二区三区四区| 一区二区欧美激情| 欧美刺激性大交免费视频| 狠狠色综合色区| 欧美一区二区三区免费视频| 一区二区免费在线播放| 欧美日韩成人在线播放| 亚洲人成高清| 亚洲第一精品在线| 久久欧美中文字幕| 国模精品一区二区三区色天香| 亚洲欧美日韩精品久久久| 亚洲精品国产品国语在线app| 久久资源av| 亚洲大片免费看| 免费亚洲网站| 久久影视精品| 亚洲国产aⅴ天堂久久| 免费成人黄色片| 久久久久久综合| 亚洲国产精品v| 亚洲国产高清在线观看视频| 欧美大学生性色视频| 日韩视频一区| 99re6热在线精品视频播放速度| 欧美国产91| 一本色道久久综合精品竹菊 | 亚洲精品黄网在线观看| 欧美风情在线| 欧美精品在线一区| 亚洲欧美国产日韩天堂区| 亚洲永久精品大片| 国产视频一区欧美| 久久视频这里只有精品| 久久影视精品| 亚洲视频在线观看三级| 亚洲欧美综合| 亚洲国产mv| 99精品欧美一区二区三区 | 欧美吻胸吃奶大尺度电影| 亚洲视频一区二区免费在线观看| 亚洲视频一二区| 红桃视频亚洲| 亚洲精品久久久久久久久久久| 欧美日韩岛国| 久久国产一区二区| 蜜桃av一区| 亚洲在线黄色| 久久久噜久噜久久综合| 中文精品在线| 久久久久久久综合色一本| 99ri日韩精品视频| 亚洲免费一区二区| 亚洲第一区在线观看| 在线亚洲免费视频| 亚洲国产成人精品女人久久久 | 久久精品一区二区| 亚洲免费观看高清完整版在线观看熊| 亚洲日本国产| 激情五月***国产精品| 亚洲精品国产精品国自产在线| 国产欧美精品一区aⅴ影院| 亚洲高清一区二区三区| 国产欧美日韩视频| 91久久精品久久国产性色也91| 国产精品亚洲人在线观看| 亚洲第一精品久久忘忧草社区| 国产日韩精品久久| 日韩五码在线| 亚洲欧洲精品一区| 久久精品毛片| 欧美在线亚洲在线| 欧美色欧美亚洲高清在线视频| 另类天堂av| 国产精品亚洲成人| 一区二区三区日韩精品视频| 亚洲黄一区二区三区| 欧美中文字幕在线播放| 亚洲欧美视频在线观看视频| 欧美国产日韩在线观看| 免费试看一区| 韩国精品主播一区二区在线观看| 一区二区三区精品国产| 99在线视频精品| 欧美激情视频免费观看| 欧美国产精品久久| 在线电影院国产精品| 久久成人综合视频| 久久久噜噜噜久久中文字幕色伊伊| 欧美日韩专区在线| 日韩一区二区免费看| 亚洲一区综合| 国产精品女主播| 亚洲午夜激情在线| 性感少妇一区| 国产婷婷色综合av蜜臀av| 午夜视频在线观看一区二区| 午夜在线精品| 国产日韩欧美综合一区| 国产综合色产| 看片网站欧美日韩| 西瓜成人精品人成网站| 欧美日韩黄视频| 亚洲精品欧洲| 日韩系列在线| 欧美日韩亚洲一区在线观看| 亚洲人成人一区二区在线观看| 亚洲片在线观看| 欧美精品日韩综合在线| av不卡在线看| 久热国产精品| 日韩视频亚洲视频| 欧美日韩亚洲高清| 在线一区二区日韩| 亚洲黄一区二区| 欧美在线日韩精品| 欧美精品激情在线观看| 国内偷自视频区视频综合| 亚洲日本一区二区三区| 久久久久久久网站| 亚洲国产精品电影| 亚洲一级一区| 欧美插天视频在线播放| 国产精品一区免费观看| 亚洲电影免费观看高清| 亚洲在线播放| 欧美激情综合在线| 在线观看国产精品淫| 亚洲人成网站影音先锋播放| 国产亚洲精品久久久久婷婷瑜伽| 久久爱www久久做| 亚洲人成在线观看| 麻豆九一精品爱看视频在线观看免费| 欧美日韩一区二区精品| 国产精品久久福利| 极品中文字幕一区| 国产综合久久| 免费成人在线观看视频| 亚洲人成人一区二区三区| 久久国产欧美精品| 99re亚洲国产精品| 黑人一区二区三区四区五区| 欧美日本一区二区视频在线观看| 午夜天堂精品久久久久 | **性色生活片久久毛片| 欧美日韩中文字幕在线| 久久综合中文色婷婷| 亚洲一区二区欧美| 亚洲欧洲一级| 你懂的成人av| 久久精品亚洲国产奇米99| 99综合在线| 亚洲激情精品| 国内精品久久久久久影视8| 玖玖国产精品视频| 欧美一区二区三区久久精品| 一区二区三区视频在线播放| 亚洲国产精品嫩草影院|