ActiveX控件的MFC设计之旅-第15步

news/2024/11/24 7:50:03/
在VB和类似的包容器在属性视图中显示控件的属性,特别是枚举类型的属性时,会有一个下拉按钮,当点击该按钮时,会弹出一个列表框,显示一些友好的文字,供用户选择。而对于某些特殊的属性,如字体等,还会弹出一个对话框来供用户设置属性。

要添加这种功能,你必须实现 IPerPropertyBrowsing接口,
 typedef struct tagCALPOLESTR {
ULONG cElems;
OLECHAR ** pElems;
} CALPOLESTR;

typedef struct tagCADWORD {
ULONG cElems;
DWORD * pElems;
} CADWORD;

interface IPerPropertyBrowsing : IUnknown
{
HRESULT GetDisplayString(DISPID dispid, BSTR * lpbstr);
HRESULT MapPropertyToPage(DISPID dispid, CLSID *lpclsid);
HRESULT GetPredefinedStrings(DISPID dispid, CALPOLESTR *lpcasz,
CADWORD *lpcadw);
HRESULT GetPredefinedValue(DISPID dispid, DWORD dwCookie,
VARIANT *lpvarOut);
}

幸运的是,在用MFC设计ActiveX控件时,COleControl已经帮我们实现了这个接口,我们只需要重载COleControl的一些函数就可以实现我们所需要的功能了。这些函数是
    virtual BOOL OnGetDisplayString(DISPID dispid, CString& strValue);
    virtual BOOL OnGetPredefinedStrings(DISPID dispid, CStringArray* pStringArray, CDWordArray* pCookieArray);
    virtual BOOL OnGetPredefinedValue(DISPID dispid, DWORD dwCookie, VARIANT* lpvarOut);
    virtual BOOL OnMapPropertyToPage(DISPID dispid, LPCLSID lpclsid, BOOL* pbPageOptional);

分别和IPerPropertyBrowsing的四个接口方法一一对应。其中,前三个就是用来显示友好文字的列表框式的属性设置的,最后一个则是用来显示属性页对话框式的属性设置的。

注:VB首先查询控件的IPerPropertyBrowsing接口,以获得一个属性的显示字符串。当查询失败时,如果可能的话,VB会装载类型库并找到在IDL文件中为这个属性指定的枚举值。如果再次失败,VB会显示实际属性值。

1.建立控件Tppb,添加属性long Week
2.添加连续的7个字符串资源
IDS_WEEK_MONDAY,IDS_WEEK_TUESDAY,......IDS_WEEK_SUNDAY;
相应的字符串分别是
星期一,星期二,......星期日。
3.重载OnGetDisplayString,OnGetPredefinedStrings和OnGetPredefinedValue。

BOOL CTppbCtrl::OnGetDisplayString(DISPID dispid, CString& strValue)
{
    // TODO: Add your specialized code here and/or call the base class
    if(dispid == dispidWeek){
        strValue.LoadString(IDS_WEEK_MONDAY+m_week);
        return TRUE;
    }
    return COleControl::OnGetDisplayString(dispid, strValue);
}

BOOL CTppbCtrl::OnGetPredefinedStrings(DISPID dispid, CStringArray* pStringArray, CDWordArray* pCookieArray)
{
    // TODO: Add your specialized code here and/or call the base class
    if(dispid == dispidWeek){
        for(int i=0; i<7; i++){
            CString str;
            str.LoadString(IDS_WEEK_MONDAY+i);
            pStringArray->Add(str);
            pCookieArray->Add(i);
        }
        return TRUE;
    }
    return COleControl::OnGetPredefinedStrings(dispid, pStringArray, pCookieArray);
}

BOOL CTppbCtrl::OnGetPredefinedValue(DISPID dispid, DWORD dwCookie, VARIANT* lpvarOut)
{
    // TODO: Add your specialized code here and/or call the base class
    if(dispid == dispidWeek){
        VariantInit(lpvarOut);
        lpvarOut->vt = VT_I4;
        //和dwCookie一一对应,0号位值就是0,......,6号位的值就是6
        lpvarOut->lVal = dwCookie;
        return TRUE;
    }
    return COleControl::OnGetPredefinedValue(dispid, dwCookie, lpvarOut);
}

4.在VB中测试就可以看到Week属性会列出从星期一到星期日共七个选项的列表选择框。

5.添加属性long Param和固有属性Caption

6.新建一属性页(资源为IDD_PROPPAGE_TEST,类为CTestPropPage),属性页中只有一个编辑框IDC_EDIT_CAPTION,和固有属性Caption关联。(新建属性页的步骤不详述,请参考本系列其它文章)


