您目前已離線,請等候您的網際網路重新連線

AtlEvnt.exe 範例會示範如何使用 ATL IDispEventImpl 和 IDispEventSimpleImpl 類別建立 ATL 接收

請注意--重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,且可能由 Microsoft Community 利用 Community Translation Framework技術或人工進行事後編修。翻譯過程並無專業譯者參與。Microsoft 同時提供使用者人為翻譯、機器翻譯及社群編修後的機器翻譯三種版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,所有翻譯文章都可能不盡完美,內容都可能出現詞彙、語意或文法上的錯誤。就翻譯內容之不正確或錯誤,或客戶因使用翻譯內容所產生的任何損害,微軟不負擔任何責任。Microsoft將依合理的商業努力不斷地更新機器翻譯軟體和工具,以期能為使用者提供更好的服務。

按一下這裡查看此文章的英文版本:194179
Microsoft Visual C++.NET (2002) 與 Microsoft Visual C++.NET(2003) 支援這兩種.NET 所提供的 managed 程式碼模型架構並不受管理的原生 Windows 程式碼模型。在此資訊發行項會套用至 unmanaged Visual C++ 的程式碼只。
結論
AtlEvnt.exe 會告訴您,如何實作事件接收使用ATL IDispEventImpl 和 IDispEventSimpleImpl 類別。對於複合控制項或 ATL 對話方塊精靈可將插入 IDispEventImpl 繼承清單中設定接收。本範例的重點在於能夠建立其他類型的接收所以COM 物件和用戶端。這是唯一可套用到來源介面的請輸入分配介面。

當您具有存取權,請使用 IDispEventImpl型別程式庫。當您沒有存取權類型,請使用 IDispEventSimpleImpl媒體櫃或當您要藉由不載入型別程式庫是較有效率。

除了此範例中,[其他資訊] 區段的連結本文包含有關如何與專案的概觀實作每個類別。
其他相關資訊
[下列檔案是可以從 Microsoft 下載下載中心:

Visual C++.NET

發行日期: 2002 年 6 月 25日日

如需有關如何下載 Microsoft 支援檔的詳細資訊,請按一下下面的文件編號,檢視 「 Microsoft 知識庫 」 中的文件:
119591 如何從線上服務取得 Microsoft 的支援檔案
Microsoft 掃描這個檔案有無病毒。Microsoft 會使用檔案公佈當日所能取得最新病毒偵測軟體。檔案儲存在加強保全的伺服器上,隔絕任何非法的變更檔案。 [ATLEVNT] 工作區所組成這兩個專案,AtlEvnt 和 EventSrc。當您執行 AtlEvnt.exe 時,請使用-d 選項:
AtlEvnt.exe-d

專案概觀

[AtlEvnt] 工作區所組成的兩個專案 AtlEvnt 和EventSrc。

EventSrc 專案是預設的 ATL DLL 專案以內「 簡單物件 」。簡單的物件沒有方法,並已被修改,支援連接點和 IPersist 介面。COM 物件公開 (expose)(下) 的預設值來源介面具有單一方法呼叫刻度。COM物件會連接到它,以計時器為基礎的所有接收物件上呼叫這個方法:
   dispinterface _EventSink   {      properties:      methods:      [id(1), helpstring("method Tick")] HRESULT Tick([in] long tckcnt);   }				
AltEvnt 的專案是 ATL EXE 專案。ATL CDialogImpl 類別都是加入將專案轉變為簡單的對話方塊應用程式。四種接收器已加入至專案 (兩個使用 IDispEventImpl 和兩個使用中IDispEventSimpleImpl)。每一個接收說明提供不同的方式若要處理的 EventSrc COM 物件所引發的 Tick 事件接收器物件。

這個對話方塊有四個按鈕,並按下按鈕讓正在連接 EventSrc COM 物件的相對應的接收。清單方塊顯示表單的字串"Sinkn: Tick 事件接收到-x 」 每次滴答在接收器事件處理常式會呼叫。一旦建立連線時,已停用] 按鈕。如果沒有建立該連線會再有問題按鈕文字會取代表單"連線 Err-hr"的字串,其中"hr"代表失敗的 HRESULT。使用附隨於 「 錯誤查詢"工具Visual C++,以取得錯誤的說明的 6.0 版。

若要執行這個範例,第一次建置 EventSrc 專案,並確保 EventSrc 物件成功地登錄。然後建置 AtlEvnt 專案,並執行它。對話方塊有四個按鈕 (除了 [確定] 和 [取消]) 方塊和清單方塊隨即出現。四個按鈕都代表四種接收器。按下按鈕,會連接到接收來源。一旦連線之後,將字串加入至清單方塊每個會呼叫處理常式的時間。

若要實作 IDispEventImpl 的步驟

  1. 建立新的類別衍生自 IDispEventImpl。您可以按一下 新的類別 在上 插入 若要產生新的類別的功能表。針對每個不同的面盆,新增IDispEventImpl 類別,以與唯一的 ID,作為第一的繼承清單參數。接收器類別可以是 COM 物件 (如下所示將複合稿控制項) 或只是從 IdispEventImpl 衍生的類別:
    // Just a sink.      class CSinkObj : public IDispEventImpl<IDC_OBJ, CSinkObj>      {         ...      }
    -或者-
    // COM object that also implements a sink (as in a composite      // control).      class ATL_NO_VTABLE CSinkObj :         public CComObjectRootEx<CComSingleThreadModel>,         public CComCoClass<CSinkObj, &CLSID_SinkObj>,         public IDispatchImpl<ISinkObj, &IID_ISinkObj, &LIBID_SINKPROJLib>,         public IDispEventImpl<IDC_SRCOBJ, CSinkObj>      {         ...      }
  2. 您可以指定的來源介面 ID 型別程式庫 ID,主要和次要版本號碼,包含您建立的型別程式庫做為參數的 IdispEventImpl,明確地來源介面相同,或是使用若要從型別擷取這項資訊的 AtlGetObjectSourceInterface()文件庫。使用 AtlGetObjectSourceInterface() 的所需的 COM 物件引發事件實作 IProvideClassInfo2 或 IPersist * 可能是:
    class CSinkObj : public IDispEventImpl<IDC_OBJ, CSinkObj>      {         ...      }
    -或者-
    class CSinkObj : public IDispEventImpl<IDC_OBJ, CSinkObj,         &DIID__EventSink, // Source interface GUID.         &LIBID_COMOBJLib, // typelib ID containing source interface.         1,                // Major version # of LIBID_COMOBJLib.         0>                // Minor version # of LIBID_COMOBJLib.      {         ...      }
  3. 將接收對應加入至上述的類別以及接收項目對應到您想要的來源介面的每個事件控制代碼。當來源介面指定為使用 SINK_ENTRY_EX()中 IDispEventImpl,否則參數會使用 SINK_ENTRY():
    class CSinkObj : public IDispEventImpl<IDC_SRCOBJ, CSinkObj>      {      public:         BEGIN_SINK_MAP(CSinkObj)            SINK_ENTRY(IDC_SRCOBJ, 1 /*DISPID*/, OnTick /*Event Handler*/)         END_SINK_MAP()         ...      }
    -或者-
    class CSinkObj : public IDispEventImpl<IDC_OBJ, CSinkObj,                              &DIID__EventSink, &LIBID_COMOBJLib, 1, 0>      {      public:         BEGIN_SINK_MAP(CSinkObj)            SINK_ENTRY_EX(IDC_SRCOBJ, DIID__EventSink, 1, OnTick)         END_SINK_MAP()         ...      }
  4. 將事件處理常式方法加入至您的類別。請確定它們有 __stdcall 呼叫慣例:
    class CSinkObj : public IDispEventImpl<IDC_SRCOBJ, CSinkObj3>      {      public:         BEGIN_SINK_MAP(CSinkObj)            SINK_ENTRY(IDC_SRCOBJ, 1 , OnTick)         END_SINK_MAP()         // event handler for event defined in idl as         // [id(1)] HRESULT Tick([in] long tckcnt);         HRESULT __stdcall OnTick(long tickcnt)         {            ATLTRACE("CSinkObj::OnTick\n");            return S_OK;         }         ...      }
  5. 藉由呼叫連接至 COM 物件的接收器DispEventAdvise()。如果來源介面指定當做參數然後呼叫 IDispEventImpl:
    // pUnk is the IUnknown pointer of the COM object that fires events.   // pSinkObj is an instance of the CSinkObj class.      pSinkObj->DispEventAdvise(pUnk);
    否則呼叫:
    // Make sure the COM object corresponding to pUnk implements      // IProvideClassInfo2 or IPersist*.      // Call this method to extract info about source type library if you      // specified only two parameters to IdispEventImpl.      AtlGetObjectSourceInterface(pUnk, &pSinkObj->m_libid,         &pSinkObj->m_iid, &pSinkObj->m_wMajorVerNum,         &pSinkObj->m_wMinorVerNum);      hr = pSinkObj->DispEventAdvise(pUnk, &pSinkObj->m_iid);
  6. 藉由呼叫 DispEventUnadvise(),中斷連線,接收:
    pSinkObj->DispEventUnadvise(pUnk);

若要實作 IDispEventSimpleImpl 的步驟

  1. 建立從 IDispEventSimpleImpl 衍生而來的類別。[必須指定來源介面。
  2. 請依照下列步驟 3 上面,只不過每張新增 SINK_ENTRY_INFO()您要處理的來源介面的方法。自IDispEventSimpleImpl 不具有存取,您需要的型別程式庫提供透過 _ATL_FUNC_INFO 的每個事件處理常式的相關資訊結構中,一個用於每個事件處理常式。

    而不是指定_ATL_FUNC_INFO 結構中 SINK_ENTRY_INFO(),您可以使用 SINK_ENTRY_EX()巨集,並覆寫虛擬函式來填入 GetFuncInfoFromId()_ATL_FUNC_INFO 結構中,如下列程式碼所示。
  3. 請遵循上述的步驟 4 到 6:
    static _ATL_FUNC_INFO OnTickInfo = {         CC_STDCALL,   // Calling convention.         VT_I4,        // Return type.         1,            // Number of arguments.         {VT_I4}       // Argument types.      };      class CSinkObj :         public IDispEventSimpleImpl<IDC_SRCOBJ, CSinkObj,                &DIID__EventSink>      {      public:      BEGIN_SINK_MAP(CSinkObj)         SINK_ENTRY_INFO(IDC_SRCOBJ, DIID__EventSink, 1, OnTick,                         &OnTickInfo)      END_SINK_MAP()         HRESULT __stdcall OnTick(long tickcnt)         {            ATLTRACE("CSinkObj::OnTick\n");            return S_OK;         }         ...      }
    -或者-
    class CSinkObj :         public IDispEventSimpleImpl<IDC_SRCOBJ, CSinkObj,                &DIID__EventSink>      {      public:      BEGIN_SINK_MAP(CSinkObj4)         SINK_ENTRY_EX(IDC_SRCOBJ, DIID__EventSink, 1, OnTick)         // Equivalent to:         // SINK_ENTRY_INFO(IDC_SRCOBJ, DIID__EventSink, 1, OnTick, NULL)      END_SINK_MAP()         HRESULT GetFuncInfoFromId(const IID& iid, DISPID dispidMember,            LCID lcid, _ATL_FUNC_INFO& info)         {            if (InlineIsEqualGUID(iid, DIID__EventSink))            {               info.cc = CC_STDCALL;               switch(dispidMember)               {                  case 1:                     info.vtReturn = VT_I4;                     info.nParams = 1;                     info.pVarTypes[0] =  VT_I4;                     return S_OK;                  default:                     return E_FAIL;               }            }            return E_FAIL;         }         HRESULT __stdcall OnTick(long tickcnt)         {            ATLTRACE("CSinkObj::OnTick\n");            return S_OK;         }         ...      }
参考
如需詳細資訊,按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件:
181277AtlSink 會使用 ATL 來建立一個分配介面接收
清單方塊 Atlevnt Atlevntvcnet

警告:本文為自動翻譯

內容

文章識別碼:194179 - 最後檢閱時間:06/28/2013 12:44:00 - 修訂: 5.0

Microsoft ActiveX Template Library 3.0

  • kbtshoot kbdownload kbactivexevents kbconnpts kbFAQ kbfile kbhowto kbsample kbmt KB194179 KbMtzh
意見反應