zoukankan      html  css  js  c++  java
  • MFC 静态文本的自绘 空心字的实现

       想在对话框里,显示几个字是很简单的,只要用静态文本的输出就可以了。然而有时候我们需要显示特效的字,我们希望显示的文字就像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); 

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

    高山流水,海纳百川!
  • 相关阅读:
    推介一款小工具——SwitchHosts
    Postman的使用之进行文件上传
    Postman的使用之普通的提交Post和Get请求
    Postman的安装
    Windows配置基础环境(jdk+tomcat)
    yum clean all大坑解决
    通过代理实现访问内网系统
    批量配置免密登录
    设置JRebel热部署【本地模式】
    使用多线程程序模拟实现单生产者/多消费者问题 (Linux 线程锁实践)
  • 原文地址:https://www.cnblogs.com/ahcc08/p/6082478.html
Copyright © 2011-2022 走看看