如何在ActiveX控件中使用字体3
例程2:Label1.ocx
例程2的Label1控件与例程1的Label控件在功能实现上没有任何区别,只是在改变字体特性时,不再使用库存字体属性Font,而是使用自定义字体属性CaptionFont。下面我们将结合Label1控件介绍如何在控件中使用自定义属性。
打开Visual C++ 6.0,按照例程1的操作步骤新建Label1工程,象例程1那样接受所有默认设置, 完成Label1工程创建。如图2-1。
图2-1
使用ClassWizard 给控件增加库存属性BackColor,ForeColor,Caption
- 单击View菜单的ClassWizard打开 ClassWizard;
- 单击Automation标签;
- Class Name下拉列表框选择CLabel1Ctrl,单击 Add Property;
- 在External name框中,单击BackColor;
- 单击OK;
- 单击OK确认你的选择并关闭ClassWizard;
按上述同样操作,添加库存属性ForeColor,Caption。BackColor,ForeColor,Caption这三个属性分别用来设置Label1控件的背景色,前景色和字符串内容。如图2-2。
图2-2
使用ClassWizard 给控件增加自定义属性CaptionFont
- 单击View菜单的ClassWizard打开 ClassWizard;
- 单击Automation标签;
- Class Name下拉列表框选择CLabel1Ctrl,单击 Add Property;
- 在External name框中,输入自定义属性名CaptionFont;
- 在Implementation框中,单击Get/Set methods;
- 在Return Type框中,选择LPFONTDISP作为属性类型;
- 单击OK;
- 单击OK确认你的选择并关闭ClassWizard;
如图2-3
图2-3
修改控件代码
在控件的头文件(Label1Ctl.h),添加一个protected成员变量的声明:
protected:
CFontHolder m_fontCaption;
如图2-4。
在控件的执行文件(.CPP)中,如下操作:
在控件的构造函数中初始化m_fontCaption。
CLabel1Ctrl::CLabel1Ctrl(): m_fontCaption(&m_xFontNotification)
{
InitializeIIDs(&IID_DLabel1, &IID_DLabel1Events);
// TODO: Initialize your control''s instance data here.
}
声明一个静态FONTDESC结构,该结构包含缺省的字体属性。
static const FONTDESC _fontdescCaption =
{ sizeof(FONTDESC), OLESTR("MS Sans Serif"), FONTSIZE( 12 ), FW_BOLD,
ANSI_CHARSET, FALSE, FALSE, FALSE };
在控件的DoPropExchange 成员函数,添加一个PX_Font函数的调用,提供自定义字体属性的初始化和持久化。
void CLabel1Ctrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
PX_Font(pPX, _T("CaptionFont"), m_fontCaption, &_fontdescCaption);
}
完成控件的GetCaptionFont成员函数。
LPFONTDISP CLabel1Ctrl::GetCaptionFont()
{
// TODO: Add your property handler here
return m_fontCaption.GetFontDispatch();
}
完成控件的SetHeadingFont成员函数
void CLabel1Ctrl::SetCaptionFont(LPFONTDISP newValue)
{
// TODO: Add your property handler here
m_fontCaption.InitializeFont(&_fontdescCaption,newValue);
OnFontChanged();
SetModifiedFlag();
}
修改控件的OnDraw成员函数,
void CLabel1Ctrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
// TODO: Replace the following code with your own drawing code.
COLORREF colorBack=TranslateColor(GetBackColor());
COLORREF colorFore=TranslateColor(GetForeColor());
CBrush brush(colorBack);
pdc->FillRect(rcBounds, &brush);
//背景色填充整个控件
pdc->SetBkMode(TRANSPARENT);
//设置透明背景色
pdc->SetTextColor(colorFore);
//前景色设置为字体颜色
const CString& strCaption = InternalGetText();
//获得库存属性Caption的值
CFont* pOldFont;
pOldFont = SelectFontObject(pdc,m_fontCaption);
//设备上下文中选择字体对象
RECT rect;
::CopyRect(&rect,rcBounds);
pdc->DrawText(strCaption,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
//单行,水平居中,垂直居中显示
pdc->SelectObject(pOldFont);
}
添加颜色属性页和字体属性页打开工程的Label1Ctl.cpp文件,将其中的如下代码进行修改:
BEGIN_PROPPAGEIDS(CLabel1Ctrl, 1)
修改后的代码:
PROPPAGEID(CLabelPropPage::guid)
END_PROPPAGEIDS(CLabel1Ctrl)BEGIN_PROPPAGEIDS(CLabel1Ctrl, 3) // 具体个数由实际情况而定
修改系统自带的属性页
PROPPAGEID(CLabel1PropPage::guid)//系统自带的属性页
PROPPAGEID(CLSID_CColorPropPage) //加入Color属性页
PROPPAGEID(CLSID_CFontPropPage) //加入Font属性页
END_PROPPAGEIDS(CLabel1Ctrl)
打开系统自带的属性页资源IDD_PROPPAGE_LABEL1,将静态文本框IDC_STATIC的内容改为"Caption:",添加一个编辑框(Edit Box)控件,控件ID为IDC_CAPTION。如图2-5。
图2-5
按下"Ctrl+W"组合键打开ClassWizard,选中Member Variables标签,Class name:下拉列表框选择CLabel1PropPage,Control IDs:选中IDC_CAPTION,单击Add Variable…按钮,弹出Add Member Variable对话框。
在Add Member Variable对话框中,Member variable name:框输入m_caption,Category选择Value,Variable type:框选择CString,Optional property name:框选择Caption,单击OK按钮。
再次单击OK按钮关闭ClassWizard。
上述操作,编辑框IDC_CAPTION与Caption属性之间建立了联系。您可以通过修改编辑框的内容来改变控件Caption的属性值。
编译并构建Label1.ocx控件。
第三部分 使用多种字体
前面分别详细说明了如何在控件中使用库存属性和自定义属性。但有时我们需要在一个控件中使用多种字体,下面我们将说明如何在一个控件中实现多种字体属性。
大多数情况下,每个字体对象都能够通过调用IFontNotification接口的成员函数(由COleControl实现)在自身更改时提供通知。如果控件使用库存Font属性,则其通知由COleControl的OnFontChanged成员函数处理。当添加自定义Font属性时,可以让它们使用同一实现。在第二部分的例程中,这一点通过在初始化m_fontCaption成员变量时传递&m_xFontNotification来实现。
例程3将演示多个字体对象使用IFontNotification的同一实现,实现在一个控件中使用多种字体。
例程3:LabelEx0.ocx
例程1的Label控件确实增强了VC++工具箱中的Static Text控件的功能。但对于形如"m3/h","h2o"的文本内容,使用一个Label控件就有点无能为力了,下面我们将制作一个LabelEx0控件来再次扩展Label控件的功能,同时演示如何在控件中添加多种字体属性。
LabelEx0控件内部由上、中、下三个部分组成,三个部分的字体内容和字体属性可以分别设置,以方便地显示上下标部分。
打开Visual C++ 6.0,新建LabelEx0工程,接受所有默认设置,完成LabelEx0工程创建。使用ClassWizard 给控件增加库存属性BackColor,ForeColor:
- 单击View菜单的ClassWizard打开 ClassWizard;
- 单击Automation标签;
- Class Name下拉列表框选择CLabelEx0Ctrl,单击 Add Property;
- 在External name框中,单击BackColor;
- 单击OK;
- 单击OK确认你的选择并关闭ClassWizard;
我们已经给控件增加了库存属性BackColor,该属性用以设置LabelEx0控件的背景色。按上述同样操作,添加库存属性ForeColor。
使用ClassWizard 给控件增加自定义属性CaptionUp,CaptionMiddle,CaptionDown:
- 单击View菜单的ClassWizard打开 ClassWizard;
- 单击Automation标签;
- Class Name下拉列表框选择CLabelEx0Ctrl,单击 Add Property;
- 在External name框中,输入自定义属性名CaptionUp;
- 在Implementation框中,单击Member variable;
- 在Return Type框中,选择CString作为属性类型;
- 单击OK;
- 单击OK确认你的选择并关闭ClassWizard;
按上述同样操作,添加自定义属性CaptionMiddle,CaptionDown。CaptionUp,CaptionMiddle和CaptionDown分别用以设置LabelEx0控件上、中、下三个部分的文本内容。
使用ClassWizard 给控件增加自定义属性XUp,YUp,XMiddle, YMiddle, XDown, YDown
- 单击View菜单的ClassWizard打开 ClassWizard;
- 单击Automation标签;
- Class Name下拉列表框选择CLabelEx0Ctrl,单击 Add Property;
- 在External name框中,输入自定义属性名XUp;
- 在Implementation框中,单击Member variable;
- 在Return Type框中,选择long作为属性类型;
- 单击OK;
- 单击OK确认你的选择并关闭ClassWizard;
按上述同样操作,添加自定义属性YUp,XMiddle, YMiddle, XDown和YDown。其中XUp 和Yup属性用来决定上标文本的位置;XMiddle和YMiddle用以设置中间文本的位置;XDown和YDown 用以设置LabelEx0控件下标文本的位置。
使用ClassWizard 给控件增加自定义属性FontUp,FontMiddle,FontDown
- 单击View菜单的ClassWizard打开 ClassWizard;
- 单击Automation标签;
- Class Name下拉列表框选择CLabelEx0Ctrl,单击 Add Property;
- 在External name框中,输入自定义属性名FontUp;
- 在Implementation框中,单击Get/Set methods;
- 在Return Type框中,选择LPFONTDISP作为属性类型;
- 单击OK;
- 单击OK确认你的选择并关闭ClassWizard;
按上述同样操作,添加自定义属性FontMiddle,FontDown。FontUp,FontMiddle和FontDown分别用以设置LabelEx0控件上、中、下三个部分的字体属性。