C++实现圆角矩形

来源:互联网 发布:淘宝优惠群公告怎么写 编辑:程序博客网 时间:2024/05/17 08:15
大家先看一个原理图(假设区域2,3,4,5的高度都为1像素):
C++实现圆角矩形原理(金山开源程序) - strive_only - 奋斗,我要一直奋斗...等你...
 由图,非圆角矩形是整个虚线围成的矩形区域(rcClient),而所要的圆角矩形是最外围实线形成的区域(rgnWindow)。 现在我们把整个圆角矩形进行分解:
1. rcClient上下各偏移2像素的矩形区域 Rect(rcClient.left, rcClient.top + 2, rcClient.right, rcClient.bottom - 2)
2. rcClinet 左右偏移2像素,高度为1像素的矩形区域 Rect(rcClient.left + 2, rcClient.top, rcClient.right - 2, rcClient.top + 1)
3. 与2区域上下对称的矩形区域 。
4. rcClient左右偏移1像素,高度为1像素的矩形区域 Rect(rcClient.left + 1, rcClient.top + 1, rcClient.right - 1, rcClient.top + 2)
5. 与4区域上下对称的矩形区域。
我们可以很简单的得到上面的5个区域的矩形,然后利用VC中多边形的组合便可以得到如上想要的圆角矩形区域。

下面是金山卫士开源出来的一段实现圆角矩形的代码(其中注释1----5 的地方法对应于上面的分解的5个矩形区域):
template <class T>
class CWHRoundRectFrameHelper
{
    ...........
protected:
    ...........
    void OnSize(UINT nType, CSize size)
    {
        T *pT = static_cast<T*>(this);

        if (nType == SIZE_MINIMIZED)
            return;

        if (size == m_sizeWnd)
            return;

        CRect rcWindow, rcClient;
        CRgn rgnWindow, rgnMinus, rgnAdd;

        pT->GetWindowRect(rcWindow);
        pT->GetClientRect(rcClient);
        pT->ClientToScreen(rcClient);

        rcClient.OffsetRect(- rcWindow.TopLeft());
        //1
        rgnWindow.CreateRectRgn(rcClient.left, rcClient.top + 2, rcClient.right, rcClient.bottom - 2);
        //2
        rgnAdd.CreateRectRgn(rcClient.left + 2, rcClient.top, rcClient.right - 2, rcClient.top + 1);
        rgnWindow.CombineRgn(rgnAdd, RGN_OR);
        //3
        rgnAdd.OffsetRgn(0, rcClient.Height() - 1);
        rgnWindow.CombineRgn(rgnAdd, RGN_OR);
        //4
        rgnAdd.SetRectRgn(rcClient.left + 1, rcClient.top + 1, rcClient.right - 1, rcClient.top + 2);
        rgnWindow.CombineRgn(rgnAdd, RGN_OR);
        //5
        rgnAdd.OffsetRgn(0, rcClient.Height() - 3);
        rgnWindow.CombineRgn(rgnAdd, RGN_OR);

        pT->SetWindowRgn(rgnWindow);

        m_sizeWnd = size;
    }
    ............
};
0 0