如何在 ActiveX 控件中使用字体

字体的使用是ActiveX控件制作过程中不可缺少的部分。本文将深入浅出地介绍在ActiveX控件中制作过程中如何使用字体。本文所提及的ActiveX控件制作是指利用VC++6.0的MFC ActiveX ControlWizard 工具,用其它方法制作 ActiveX 控件本文不作讨论。
  本文专门设置了一些例程,以便您能够更好地掌握这些内容。这些例程都是完整的ActiveX控件制作源代码。为了突出重点,本文仅对字体使用相关部分的源代码作较详细的介绍,其余部分的代码本文不作过多讨论。字体作为一种属性在ActiveX控件中使用,与其它属性没有区别,同样分为库存属性和自定义属性,本文将分四个部分进行介绍。

第一部分 在控件中使用库存字体(Stock Font)属性

使用ClassWizard 添加 Font库存属性的步骤:

  1. 打开控件工程, 单击View菜单的ClassWizard打开ClassWizard;
  2. 单击Automation标签;
  3. 在Class Name框,选择你的控件类名;
  4. 单击Add Property;
  5. 在 External name框, 单击Font;
  6. 单击 OK;
  7. 单击 OK确认你的选择并关闭 ClassWizard;

ClassWizard将在控件类的执行文件的dispatch映射表中加入下列行:

DISP_STOCKPROP_FONT()

另外, ClassWizard 在.ODL 文件中加入下列行:

[id(DISPID_FONT), bindable] IFontDisp* Font;

例程1:Label.ocx

  下面,我们举一个具体的实例详细演示如何在控件中添加Font库存属性。您可以下载该例程进行编译生成 .ocx 控件,并测试该控件。
我们将要制作的控件取名Label.ocx,模仿VB工具箱中的Label控件。该控件增强了VC++工具箱中的Static Text控件的有限的功能,您可以方便地在您的工程中使用。例程的工程名也取名为Label。

创建Label工程

  打开Visual C++ 6.0,单击File菜单的New,弹出New对话框。在对话框中选择MFC ActiveX ControlWizard,并输入工程名Label,单击OK按钮,关闭该对话框并弹出MFC ActiveX ControlWizard-Step 1 of 2对话框。如图1-1。


图1-1

  接受MFC ActiveX ControlWizard-Step 1 of 2对话框所有默认设置,单击Next按钮,关闭该窗口同时弹出MFC ActiveX ControlWizard-Step 2 of 2对话框。继续接受MFC ActiveX ControlWizard-Step 2 of 2对话框所有默认设置,单击Finish按钮。
继续单击OK 按钮,Label工程创建完成,我们将继续对该工程进行修改。使用ClassWizard 给控件增加库存属性Caption,BackColor,ForeColor,Font。

  1. 单击View菜单的ClassWizard打开 ClassWizard;
  2. 单击Automation标签;
  3. Class Name下拉列表框选择CLabelCtrl,单击 Add Property;
  4. 在External name框中,单击Caption;
  5. 单击OK;
  6. 单击OK确认你的选择并关闭ClassWizard;

我们已经给控件增加了库存属性Caption,该属性用以设置Label控件的文本内容。按上述同样操作,依次添加库存属性BackColor,ForeColor,Font。这3个属性分别用以设置Label控件的背景色,前景色以及字体的属性。如图1-2。


图1-2

添加颜色属性页和字体属性页

打开工程的LabelCtl.cpp文件,将其中的如下代码进行修改:

BEGIN_PROPPAGEIDS(CLabelCtrl, 1)
PROPPAGEID(CLabelPropPage::guid)
END_PROPPAGEIDS(CLabelCtrl)

修改后的代码:

BEGIN_PROPPAGEIDS(CLabelCtrl, 3) // 具体个数由实际情况而定
PROPPAGEID(CLabelPropPage::guid)//系统自带的属性页
PROPPAGEID(CLSID_CColorPropPage) //加入Color属性页
PROPPAGEID(CLSID_CFontPropPage) //加入Font属性页
END_PROPPAGEIDS(CLabelCtrl) 

修改系统自带的属性页

  打开系统自带的属性页资源IDD_PROPPAGE_LABEL,将静态文本框IDC_STATIC的内容改为"Caption:",添加一个编辑框(Edit Box)控件,控件ID为IDC_CAPTION。如图1-3


图1-3

  按下"Ctrl+W"组合键打开ClassWizard,选中Member Variables标签,Class name:下拉列表框选择CLabelPropPage,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按钮。如图1-4。


图1-4

再次单击OK按钮关闭ClassWizard。上述操作,编辑框IDC_CAPTION与Caption属性之间建立了联系。您可以通过修改编辑框的内容来改变控件Caption的属性值。

修改OnDraw函数

修改后的OnDraw函数如下:

void CLabelCtrl::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());
     // GetBackColor(),GetForeColor()分别得到背景色和前景色
     // GetBackColor(),GetForeColor()返回类型为OLE_COLOR
     // TranslateColor函数将OLE_COLOR类型转换为COLORREF类型

	CBrush brush(colorBack);
	pdc->FillRect(rcBounds, &brush);
     //背景色填充整个控件
	pdc->SetBkMode(TRANSPARENT);
     //设置透明背景色
	pdc->SetTextColor(colorFore);
     //前景色设置为字体颜色
	const CString& strCaption = InternalGetText();
     //获得库存属性Caption的值
	CFont* pOldFont;
	pOldFont = SelectStockFont(pdc);
     //设备上下文中选择字体对象
	RECT rect;
	::CopyRect(&rect,rcBounds);
	pdc->DrawText(strCaption,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
     //单行,水平居中,垂直居中显示
	pdc->SelectObject(pOldFont);
}

  Label控件的制作已经完成了,您可以方便地改变字体的大小、类型、颜色以及控件的背景色。当然,您还可以进一步完善该控件,更加方便您的使用。

第二部分 在控件中使用自定义的字体(Custom Font)属性

  除了库存字体属性Font外, ActiveX控件还允许使用自定义的字体属性。添加一个自定义字体属性,要完成一个自定义字体属性,你应该首先使用 ClassWizard 添加自定义字体属性,然后对代码作一些修改。下面将描述怎样给一个控件添加自定义属性(假设控件的名字为Sample):
使用 ClassWizard 添加自定义字体属性

  1. 打开 控件工程,单击View菜单的ClassWizard打开 ClassWizard;
  2. 单击Automation标签;
  3. 单击 Add Property;
  4. 在External name框中,输入属性名(在本例中,假设输入的自定义属性名为HeadingFont);
  5. 在Implementation框中,单击Get/Set Methods;
  6. 在Return Type框中,选择LPFONTDISP作为属性类型;
  7. 单击OK;
  8. 单击OK确认你的选择并关闭ClassWizard;

  ClassWizard 将产生相应的代码把自定义属性HeadingFont添加到CSampleCtrl类中和 SAMPLE.ODL文件中。既然 HeadingFont是一个 Get/Set 属性类型,ClassWizard 修改CSampleCtrl 类的dispatch 映射表来包括一个DISP_PROPERTY_EX 宏入口:

BEGIN_DISPATCH_MAP(CSampleCtrl, COleControl)
//{{AFX_DISPATCH_MAP(CSampleCtrl)
DISP_PROPERTY_EX(CSampleCtrl, "HeadingFont", GetHeadingFont,
   SetHeadingFont, VT_DISPATCH)
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()      
  DISP_PROPERTY_EX 宏把HeadingFont属性名和它的相应的CSampleCtrl类的Get / Set 方法(GetHeadingFont and SetHeadingFont)联系起来。 ClassWizard 也在控件的头文件(.H)为GetHeadingFont 和 SetHeadingFont函数添加声明 ,并在控件的执行文件(.CPP)添加模板函数:
LPFONTDISP CSampleCtrl::GetHeadingFont() 
{
 // TODO: Add your property handler here
 return NULL;
}
void CSampleCtrl::SetHeadingFont(LPFONTDISP newValue)
{
 // TODO: Add your property handler here
 SetModifiedFlag();
}      
最后, ClassWizard修改控件的 .ODL 文件,为HeadingFont 属性添加一个入口:
[id(1)] IFontDisp* HeadingFont;

修改控件代码

  现在你已经为控件添加了HeadingFont属性,你必须对控件的头文件和执行文件进行修改以完全支持新的属性。在控件的头文件(.H),添加一个protected成员变量的声明:

protected:
CFontHolder m_fontHeading;

在控件的执行文件(.CPP)中,如下操作:在控件的构造函数中初始化 m_fontHeading。

CSampleCtrl::CSampleCtrl( ) : m_fontHeading( &m_xFontNotification )
{
    // [...body of constructor...]
}      
声明一个静态FONTDESC结构,该结构包含缺省的字体属性。
static const FONTDESC _fontdescHeading =
  { sizeof(FONTDESC), OLESTR("MS Sans Serif"), FONTSIZE( 12 ), FW_BOLD, 
     ANSI_CHARSET, FALSE, FALSE, FALSE };      
在控件的DoPropExchange 成员函数,添加一个PX_Font函数的调用,提供自定义字体属性的初始化和持久化。
void CSampleCtrl::DoPropExchange(CPropExchange* pPX)
{
   COleControl::DoPropExchange(pPX);
    // [...other PX_ function calls...]
    PX_Font(pPX, _T("HeadingFont"), m_fontHeading, &_fontdescHeading);
}      
完成控件的GetHeadingFont成员函数。
LPFONTDISP CSampleCtrl::GetHeadingFont( )
{
    return m_fontHeading.GetFontDispatch( );
}      
完成控件的SetHeadingFont成员函数
void CSampleControl::SetHeadingFont( LPFONTDISP newValue )
{
    m_fontHeading.InitializeFont( &_fontdescHeading, newValue);
    OnFontChanged();    //notify any changes
    SetModifiedFlag( );
}      
修改控件的OnDraw成员函数,定义一个变量控制以前选择的字体。
CFont* pOldHeadingFont;     
修改控件的OnDraw成员函数,添加下列代码,在设备上下文中选择自定义的字体。
pOldHeadingFont = SelectFontObject(pdc, m_fontHeading);      
修改控件的OnDraw成员函数,字体使用完后恢复原字体到设备上下文。
pdc->SelectObject(pOldHeadingFont);      
添加标准字体属性页自定义字体属性设置完成后,应添加标准字体属性页,允许控件使用者更改控件当前的字体。为标准字体属性页增加属性页的ID号, 在BEGIN_PROPPAGEIDS宏后添加如下行:
PROPPAGEID(CLSID_CFontPropPage)      
完成这些工作后,重新编译工程。

例程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

  1. 单击View菜单的ClassWizard打开 ClassWizard;
  2. 单击Automation标签;
  3. Class Name下拉列表框选择CLabel1Ctrl,单击 Add Property;
  4. 在External name框中,单击BackColor;
  5. 单击OK;
  6. 单击OK确认你的选择并关闭ClassWizard;

  按上述同样操作,添加库存属性ForeColor,Caption。BackColor,ForeColor,Caption这三个属性分别用来设置Label1控件的背景色,前景色和字符串内容。如图2-2。


图2-2

使用ClassWizard 给控件增加自定义属性CaptionFont

  1. 单击View菜单的ClassWizard打开 ClassWizard;
  2. 单击Automation标签;
  3. Class Name下拉列表框选择CLabel1Ctrl,单击 Add Property;
  4. 在External name框中,输入自定义属性名CaptionFont;
  5. 在Implementation框中,单击Get/Set methods;
  6. 在Return Type框中,选择LPFONTDISP作为属性类型;
  7. 单击OK;
  8. 单击OK确认你的选择并关闭ClassWizard;

如图2-3


图2-3
 

修改控件代码

在控件的头文件(Label1Ctl.h),添加一个protected成员变量的声明:

protected:
CFontHolder m_fontCaption;

如图2-4。


图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控件。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值