详解路径层和裁剪区域应用

路径层概念


    除了已有的位图,画笔,画刷,字体,调色板和区域之外,还一个新的GDI对象:路径层。它可以理解为该对象在View的客户区中所占领的区域,在各自区域内可以进行作图、文字输出等,不受外界影响。


路径层创建


      在MFC中,路径层是利用CDC类中的BeginPath和EndPath这两个函数来实现的。

第一步:使用BeginPath在设备描述表中打开一个路径层;

第二步:利用GDI提供的绘图函数确定路径层对象;

第三步:绘图完成后,使用EndPath函数关闭这个路径层;


在Win32中,可以用于定义路径的GDI绘图函数包括如下函数:

AngleArc
Arc
ArcTo  
Chord  
CloseFigure   
Ellipse  
ExtTextOut   
LineTo   
MoveToEx   
Pie  
PolyBezier   
PolyBezierTo   
PolyDraw  
Polygon   
Polyline    
PolylineTo    
PolyPolygon   
PolyPolyline   
Rectangle  
RoundRect  
TextOut 


路径层相关函数


以下这些path相关的函数被调用后,路径层对象就从设备描述表中丢弃,各个相关的函数功能参见MSDN。



路径层应用


路径层的引入,使得我们的作图更加的多样化,也丰富了画图效果,下面代码演示了路径层的使用,绘图操作在OnDraw中实现。

void CMFC_TestView::OnDraw(CDC* pDC)
{
    CMFC_TestDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;
    //创建画刷
    CBrush Brush(RGB(255,0,0));
    //画刷选入DC
    CBrush *pOldBrush = pDC->SelectObject(&Brush);
    //输出文字
    CString strBookName = "VC++ 深入编程 ";
    CString strAuthor = "Sunxin";
    pDC->SetTextColor(RGB(0,0,255));
    pDC->TextOut(100,50,strBookName + strAuthor);

    CSize sz = pDC->GetTextExtent(strBookName + strAuthor);
    //打开路径层
    pDC->BeginPath();
    //路径层对象确定的范围,大小等于字符串占据的空间
    pDC->Rectangle(100, 50, 100+sz.cx,50+sz.cy);
    //关闭路径层
    pDC->EndPath();
    //设置裁剪区和路径层关系
    pDC->SelectClipPath(RGN_DIFF);


    //画圆角矩形,在路径层范围内
    pDC->RoundRect(CRect(100,100,150,150),CPoint(120,120));
    pDC->RoundRect(CRect(150,150,250,250),CPoint(200,200));
    //输出文本,在路径层范围内
    pDC->SetTextColor(RGB(0,255,0));
    pDC->TextOut(160,110,"hello world!");


    //在该路径层确定的范围内的GDI操作,不受外界影响
    pDC->BeginPath();
    pDC->Rectangle(100, 100, 250, 250);//路径层确定的范围
    pDC->EndPath();
	//pDC->FillPath();
    //pDC->WidenPath();
    //pDC->StrokeAndFillPath();
    //pDC->StrokePath();
    pDC->SelectClipPath(RGN_DIFF);

    //画网格
    for (int i = 0; i < 350; i += 10)
    {
        pDC->MoveTo(0,i);
        pDC->LineTo(350 ,i);
        pDC->MoveTo(i,0);
        pDC->LineTo(i,350);
    }

    pDC->SelectObject(pOldBrush);	
}

运行效果:


                          图1 有路径层对象的效果图


 

                            图2 没有路径层对象的效果图


裁剪区域概念


裁剪区域(clipping region)可以把它理解为一个绘图区域,其大小可以由我们来控制。对于单文档应用程序来说,可以把客户区看做是一个大的裁剪区域。选定了裁剪区域后,后续的绘图操作就在这个裁剪区中生效。


裁剪区域创建


在MFC中有一个CRgn类,该类提供了关于区域的相关操作,下面是创建裁剪区域对象步骤。

步骤一:定义一个CRgn的对象。

步骤二:调用CRgn中的初始化函数,用于确定裁剪区域形状、大小等要素。

步骤三:调用SelectClipRgn函数将当前裁剪区域选入设备描述表中。


SelectClipRgn有两种形式,函数声明如下:

int SelectClipRgn(CRgn* pRgn);
int SelectClipRgn(CRgn* pRgn,int nMode);
现在着重说明下第二种形式的第二参数,nMode参数指定了当前裁剪区域和设备描述表中的裁剪区域的组合方式,它可以是以下几种方式:


RGN_AND 两个剪裁区域的公共部分
RGN_OR 两个剪裁区域的全部
RGN_XOR 两个剪裁区域的全部除去公共部分
RGN_DIFF          hSrcRgn1不在hSrcRgn2中的部分
RGN_COPY        hSrcRgn1的全部(忽略hSrcRgn2)


CDC类中提供了一个SelectClipPath函数,该函数的作用是将当前的路径层和设备描述表中的已有裁剪区域按照一定模式进行互操作,操作模式也是以上五种模式。


裁剪区域和路径层综合应用


下面就裁剪区域和路径层进行综合应用进行演示,关键代码如下:

void CMFC_TestView::OnDraw(CDC* pDC)
{
    CMFC_TestDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    //定义画刷
    CBrush Brush(RGB(0,250,0));
    CBrush *pOldBrush = pDC->SelectObject(&Brush);

    //设置裁剪区
    CRgn rgnA;
    CRgn rgnB;
    rgnA.CreateEllipticRgn(0, 0, 300, 300);
    pDC->SelectClipRgn(&rgnA);

    rgnB.CreateEllipticRgn(200,200, 500, 500);
    pDC->SelectClipRgn(&rgnB,RGN_OR);
    //文本设置和输出
    pDC->SetTextColor(RGB(0,0,250));
    pDC->TextOut(130, 150,"code");

    //创建路径层对象
    pDC->BeginPath();
    pDC->RoundRect(CRect(100,100,200,200), CPoint(150 ,150));
    pDC->EndPath();
    pDC->SelectClipPath(RGN_DIFF);

    //路径层中的矩形
    pDC->Rectangle(CRect(340,340,360,360));

    //创建路径层对象
    pDC->BeginPath();
    pDC->RoundRect(CRect(300,300,400,400), CPoint(350 ,350));
    pDC->EndPath();
    pDC->SelectClipPath(RGN_DIFF);
    //画网格
    for (int i = 0; i < 500; i += 10)
    {
        pDC->MoveTo(0,i);
        pDC->LineTo(500 ,i);
        pDC->MoveTo(i,0);
        pDC->LineTo(i,500);
    }

    pDC->SelectObject(pOldBrush);

}
运行效果:


                                      图 3路径层和裁剪区域综合应用


原文地址:https://www.cnblogs.com/jinxiang1224/p/8468377.html