7.重载OnMapPropertyToPage以在设置Param属性时显示对话框

BOOL CTppbCtrl::OnMapPropertyToPage(DISPID dispid, LPCLSID lpclsid, BOOL* pbPageOptional)
{
    // TODO: Add your specialized code here and/or call the base class
    if(dispid == dispidParam){
        *lpclsid = CTestPropPage::guid;
        *pbPageOptional = TRUE;
        return TRUE;
    }
    return COleControl::OnMapPropertyToPage(dispid, lpclsid, pbPageOptional);
}
注:为什么不在属性页中设置Param属性,而是Caption属性呢,主要是想解释一下,从哪个属性设置中弹出属性页和在该属性页中设置哪个属性并无关联,你也可以在弹出的属性页对话框中设置多个属性。

8.简单修饰一下控件,为控件添加一些初始值

void CTppbCtrl::OnResetState()
{
    COleControl::OnResetState();  // Resets defaults found in DoPropExchange

    // TODO: Reset any other control state here.
    m_week = 0;
    m_param = 0;
}

9.可以在VB下测试了




http://www.ppmy.cn/news/706075.html

相关文章

ActiveX控件属性的下拉列表

1、给控件类加上IPerPropertyBrowsingImpl接口 public IPerPropertyBrowsingImpl 在BEGIN_COM_MAP/END_COM_MAP()中间加上 COM_INTERFACE_ENTRY_IMPL(IPerPropertyBrowsing) 2、 在该类中添加下列函数 (A)STDMETHOD(MapPropertyToPage)(DISPID dispid, CLSID *pClsid);(B)…

ActiveX控件的MFC设计之旅-第12步 .

在VB和类似的包容器在属性视图中显示控件的属性&#xff0c;特别是枚举类型的属性时&#xff0c;会有一个下拉按钮&#xff0c;当点击该按钮时&#xff0c;会弹出一个列表框&#xff0c;显示一些友好的文字&#xff0c;供用户选择。而对于某些特殊的属性&#xff0c;如字体等&a…

OPM中细节设置

OPM中提供属性分类 常规的使用如下方法 BEGIN_OPMPROP_MAP() OPMPROP_ENTRY(0, DispID, PROPCAT_Data,0, 0, 0, “”, 0, 1, IID_NULL, IID_NULL, “”) END_OPMPROP_MAP() 其中DispIDP是R属性的 显示ID&#xff1b;OPCAT_为前缀的就是已经预定义的属性分类&#xff0c;其数值…

cad考试题库绘图题答案_CAD考试试题库和参考答案解析

CAD WORD资料.可编辑 CAD考试试题库及参考答案 一、单项选择 1、AUTOCAD的坐标体系,包括世界坐标和( D )坐标系。 A、绝对坐标 B、平面坐标 C、相对坐标 D、用户坐标 2、当进入了AUTOCAD环境中(即AUTOCAD的图形编辑器)时,缺省时所建立的坐标系统为( B ) A、用户坐标系 B、世界…

ObjectARX自定义对象的OPM

在AutoCAD绘图工作中&#xff0c;经常用到特性面板&#xff0c;它可以方便地查询、修改CAD对象的详细信息&#xff0c;如颜色、线型等&#xff0c;它是一个非常实用且便捷的工具。如果能为自定义对象添加一个特性面板&#xff08;OPM&#xff09;,这无疑是众多初学者极感兴趣的…

cesium时间轴格式化为北京时间

中心思想&#xff1a;使用JulianDate.addHours()方法&#xff0c;将时间8. 效果&#xff1a; 初始配置&#xff1a;创建viewer时打开时间轴的配置&#xff08;默认打开&#xff09;&#xff0c;动画配置shouleAnimate为true。 // timeline: false, // animation: false, shou…

高压线路零序电流方向保护程序逻辑原理(三)

四、零序保护故障处理程序原理 零序保护逻辑程序可分为三个模块&#xff1a;快速动作部分、全相循环和非全相循环模块。这是根据零序保护的特点而设计的。任何一种高压线路保护都要求快速处理I段范围内的严重故障&#xff0c;所以零序保护与距离保护一样配有快速动作部分程序模…

一卡通管理系统需求分析

一卡通管理系统需求分析业务需求 1&#xff0e;业务目的&#xff1a;将校园的各类消费与身份认证功能集成在一卡通&#xff0c;实现“一卡在手&#xff0c;走遍校园”。为在校的师生和教学管理人员提供具有开放性的、灵活性的管理平台。 2&#xff0e;业务目标&#xff1a;实现…