您的位置:首页 > 其它

MFC 静态文本的自绘 空心字的实现

2016-11-20 13:17 162 查看
想在对话框里,显示几个字是很简单的,只要用静态文本的输出就可以了。然而有时候我们需要显示特效的字,我们希望显示的文字就像Word里的艺术字一样,看起来美观。这时我们可以重写CStatic类。用DrawItem方法重绘。
首先,我们想要激活CStatic控件的自绘属性,这样DrawItem才能有效。我们发现用激活CButton自绘属性的方法那样来激活 CStatic控件的自绘属性是不行的。他们的激活方式是不一样的。
不用说先新建一个MFC类叫CCustomStatic类并继承于CStatic父类。覆写PreSubclassWindow方法,在PreSubclassWindow激活CStatic的自绘属性。

代码如下:

void CCustomStatic::PreSubclassWindow()
{
DWORD dwstyle = GetStyle();
SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwstyle | SS_OWNERDRAW );
CStatic::PreSubclassWindow();
}


现在我们可以覆写DrawItem方法了。
代码如下:

void CCustomStatic::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CString strText;
GetWindowText(strText);
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
UINT state = lpDrawItemStruct->itemState;
CRect rect;
GetClientRect(rect);

CFont font;
CFont *pOldFont;
font.CreateFont(
0.9*rect.Height(),                        // nHeight
20,                         // nWidth
40,                         // nEscapement
0,                         // nOrientation
FW_BOLD,                 // nWeight
TRUE,                     // bItalic
FALSE,                     // bUnderline
0,                         // cStrikeOut
ANSI_CHARSET,              // nCharSet
OUT_DEFAULT_PRECIS,        // nOutPrecision
CLIP_DEFAULT_PRECIS,       // nClipPrecision
DEFAULT_QUALITY,           // nQuality
DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
_T("宋体"));                 // lpszFacename

pOldFont = dc.SelectObject(&font);
dc.SetBkMode(TRANSPARENT);

CPen pen(PS_SOLID, 1, RGB(0, 128, 255));
CPen *pOldPen;
pOldPen = dc.SelectObject(&pen);
dc.BeginPath();
dc.TextOut(rect.top-10, rect.left +12, strText);
dc.EndPath();
int num = dc.GetPath(NULL, NULL, 0);
CPoint *pt = new CPoint[num];
BYTE *type = new BYTE[num];
num = dc.GetPath(pt, type, num);
CPoint pstart;
for (int j = 0; j < num; j++)
{
switch (type[j])
{
case PT_MOVETO:
dc.MoveTo(pt[j]);
pstart = pt[j];
break;
case PT_LINETO:
dc.LineTo(pt[j]);
break;
case PT_BEZIERTO:
dc.PolyBezierTo(pt + j, 3);
j += 2;
break;
case PT_BEZIERTO|PT_CLOSEFIGURE:
pt[j+2] = pstart;
dc.PolyBezierTo(pt + j, 3);
j += 2;
break;
case PT_LINETO| PT_CLOSEFIGURE :
dc.LineTo(pstart);
break;
}
dc.CloseFigure();
}
font.DeleteObject();
pen.DeleteObject();
delete pt;
delete type;

dc.Detach();
}


头文件里不要忘记了声明

virtual void PreSubclassWindow();
void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

运行效果如下:空心字 效果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: