想实现groupbox中,让控件groupbox为圆角,并且有shadow效果,阴影效果得自己添加
哪位高手能告诉这个自绘控件应该怎么实现,不熟悉重绘

解决方案 »

  1.   

    http://www.codeproject.com/KB/miscctrl/xpgroupbox.aspx
      

  2.   

    自己继承了groupbox,重载了OnPaint()实现了,貌似还有bug,不怎么会改了CPaintDC dc(this); // device context for painting
    // TODO: Add your message handler code here
    // Do not call CStatic::OnPaint() for painting messages /*
    圆角的groupbox为自绘控件,采用RoundRect+CStatic模拟实现,控件的shadow效果采用GDI+绘制上去
    由于GDI+只能在控件的当前区域进行操作,所以控件的实际区域是把右下方空出一个用于绘制shadow效果的区域
    */ CBrush* pOldBrush = dc.GetCurrentBrush();
    CPen* pOldPen = dc.GetCurrentPen();
    CFont* POldFont = dc.GetCurrentFont(); // 在此处进行控件的绘制
    CRect rect,clientRect;
    GetClientRect(&clientRect);
    dc.SelectStockObject(NULL_BRUSH); // 将当前画刷置空,在绘制圆角矩形时内部区域不进行填充 TEXTMETRIC tm;
    dc.GetTextMetrics(&tm); // 获取字体的高度
    int fontHight = (tm.tmHeight + tm.tmExternalLeading)/2;
    CPen pen(PS_SOLID, 1, RGB(128,128,128)); // 灰色画笔,用于绘制边框
    dc.SelectObject(pen);
    rect = CRect(clientRect.left,clientRect.top+fontHight,clientRect.right-5,clientRect.bottom-5); // 斜下方留出绘制控件shadow的区域
    dc.RoundRect(rect,CPoint(12,12)); // 绘制圆角边框 dc.SelectObject(pOldPen); // 绘制shadow
    Graphics graphics(dc.m_hDC);
    graphics.SetPageUnit(UnitPixel);
    INT left = rect.left;
    INT right = rect.right;
    INT top = rect.top;
    INT bottom = rect.bottom;
    INT offsetX = (right-left)*10/100;
    INT offsetY = (bottom-top)*10/100; GraphicsPath pt;
    pt.AddArc(right-offsetX, top, offsetX, offsetY, 270, 90);
    pt.AddArc(right-offsetX, bottom-offsetY, offsetX, offsetY, 0, 90);
    pt.AddArc(left, bottom - offsetY, offsetX, offsetY, 90, 90);
    pt.AddArc(left, top, offsetX, offsetY, 180, 90);
    pt.AddLine(left + offsetX, top, right - offsetX/2, top); GraphicsPath &ShadowPath = *(pt.Clone()); Matrix ShadowMatrix;
    ShadowMatrix.Translate(5,5);    
    ShadowPath.Transform(&ShadowMatrix); Region controlRegion(&pt);  
    Region ShadowRegion(&ShadowPath);   ShadowRegion.Exclude(&controlRegion); // 移动之后去掉重合区域,即得到绘制shadow的区域
    PathGradientBrush brush(&ShadowPath);  
    brush.SetCenterColor(Color(0, 0, 0, 0));   Color colors[] ={Color(128, 128, 128, 128)};  
    int count = 1;  
    brush.SetSurroundColors(colors, &count);  
    brush.SetFocusScales(0.75f, 0.75f); graphics.FillRegion(&brush, &ShadowRegion); // 渐变色填充shadow区域
    delete &ShadowPath; // 绘制标题
    CSize titleSize;
    CRect titleRect;
    if(m_caption.IsEmpty())
    {
    GetWindowText(m_caption);
    if ( ! m_caption.IsEmpty() )
    m_caption = _T(" ") + m_caption + _T(" ");
    }
    if ( ! m_caption.IsEmpty() )
    {
    titleSize = dc.GetTextExtent(m_caption);
    }
    else
    {
    titleSize.cx = 0;
    titleSize.cy = 0;
    } titleRect.top = clientRect.top + 2;
    titleRect.left = clientRect.left + (clientRect.Width() - titleSize.cx) / 2 ;
    titleRect.bottom = clientRect.top + titleSize.cy + 2;
    titleRect.right = titleRect.left + titleSize.cx; HBRUSH bkBrush = (HBRUSH)GetStockObject(GRAY_BRUSH);
    dc.SelectObject(&bkBrush);
    dc.SetBkColor(RGB(236,233,216)); // 选择灰色的背景色,和父窗体同背景色

    CFont titleFont; // 书写标题的字体,采用windows默认字体
    titleFont.CreatePointFont(90,"MS Shell Dlg");
    LOGFONT logFont;
    titleFont.GetLogFont (&logFont);
    logFont.lfWeight = FW_NORMAL;
    dc.SelectObject(&titleFont);
    dc.DrawText(m_caption, titleRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_NOCLIP);
    titleFont.DeleteObject(); // 释放创建的字体 dc.SelectObject(pOldBrush);
    dc.SelectObject(POldFont); pOldBrush->DeleteObject();
    POldFont->DeleteObject();
    pOldPen->DeleteObject();
    pen.DeleteObject();