如何在ActiveX控件中使用字体4

如何在ActiveX控件中使用字体4

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

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

BEGIN_PROPPAGEIDS(CLabelEx0Ctrl, 1)
   PROPPAGEID(CLabelEx0PropPage::guid)
END_PROPPAGEIDS(CLabelEx0Ctrl)
修改后的代码: BEGIN_PROPPAGEIDS(CLabelEx0Ctrl, 3) // 具体个数由实际情况而定
   PROPPAGEID(CLabelEx0PropPage::guid)//系统自带的属性页
   PROPPAGEID(CLSID_CColorPropPage) //加入Color属性页
   PROPPAGEID(CLSID_CFontPropPage) //加入Font属性页
END_PROPPAGEIDS(CLabelEx0Ctrl)
修改系统自带的属性页

  打开系统自带的属性页资源IDD_PROPPAGE_LABELEx0,把属性页的尺寸由250×62调整为250×110。删除原有的静态文本框,重新添加9个静态文本框,静态文本框的内容依次为"CaptionUp:", "CaptionMiddle:","CaptionDown:","XUp:","Yup:","XMiddle:","YMiddle:","XDown:","YDown:"。添加9个对应的编辑框(Edit Box)控件,控件ID依次为IDC_CAPTIONUP,IDC_CAPTIONMIDDLE,IDC_CAPTIONDOWN,IDC_XUP,IDC_YUP,IDC_XMIDDLE,IDC_YMIDDLE,IDC_XDOWN,IDC_YDOWN。其中,IDC_CAPTIONUP,IDC_CAPTIONMIDDLE,IDC_CAPTIONDOWN分别用于输入上标,中间,下标的文本内容;IDC_XUP,IDC_YUP,IDC_XMIDDLE,IDC_YMIDDLE,IDC_XDOWN,IDC_YDOWN分别用于输入上标,中间,下标的文本的坐标位置。如图3-1。

图3-1

  按下"Ctrl+W"组合键打开ClassWizard,选中Member Variables标签,Class name:下拉列表框选择CLabelEx0PropPage,Control IDs:选中IDC_CAPTIONUP,单击Add Variable…按钮,弹出Add Member Variable对话框。

  在Add Member Variable对话框中,Member variable name:框输入m_captionUp,Category选择Value,Variable type:框选择CString,Optional property name:框选择CaptionUp,单击OK按钮。重复上述操作,为其余8个编辑控件建立添加相应的成员变量。对应关系如下表:

  控件ID

  Member variable name

  Category

  Variable type

  Optional property name

  IDC_CAPTIONUP

  m_captionUp

  Value

  CString

  CaptionUp

  IDC_CAPTIONMIDDLE

  m_captionMiddle

  Value

  CString

  CaptionMiddle

  IDC_CAPTIONDOWN

  m_captionDown

  Value

  CString

  CaptionDown

  IDC_XUP

  m_xUp

  Value

  long

  XUp

  IDC_YUP

  m_yUp

  Value

  long

  YUp

  IDC_XMIDDLE

  m_xMiddle

  Value

  long

  XMiddle

  IDC_YMIDDLE

  m_yMiddle

  Value

  long

  YMiddle

  IDC_XDOWN

  m_xDown

  Value

  long

  XDown

  IDC_YDOWN

  m_yDown

  Value

  long

  YDown

  再次单击OK按钮关闭ClassWizard。修改控件代码在控件的头文件(LabelEx0Ctl.h),添加三个protected成员变量的声明:

protected:
CFontHolder m_fontUp;
CFontHolder m_fontMiddle;
CFontHolder m_fontDown;

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

m_fontUp, m_fontMiddle, m_fontDown。 CLabelEx0Ctrl::CLabelEx0Ctrl():m_fontUp(&m_xFontNotification),
m_fontMiddle(&m_xFontNotification),m_fontDown(&m_xFontNotification)
{
   InitializeIIDs(&IID_DLabelEx0, &IID_DLabelEx0Events);
   // 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_函数的调用。

void CLabelEx0Ctrl::DoPropExchange(CPropExchange* pPX)
{
   ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
   COleControl::DoPropExchange(pPX);
   // TODO: Call PX_ functions for each persistent custom property.
   PX_Font(pPX, _T("FontUp"), m_fontUp, &_fontdescCaption);
   PX_Font(pPX, _T("FontMiddle"), m_fontMiddle, &_fontdescCaption);
   PX_Font(pPX, _T("FontDown"), m_fontDown, &_fontdescCaption);
   PX_Long(pPX,_T("XUp"),m_xUp,0);
   PX_Long(pPX,_T("YUp"),m_yUp,0);
   PX_Long(pPX,_T("XMiddle"),m_xMiddle,0);
   PX_Long(pPX,_T("YMiddle"),m_yMiddle,20);
   PX_Long(pPX,_T("XDown"),m_xDown,0);
   PX_Long(pPX,_T("YDown"),m_yDown,30);
   PX_String(pPX, _T("CaptionUp"), m_captionUp, _T("上标"));
   PX_String(pPX, _T("CaptionMiddle"), m_captionMiddle, _T("中间"));
   PX_String(pPX, _T("CaptionDown"), m_captionDown, _T("下标"));
}

完成控件的成员函数

void CLabelEx0Ctrl::OnCaptionUpChanged()
{
   InvalidateControl();
   SetModifiedFlag();
}
void CLabelEx0Ctrl::OnCaptionMiddleChanged()
{
   InvalidateControl();
   SetModifiedFlag();
}
void CLabelEx0Ctrl::OnCaptionDownChanged()
{
   InvalidateControl();
   SetModifiedFlag();
}
void CLabelEx0Ctrl::OnXUpChanged()
{
   InvalidateControl();
   SetModifiedFlag();
}
void CLabelEx0Ctrl::OnYUpChanged()
{
   InvalidateControl();
   SetModifiedFlag();
}
void CLabelEx0Ctrl::OnXMiddleChanged()
{
   InvalidateControl();
   SetModifiedFlag();
}
void CLabelEx0Ctrl::OnYMiddleChanged()
{
   InvalidateControl();
   SetModifiedFlag();
}
void CLabelEx0Ctrl::OnXDownChanged()
{
   InvalidateControl();
   SetModifiedFlag();
}
void CLabelEx0Ctrl::OnYDownChanged()
{
   InvalidateControl();
   SetModifiedFlag();
}
LPFONTDISP CLabelEx0Ctrl::GetFontUp()
{
   return m_fontUp.GetFontDispatch();
}
void CLabelEx0Ctrl::SetFontUp(LPFONTDISP newValue)
{
   m_fontUp.InitializeFont(&_fontdescCaption,newValue);
   OnFontChanged();
   SetModifiedFlag();
}
LPFONTDISP CLabelEx0Ctrl::GetFontMiddle()
{
   return m_fontMiddle.GetFontDispatch();
}
void CLabelEx0Ctrl::SetFontMiddle(LPFONTDISP newValue)
{
   m_fontMiddle.InitializeFont(&_fontdescCaption,newValue);
   OnFontChanged();
   SetModifiedFlag();
}
LPFONTDISP CLabelEx0Ctrl::GetFontDown()
{
   return m_fontDown.GetFontDispatch();
}
void CLabelEx0Ctrl::SetFontDown(LPFONTDISP newValue)
{
   m_fontDown.InitializeFont(&_fontdescCaption,newValue);
   OnFontChanged();
   SetModifiedFlag();
}

修改OnDraw函数,修改后的OnDraw函数如下:

void CLabelExCtrl::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);
   CFont* pOldFont;
   RECT rect;
   ::CopyRect(&rect,rcBounds);
   pOldFont = SelectFontObject(pdc, m_fontUp);
   pdc->TextOut(m_xUp,m_yUp,m_captionUp);
   SelectFontObject(pdc, m_fontMiddle);
   pdc->TextOut(m_xMiddle,m_yMiddle,m_captionMiddle);
   SelectFontObject(pdc, m_fontDown);
   pdc->TextOut(m_xDown,m_yDown,m_captionDown);
   pdc->SelectObject(pOldFont);
}

LabelEx0控件的制作已经完成了。您可以对它进行测试,并使用它制作形如"m3/h"样式的标签。

第四部分 优化代码,合理地使用多种字体

  上例中三个字体对象使用同一IFontNotification实现,不能具体区分控件字体对象的通知。如果想区分哪个字体已更改,可以使用以下方法:

  为控件的每个字体对象各创建一个单独的IFontNotification接口实现。此技术使您只需更新使用最近修改的字体的一个或多个字符串,从而优化了绘制代码。以下将以修改例程3 LabelEx0的字体属性FontUp为例来说明如何为第二个字体属性实现单独的通知接口所必需的步骤。

  实现新的字体通知接口

  若要区分两个或多个字体的通知,必须为控件中使用的每个字体各实现一个新的通知接口。以下各节介绍如何通过修改控件头文件和实现文件来实现新的字体通知接口。

  向头文件中添加的内容

  在控件头文件(CLabelEx0Ctrl.H)中,添加下列代码:

DECLARE_INTERFACE_MAP() //声明接口映射
BEGIN_INTERFACE_PART(FontUpNotify,IPropertyNotifySink)//声明实现接口IPropertyNotifySink的嵌套类
   INIT_INTERFACE_PART(CLabelEx0Ctrl,FontUpNotify)
   STDMETHOD(OnRequestEdit)(DISPID);
   STDMETHOD(OnChanged)(DISPID);
END_INTERFACE_PART(FontUpNotify)

这样,CLabelEx0Ctrl中多了一个嵌套类XFontUpNotify,以及它的一个变量m_xFontUpNotify。在CLabelEx0Ctrl的实现文件中加入该嵌套类的实现:

//映射接口IPropertyNotifySink到相应的嵌套类
BEGIN_INTERFACE_MAP(CLabelEx0Ctrl,COleControl)
INTERFACE_PART(CLabelEx0Ctrl,IID_IPropertyNotifySink,FontUpNotify)
END_INTERFACE_MAP()
STDMETHODIMP_(ULONG) CLabelEx0Ctrl::XFontUpNotify::AddRef()
{
   METHOD_PROLOGUE_EX(CLabelEx0Ctrl,FontUpNotify)
     return (ULONG)pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CLabelEx0Ctrl::XFontUpNotify::Release()
{
   METHOD_PROLOGUE_EX(CLabelEx0Ctrl,FontUpNotify)
     return (ULONG)pThis->ExternalRelease();
}
STDMETHODIMP CLabelEx0Ctrl::XFontUpNotify::QueryInterface(REFIID iid,LPVOID FAR* ppvObj)
{
   METHOD_PROLOGUE_EX(CLabelEx0Ctrl,FontUpNotify)
     return (HRESULT)pThis->ExternalQueryInterface(&iid,ppvObj);
}
STDMETHODIMP CLabelEx0Ctrl::XFontUpNotify::OnChanged(DISPID)
{
   METHOD_PROLOGUE_EX(CLabelEx0Ctrl,FontUpNotify)
     pThis->InvalidateControl();
   return NOERROR;
}
STDMETHODIMP CLabelEx0Ctrl::XFontUpNotify::OnRequestEdit(DISPID)
{
   return NOERROR;
}

  在CLabelEx0Ctrl类的构造函数代码中,将m_fontUp(&m_xFontNotification)更改为m_fontUp(&m_xFontUpNotify)。对项目执行完这些更改后,重新生成项目,并使用测试容器测试接口。

例程4:LabelEx.ocx

  例程4的控件名称为LabelEx.ocx,它是例程3代码的优化,实现与例程3完全相同的功能。打开Visual C++ 6.0,新建LabelEx工程,接受所有默认设置,完成LabelEx工程创建。完成所有与例程3完全相同的操作,完成后再作如下改动和补充:

  向控件头文件(CLabelExCtrl.H)中添加下列代码

DECLARE_INTERFACE_MAP() //声明接口映射
BEGIN_INTERFACE_PART(FontUpNotify,IPropertyNotifySink)
INIT_INTERFACE_PART(CLabelExCtrl,FontUpNotify)
   STDMETHOD(OnRequestEdit)(DISPID);
   STDMETHOD(OnChanged)(DISPID);
END_INTERFACE_PART(FontUpNotify)
   BEGIN_INTERFACE_PART(FontMiddleNotify,IPropertyNotifySink)
   INIT_INTERFACE_PART(CLabelExCtrl,FontMiddleNotify)
   STDMETHOD(OnRequestEdit)(DISPID);
   STDMETHOD(OnChanged)(DISPID);
   END_INTERFACE_PART(FontMiddleNotify)
   BEGIN_INTERFACE_PART(FontDownNotify,IPropertyNotifySink)
   INIT_INTERFACE_PART(CLabelExCtrl,FontDownNotify)
   STDMETHOD(OnRequestEdit)(DISPID);
   STDMETHOD(OnChanged)(DISPID);
   END_INTERFACE_PART(FontDownNotify)
在CLabelExCtrl的实现文件中加入该嵌套类的实现
BEGIN_INTERFACE_MAP(CLabelExCtrl,COleControl)
INTERFACE_PART(CLabelExCtrl,IID_IPropertyNotifySink,FontUpNotify)
INTERFACE_PART(CLabelExCtrl,IID_IPropertyNotifySink,FontMiddleNotify)
INTERFACE_PART(CLabelExCtrl,IID_IPropertyNotifySink,FontDownNotify)
END_INTERFACE_MAP()
STDMETHODIMP_(ULONG) CLabelExCtrl::XFontUpNotify::AddRef()
{
   METHOD_PROLOGUE_EX(CLabelExCtrl,FontUpNotify)
     return (ULONG)pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CLabelExCtrl::XFontUpNotify::Release()
{
   METHOD_PROLOGUE_EX(CLabelExCtrl,FontUpNotify)
     return (ULONG)pThis->ExternalRelease();
}
STDMETHODIMP CLabelExCtrl::XFontUpNotify::QueryInterface(REFIID iid,LPVOID FAR* ppvObj)
{
   METHOD_PROLOGUE_EX(CLabelExCtrl,FontUpNotify)
     return (HRESULT)pThis->ExternalQueryInterface(&iid,ppvObj);
}
STDMETHODIMP CLabelExCtrl::XFontUpNotify::OnChanged(DISPID)
{
   METHOD_PROLOGUE_EX(CLabelExCtrl,FontUpNotify)
     pThis->InvalidateControl();
   return NOERROR;
}
STDMETHODIMP CLabelExCtrl::XFontUpNotify::OnRequestEdit(DISPID)
{
   return NOERROR;
}
STDMETHODIMP_(ULONG) CLabelExCtrl::XFontMiddleNotify::AddRef()
{
   METHOD_PROLOGUE_EX(CLabelExCtrl,FontMiddleNotify)
     return (ULONG)pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CLabelExCtrl::XFontMiddleNotify::Release()
{
   METHOD_PROLOGUE_EX(CLabelExCtrl,FontMiddleNotify)
     return (ULONG)pThis->ExternalRelease();
}
STDMETHODIMP CLabelExCtrl::XFontMiddleNotify::QueryInterface(REFIID iid,LPVOID FAR* ppvObj)
{
   METHOD_PROLOGUE_EX(CLabelExCtrl,FontMiddleNotify)
     return (HRESULT)pThis->ExternalQueryInterface(&iid,ppvObj);
}
STDMETHODIMP CLabelExCtrl::XFontMiddleNotify::OnChanged(DISPID)
{
   METHOD_PROLOGUE_EX(CLabelExCtrl,FontMiddleNotify)
     pThis->InvalidateControl();
   return NOERROR;
}
STDMETHODIMP CLabelExCtrl::XFontMiddleNotify::OnRequestEdit(DISPID)
{
   return NOERROR;
}
STDMETHODIMP_(ULONG) CLabelExCtrl::XFontDownNotify::AddRef()
{
   METHOD_PROLOGUE_EX(CLabelExCtrl,FontDownNotify)
     return (ULONG)pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CLabelExCtrl::XFontDownNotify::Release()
{
   METHOD_PROLOGUE_EX(CLabelExCtrl,FontDownNotify)
     return (ULONG)pThis->ExternalRelease();
}
STDMETHODIMP CLabelExCtrl::XFontDownNotify::QueryInterface(REFIID iid,LPVOID FAR* ppvObj)
{
   METHOD_PROLOGUE_EX(CLabelExCtrl,FontDownNotify)
     return (HRESULT)pThis->ExternalQueryInterface(&iid,ppvObj);
}
STDMETHODIMP CLabelExCtrl::XFontDownNotify::OnChanged(DISPID)
{
   METHOD_PROLOGUE_EX(CLabelExCtrl,FontDownNotify)
     pThis->InvalidateControl();
   return NOERROR;
}
STDMETHODIMP CLabelExCtrl::XFontDownNotify::OnRequestEdit(DISPID)
{
   return NOERROR;
}
CLabelExCtrl类的构造函数的代码作如下改动 CLabelExCtrl::CLabelExCtrl():m_fontUp(&m_xFontUpNotify),
m_fontMiddle(&m_xFontMiddleNotify),m_fontDown(&m_xFontDownNotify)
{
   InitializeIIDs(&IID_DLabelEx, &IID_DLabelExEvents);
   // TODO: Initialize your control''s instance data here.
}
 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值