SOFTIST 编程方法筆記 →目录

自描画按钮(VC++)

控件都能自描画。自描画不仅能反映应用程序的个性,还能满足特殊的要求。按钮的自描画极具代表性。为了做笔记,做一个简单的自描画,自描画内容包括:文字字模,文字大小,文字颜色,图片显示,按下状态,焦点状态。

1.使用资源编辑器,为对话框贴一个按钮,并且设其属性为「自描画」。

2.从CButton派生一个COwnerDrawButton类。

3.用ClassWizard为按钮定义一个COwnerDrawButton类型的变量。

4.重载和填写void COwnerDrawButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
函数。

void COwnerDrawButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    //取得描画范围
    CRect rct = lpDrawItemStruct->rcItem;
    CRect rctFocus = rct;
    CRect rctSft = rct;

    if(lpDrawItemStruct->itemAction & (ODA_DRAWENTIRE | ODA_SELECT))
    {
        UINT uiFlag = DFCS_ADJUSTRECT | DFCS_BUTTONPUSH;
        if(lpDrawItemStruct->itemState & ODS_SELECTED)   //押下状態
        {
            uiFlag |= DFCS_PUSHED;
            rctSft.OffsetRect(1, 1);
        }
        pDC->DrawFrameControl(rct, DFC_BUTTON, uiFlag);  //画按钮

        CString strWindowText;
        GetWindowText(strWindowText);
        if (strWindowText.GetLength())
        {
            //变字体
            LOGFONT logfont;
            memset(&logfont, 0, sizeof(logfont));
            logfont.lfHeight = 18;
            logfont.lfWidth = 0;
            logfont.lfWeight = FW_BLACK;
            logfont.lfCharSet = DEFAULT_CHARSET;
            CFont font;
            font.CreateFontIndirect(&logfont);
            pDC->SelectObject(&font);                   
            //打印按钮的文字列
            int nBkMode = pDC->SetBkMode(TRANSPARENT);
            COLORREF colorref =pDC->SetTextColor(RGB(255,0,0));
            pDC->DrawText(strWindowText, &rctSft, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
            pDC->SetTextColor(colorref);
            //随便画一个图标
            pDC->DrawState(CPoint(rctSft.left + 10, rctSft.top + 10), 
                                  CSize(32,32), 
                                  AfxGetApp()->LoadIcon(IDR_MAINFRAME),
                                  DST_ICON,
                                  HBRUSH(NULL));
        }
    }
    //画得到焦点状态
    if( (lpDrawItemStruct->itemState & ODS_FOCUS))
    {
        rctFocus.DeflateRect(4, 4);
        pDC->DrawFocusRect(rctFocus);
    }
}