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); 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM