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

yehao's Blog

如何對webbrowser和IE編程(九)

目錄(?)[-]

  1. 接收事件的途徑
    1. Visual Basic 中接收事件
    2. C++中接收事件
    3. 在ATL中接收事件
    4. 在 MFC中接收事件
      1. 在MFC中自動化一個COM 對象時接收事件
      2. 在MFC中寄宿 ActiveX 控件時處理事件

接收事件的途徑

依靠開發工具你創建客戶應用程序,你可以接收事件通過不同的途徑. 顯然, 在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 處理從 VARIANT到 BSTR包裝.

#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提供了兩個函數—AtlAdvise 和 AtlUnadvise—使得任何課連接對象的事件接收簡單化.

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

讓我們行說吧, 舉個例子, 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提供了數個宏使得你可以接收從自動化的對象或者宿主的控件的事件。在兩種情況中, 接收事件的類必須直接或者間接繼承自CCmdTargetCCmdTarget 實現接收事件的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事件接收類必須繼承自CCmdTargetCCmdTarget 使用派遣映射檢測當接收到事件時調用處理函數.你必須首先在頭文件中聲明派遣映射 然后再實現文件中 (.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 方法將被調用.在CMFCIEEvtSpyDlg的 OnDocumentComplete 方法中, 包含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 2012-09-22 21:48 厚積薄發 閱讀(2500) 評論(0)  編輯 收藏 引用 所屬分類: Windows編程

導航

<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

統計

常用鏈接

留言簿

隨筆分類

文章分類

文章檔案

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲美女视频在线免费观看| 久久只精品国产| 亚洲免费激情| 亚洲欧美99| 免费一级欧美片在线观看| 亚洲精品1区2区| 在线亚洲电影| 久久精品人人做人人综合 | 久久精品视频免费观看| 欧美成人激情视频| 国产日韩欧美成人| 亚洲一区在线免费观看| 亚洲福利精品| 欧美专区中文字幕| 欧美日韩高清在线播放| 精品成人免费| 午夜欧美精品| 最新国产の精品合集bt伙计| 亚洲成人在线免费| 性伦欧美刺激片在线观看| 老**午夜毛片一区二区三区| 亚洲天堂第二页| 国产精品爱啪在线线免费观看| 亚洲剧情一区二区| 亚洲性人人天天夜夜摸| 伊人久久久大香线蕉综合直播| 久久精彩免费视频| 欧美福利视频网站| 亚洲国产综合91精品麻豆| 美日韩精品视频免费看| 欧美日韩亚洲成人| 日韩一级精品| 亚洲欧洲日夜超级视频| 国产亚洲毛片在线| 久久躁狠狠躁夜夜爽| 欧美午夜精品一区二区三区| 鲁大师影院一区二区三区| 国产精品九九久久久久久久| 午夜精品www| 欧美激情偷拍| 亚洲网站视频福利| 免费欧美电影| 国产精品手机视频| 久久综合九色综合久99| 国产精品久久国产三级国电话系列 | 久久国产精品网站| 亚洲福利视频二区| 亚洲国产精品www| 欧美日韩国产综合视频在线观看中文 | 国产精品www色诱视频| 欧美大片在线看免费观看| 欧美不卡三区| 欧美va亚洲va国产综合| 欧美日韩福利视频| 亚洲三级免费观看| 国产精品一区二区三区成人| 久久夜色精品国产亚洲aⅴ| 国产精品黄视频| 亚洲视频导航| 亚洲动漫精品| 蜜桃av一区二区三区| 日韩视频三区| 欧美激情女人20p| 亚洲国产日本| 日韩手机在线导航| 欧美精品激情| 亚洲精品在线免费| 国内精品免费午夜毛片| 亚洲精品乱码| 中文在线资源观看视频网站免费不卡| 免费国产自线拍一欧美视频| 亚洲欧美日韩在线综合| 国产精品igao视频网网址不卡日韩| 欧美国产免费| 久久综合九色| 亚洲福利视频三区| 欧美顶级艳妇交换群宴| 亚洲国产综合91精品麻豆| 亚洲伦理网站| 欧美午夜视频在线观看| 亚洲综合国产| 亚洲自拍偷拍福利| 国产女精品视频网站免费| 亚洲欧洲日本mm| 中国成人黄色视屏| 国产精品日韩精品| 久久精品免费| 最新日韩在线| 欧美一区二视频在线免费观看| 欧美激情影音先锋| 一本色道久久精品| 亚洲精品一区二区三区樱花| 欧美一级理论性理论a| 午夜精品久久久久| 国内免费精品永久在线视频| 欧美sm重口味系列视频在线观看| 日韩视频一区二区三区| 欧美在线观看视频在线| 亚洲啪啪91| 欧美国产欧美亚洲国产日韩mv天天看完整 | aa亚洲婷婷| 欧美成人69av| 亚洲一区二区三区成人在线视频精品 | 亚洲欧美日韩国产成人| 亚洲一区综合| 在线欧美日韩精品| 国产精品美女久久久久久久| 亚洲一区二区在| 欧美高清在线视频观看不卡| 亚洲午夜免费视频| 在线观看中文字幕亚洲| 欧美手机在线视频| 中文在线一区| 欧美激情一区二区三区蜜桃视频| 亚洲女同性videos| 日韩午夜激情电影| 黑人操亚洲美女惩罚| 久久色在线观看| 麻豆91精品91久久久的内涵| 亚洲色诱最新| 亚洲电影免费| 国产亚洲激情| 国产精品国产亚洲精品看不卡15| 久久天堂国产精品| 亚洲午夜久久久久久久久电影院| 亚洲福利免费| 欧美激情第1页| 久久久久久综合| 亚洲精品视频啊美女在线直播| 国产麻豆精品视频| 欧美性片在线观看| 欧美高清你懂得| 久久香蕉国产线看观看av| 午夜欧美视频| 亚洲国产美女久久久久| 免费看成人av| 亚洲国内欧美| 亚洲欧洲精品一区二区三区 | 亚洲视频综合| 夜夜嗨av一区二区三区网站四季av | 久久久国产精彩视频美女艺术照福利| 亚洲小说春色综合另类电影| 亚洲精品黄网在线观看| 亚洲国产一区二区精品专区| 欧美黄色小视频| 欧美成人在线免费视频| 米奇777超碰欧美日韩亚洲| 久久人人97超碰国产公开结果| 久久国产精品久久国产精品| 91久久精品国产91性色tv| 在线日韩av| 亚洲国产精品v| 亚洲美女电影在线| 一区二区日韩免费看| 日韩一区二区精品视频| 一区二区精品国产| 亚洲欧美在线免费观看| 亚欧成人在线| 老司机久久99久久精品播放免费| 蜜臀av性久久久久蜜臀aⅴ四虎 | 亚洲高清毛片| 99精品欧美一区二区三区综合在线| 日韩一区二区高清| 午夜免费在线观看精品视频| 久久久欧美精品sm网站| 欧美大色视频| 9l国产精品久久久久麻豆| 欧美激情bt| 一本色道久久综合亚洲精品小说| 亚洲一区在线免费| 久久精品中文| 欧美国产日韩视频| 国产精品久久久久久影视| 国产欧美综合一区二区三区| 影音欧美亚洲| 中文在线资源观看网站视频免费不卡 | 欧美va天堂| 国产精品日韩精品欧美在线| 在线电影院国产精品| 这里只有精品丝袜| 久久久蜜臀国产一区二区| 亚洲国产精品日韩| 亚洲欧美中文日韩v在线观看| 久久久xxx| 国产精品九九| 亚洲精品三级| 久久久久国产精品人| 久久美女性网| 一级成人国产| 裸体一区二区三区| 国产精品一区二区久久| 亚洲看片网站| 欧美超级免费视 在线| 亚洲性感激情| 欧美日韩成人网| 亚洲国产精品电影| 久久精品青青大伊人av| 99精品欧美一区二区蜜桃免费| 久久精视频免费在线久久完整在线看| 欧美三级免费|