首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

向 CCmdTarget 派生類別新增介面實作:MFC 嵌套類別與介面映射機制深度解析

     編輯:VC 教學

背景與動機

在 COM 程式設計中,類別常需實作多個介面(如事件通知、連接點)。MFC 採用 嵌套類別 + 介面映射巨集 的方式,避免多重繼承的複雜性,並自動處理 IUnknown 的參考計數與 QueryInterface 轉發。

實作步驟範例:為 CSampleView 新增 IMyTest 介面

1. 標頭檔宣告

class CSampleView : public CView {
    DECLARE_INTERFACE_MAP()
    BEGIN_INTERFACE_PART(TestInterface, IMyTest)
        STDMETHOD(Test)();
    END_INTERFACE_PART(TestInterface)
    // ...
};

2. 實作檔定義介面映射與成員函數


BEGIN_INTERFACE_MAP(CSampleView, CCmdTarget)
    INTERFACE_PART(CSampleView, IID_IMyTest, TestInterface)
END_INTERFACE_MAP()

// IUnknown 轉發至 CCmdTarget
STDMETHODIMP_(ULONG) CSampleView::XTestInterface::AddRef() {
    METHOD_PROLOGUE_EX(CSampleView, TestInterface)
    return pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CSampleView::XTestInterface::Release() {
    METHOD_PROLOGUE_EX(CSampleView, TestInterface)
    return pThis->ExternalRelease();
}
STDMETHODIMP CSampleView::XTestInterface::QueryInterface(REFIID iid, LPVOID* ppvObj) {
    METHOD_PROLOGUE_EX(CSampleView, TestInterface)
    return pThis->ExternalQueryInterface(&iid, ppvObj);
}

// 介面實際方法
STDMETHODIMP CSampleView::XTestInterface::Test() {
    METHOD_PROLOGUE_EX(CSampleView, TestInterface)
    // 具體業務邏輯
    return S_OK;
}

核心巨集深度剖析

DECLARE_INTERFACE_MAP

宣告靜態介面映射表結構 _interfaceEntries[] 與 interfaceMap,並提供虛擬函數 GetInterfaceMap() 供執行期查詢。

BEGIN_INTERFACE_PART / END_INTERFACE_PART

定義嵌套類別 XTestInterface 繼承自 IMyTest,自動包含 AddRef、Release、QueryInterface 宣告,並在外層類別產生實例成員 m_xTestInterface。

BEGIN_INTERFACE_MAP / INTERFACE_PART / END_INTERFACE_MAP

建立介面映射表陣列,每筆記錄包含 IID 與嵌套類別在外層類別中的位移(offsetof)。CCmdTarget::ExternalQueryInterface 會遞迴搜尋此表以回傳正確介面指標。

METHOD_PROLOGUE_EX

關鍵巨集:從嵌套類別的 this 計算外層類別指標 pThis。原理:pThis = (外層類別*)((BYTE*)this - offsetof(外層類別, m_x嵌套類別))。

為什麼這樣設計?

  • 避免多重繼承菱形問題:嵌套類別各自單獨繼承介面,外層類別僅包含嵌套類別實例。
  • 自動處理 IUnknown:CCmdTarget 提供 ExternalAddRef/Release/QueryInterface,嵌套類別僅需轉發。
  • 類似訊息映射機制:介面映射表結構與訊息映射高度相似,學習成本低。

適用場景

ActiveX 控制項開發、連接點事件來源、自訂 COM 物件實作多介面等。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved