ActiveX控制項的MFC設計之旅-第16步

來源:互聯網
上載者:User
在VB的屬性視圖中,還有一個有意思的功能是將屬性列在不同的類別,如,外觀,行為,資料等等。這種功能是怎麼來的,我自己的控制項中的自訂的屬性是不是也能列在這些類別中,我能不能建立自己的類別呢。

很簡單,在你的控制項中實現一個介面ICategorizeProperties就可以了,這個介面只有兩個方法
        HRESULT MapPropertyToCategory(DISPID dispid, PROPCAT* ppropcat);
        HRESULT GetCategoryName(PROPCAT propcat, LCID lcid, BSTR* pbstrName);

PROPCAT實際上就是一int,表示某種類別編號
MapPropertyToCategory就是用來設定相應dispid的屬性的類別的
GetCategoryName應是用來設定你自訂的類別(編號為propcat)的顯示字串的

看起來似乎挺簡單的,可惜的是,這個介面沒有定義,COleControl也沒有幫我們做任何的工作。幸好,對於添加介面,我們已經有了經驗了,前面的文章有過許多例子了。

我們有上一文中的例子tppb

1.在.odl上添加新介面定義

    //  ICategorizeProperties介面定義
    [ uuid(4D07FC10-F931-11CE-B001-00AA006884E5),
      helpstring("ICategorizeProperties Interface"), pointer_default (unique) ]
    interface ICategorizeProperties : IUnknown
    {
        typedef [public] int PROPCAT;
        const int PROPCAT_Nil            = -1;
        const int PROPCAT_Misc            = -2;
        const int PROPCAT_Font            = -3;
        const int PROPCAT_Position        = -4;
        const int PROPCAT_Appearance    = -5;
        const int PROPCAT_Behavior        = -6;
        const int PROPCAT_Data            = -7;
        const int PROPCAT_List            = -8;
        const int PROPCAT_Text            = -9;
        const int PROPCAT_Scale            = -10;
        const int PROPCAT_DDE            = -11;
        HRESULT MapPropertyToCategory(DISPID dispid, PROPCAT* ppropcat);
        HRESULT GetCategoryName(PROPCAT propcat, LCID lcid, BSTR* pbstrName);
    };

2.添加嵌套類,作為ICategorizeProperties介面的實作類別
a.在tppbctl.h中添加聲明
......
    DECLARE_EVENT_MAP()

public:
    BEGIN_INTERFACE_PART(CategorizeProperties, ICategorizeProperties)
        STDMETHOD(MapPropertyToCategory)(DISPID dispid, PROPCAT* ppropcat);
        STDMETHOD(GetCategoryName)(PROPCAT propcat, LCID lcid, BSTR* pbstrName);
    END_INTERFACE_PART(CategorizeProperties)
    DECLARE_INTERFACE_MAP()
// Dispatch and event IDs
public:
    enum {
    //{{AFX_DISP_ID(CTppbCtrl)
    dispidWeek = 1L,
    dispidParam = 2L,
    //}}AFX_DISP_ID
    };
......
b.在tppbctl.cpp中添加實現代碼

STDMETHODIMP_(ULONG) CTppbCtrl::XCategorizeProperties::AddRef()
{
    METHOD_PROLOGUE_EX_(CTppbCtrl, CategorizeProperties)
    return (ULONG)pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG) CTppbCtrl::XCategorizeProperties::Release()
{
    METHOD_PROLOGUE_EX_(CTppbCtrl, CategorizeProperties)
    return (ULONG)pThis->ExternalRelease();
}

STDMETHODIMP CTppbCtrl::XCategorizeProperties::QueryInterface(REFIID iid, LPVOID* ppvObj)
{
    METHOD_PROLOGUE_EX_(CTppbCtrl, CategorizeProperties)
    return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}

STDMETHODIMP CTppbCtrl::XCategorizeProperties::MapPropertyToCategory(DISPID dispid, PROPCAT* ppropcat)
{
    METHOD_PROLOGUE_EX_(CTppbCtrl, CategorizeProperties)
    if(dispid == dispidWeek){
        *ppropcat = PROPCAT_Data;
        return S_OK;
    }
    else if(dispid == dispidParam){
        *ppropcat = 1;
        return S_OK;
    }
    return E_FAIL;
}

STDMETHODIMP CTppbCtrl::XCategorizeProperties::GetCategoryName(PROPCAT propcat, LCID lcid, BSTR* pbstrName)
{
    METHOD_PROLOGUE_EX_(CTppbCtrl, CategorizeProperties)
    if(propcat == 1){
        *pbstrName = ::SysAllocString(L"參數");
        return S_OK;
    }
    return E_FAIL;
}
註:這裡將Week屬性列入了資料類別(PROPCAT_Data)中,將Param屬性列入自訂的類別"參數"中,類別編號為1,對於自訂的類別編號,必須大於0

3.將ICategorizeProperties介面添加到控制項的介面映射表中
a.在tppbctl.h中添加介面映射聲明
public:
    BEGIN_INTERFACE_PART(CategorizeProperties, ICategorizeProperties)
        STDMETHOD(MapPropertyToCategory)(DISPID dispid, PROPCAT* ppropcat);
        STDMETHOD(GetCategoryName)(PROPCAT propcat, LCID lcid, BSTR* pbstrName);
    END_INTERFACE_PART(CategorizeProperties)
    DECLARE_INTERFACE_MAP()

b.在tppbctl.cpp中添加ICategorizeProperties到映射表中

BEGIN_INTERFACE_MAP(CTppbCtrl, COleControl)
    INTERFACE_PART(CTppbCtrl, IID_IDispatch, Dispatch)
    INTERFACE_PART(CTppbCtrl, DIID__DTppb, Dispatch)
    INTERFACE_PART(CTppbCtrl, IID_ICategorizeProperties, CategorizeProperties)
END_INTERFACE_MAP()

4.現在編譯的話,會發現少了很多的定義,需要從.odl中產生相應的介面定義檔案,在檔案清單中找到tppb.odl,點右鍵,選擇Settings,在Output header file name中輸入tppbuuid.h(不存在的任何檔案名稱都可),確定後,再點右鍵,選擇Compile tppb.odl,即產生tppbuuid.h檔案了。

5.在tppbctl.h檔案中#include "tppbuuid.h"

6.建立一initIIDs.cpp檔案,輸入代碼如下:
#include <ole2.h>
#include <initguid.h>
#include "tppbuuid.h"
在檔案清單中,找到initIIDs.cpp,點右鍵,在C/C++項中,選擇Category為Precompiled Headers,並設定為Not using precompiled headers

7.編譯,如果連結出現DllMain之類的錯誤,請移除initIIDs.cpp,然後再加入,並重新設定Precompiled Headers,再編譯即可。

8.好了,在VB下測試就可以了

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.