Windows裁剪区域

    作者: admin     浏览: 77     评论: 0     分类: C++     标签: 区域裁剪,CreateRectRgn,CreatePolygonRgn,CombineRgn

裁剪区域

指定某个区域是可以被绘图
即指定某个区域是可以被绘图的,在这个区域以外的地方,绘图无效。
即被会这个区域的边界给裁掉。只留下在区域内的图形。

CreateRectRgn ()//创建矩形区域<br/>
CombineRgn ()//合并两个区域<br/>
SelectClipRgn ()//设定剪载区域<br/>


以下是《Windows程序设主》第五章的内容

建立和绘制剪裁区域  

剪裁区域是对显示器上一个范围的描述,这个范围是矩形、多边形和椭圆的组合。剪裁区域可以用於绘制和剪裁,通过将剪裁区域选进装置内容,就可以用剪裁区域来进行剪裁(就是说,将可以绘图的范围限制为显示区域的一部分)。与画笔、画刷和点阵图一样,剪裁区域是GDI物件,您应该呼叫DeleteObject来删除您所建立的剪裁区域。

当您建立一个剪裁区域时,Windows传回一个该剪裁区域的代号,型态为HRGN。最简单的剪裁区域是矩形,有两种建立矩形的方法:

  1. hRgn = CreateRectRgn (xLeft, yTop, xRight, yBottom) ;
  2. 或者
  3. hRgn = CreateRectRgnIndirect (&rect) ;
  4. 您也可以建立椭圆剪裁区域:
  5. hRgn = CreateEllipticRgn (xLeft, yTop, xRight, yBottom) ;
  6. 或者
  7. hRgn = CreateEllipticRgnIndirect (&rect) ;
  8. CreateRoundRectRgn建立圆角的矩形剪裁区域。

建立多边形剪裁区域的函式类似於Polygon函式:

  1. hRgn = CreatePolygonRgn (&point, iCount, iPolyFillMode) ;
  2. point参数是一个POINT型态的结构阵列,iCount是点的数目,iPolyFillModeALTERNATE或者WINDING。您还可以用CreatePolyPolygonRgn来建立多个多边形剪裁区域。

那么,您会问,剪裁区域究竟有什么特别之处?下面这个函式才真正显示出了剪裁区域的作用:

iRgnType = CombineRgn (hDestRgn, hSrcRgn1, hSrcRgn2, iCombine) ;
这一函式将两个剪裁区域(hSrcRgn1和hSrcRgn2)组合起来并用代号hDestRgn指向组合成的剪裁区域。这三个剪裁区域代号都必须是有效的,但是hDestRgn原来所指向的剪裁区域被破坏掉了(当您使用这个函式时,您可能要让hDestRgn在初始时指向一个小的矩形剪裁区域)。

iCombine参数说明hSrcRgn1和hSrcRgn2如何组合,见表5-9。

表5-9

  1. iCombine 新剪裁区域
  2. RGN_AND 两个剪裁区域的公共部分
  3. RGN_OR 两个剪裁区域的全部
  4. RGN_XOR 两个剪裁区域的全部除去公共部分
  5. RGN_DIFF hSrcRgn1不在hSrcRgn2中的部分
  6. RGN_COPY hSrcRgn1的全部(忽略hSrcRgn2

从CombineRgn传回的iRgnType值是下列之一:NULLREGION,表示得到一个空剪裁区域;SIMPLEREGION,表示得到一个简单的矩形、椭圆或者多边形;COMPLEXREGION,表示多个矩形、椭圆或多边形的组合;ERROR,表示出错了。

剪裁区域的代号可以用於四个绘图函式:

  1. FillRgn (hdc, hRgn, hBrush) ;
  2. FrameRgn (hdc, hRgn, hBrush, xFrame, yFrame) ;
  3. InvertRgn (hdc, hRgn) ;
  4. PaintRgn (hdc, hRgn) ;
  5. FillRgnFrameRgnInvertRgn类似於FillRectFrameRectInvertRectFrameRgnxFrameyFrame参数是画在区域周围的边框的宽度和高度。PaintRgn函式用装置内容中目前画刷填入所指定的区域。所有这些函式都假定区域是用逻辑座标定义的。

在您用完一个区域後,可以像删除其他GDI物件那样删除它:
DeleteObject (hRgn) ;
矩形与区域的剪裁  

区域也在剪裁中扮演了一个角色。InvalidateRect函式使显示的一个矩形区域失效,并产生一个WM_PAINT讯息。例如,您可以使用InvalidateRect函式来清除显示区域并产生一个WM_PAINT讯息:

InvalidateRect (hwnd, NULL, TRUE) ;
您可以通过呼叫GetUpdateRect来取得失效矩形的座标,并且可以使用ValidateRect函式使显示区域的矩形有效。当您接收到一个WM_PAINT讯息时,无效矩形的座标可以从PAINTSTRUCT结构中得到,该结构是用BeginPaint函式填入的。这个无效矩形还定义了一个「剪裁区域」,您不能在剪裁区域外绘图。

Windows有两个作用於剪裁区域而不是矩形的函式,它们类似於InvalidateRect和ValidateRect:

  1. InvalidateRgn (hwnd, hRgn, bErase) ;
  2. ValidateRgn (hwnd, hRgn) ;

当您接收到一个由无效区域引起的WM_PAINT讯息时,剪裁区域不一定是矩形。

您可以使用以下两个函式之一:

  1. SelectObject (hdc, hRgn) ;
  2. SelectClipRgn (hdc, hRgn) ;
  3. 通过将一个剪裁区域选进装置内容来建立自己的剪裁区域,这个剪裁区域使用装置座标。

GDI为剪裁区域建立一份副本,所以在将它选进装置内容之後,使用者可以删除它。Windows还提供了几个对剪裁区域进行操作的函式,如ExcludeClipRect用於将一个矩形从剪裁区域里排除掉,IntersectClipRect用於建立一个新的剪裁区域,它是前一个剪裁区域与一个矩形的交,OffsetClipRgn用於将剪裁区域移动到显示区域的另一部分。



什么是剪裁区域

剪裁区域就是设备描述表中的区域,用于描画处理。

所以一切还要从区域说起:

设备描述表中的区域

与画笔、画刷和位图一样,区域也是GDI对象,需要调用DeletObject来删除创建的区域

区域类型句柄为HRGN

创建矩形区域

hRgn = CreateRectRgn(xLeft, yTop, xRight, yBottom);

hRgn = CreateRectRgnIndirect(&rect);

创建椭圆区域

hRgn = CreateEllipticRgn(xLeft, yTop, xRight, yBottom);

hRgn = CreateEllipticRgnIndirect(&rect);

创建圆角的矩形区域

CreateRoundRectRgn

创建多边形区域

hRgn = CreatePolygonRgn(&point, iCount, iPolyFillMode);

iPolyFillMode 是 ALTERNATE 或者 WINDING

ALTERNATE:封闭区域内部画随便一条射线,只有这条射线能穿过了奇数条边界线时才填充封闭区域

WINDING:封闭区域内部画随便一条射线,只有这条射线能穿过了奇数条边界线时才填充封闭区域,这和ALTERNATE一样。如果这条射线穿过偶数条边界线,如果一个方向(封闭区的边界线方向)的边界线数与另一个方向的边界线数不相等,就填充区域。

创建多个多边形区域

CreatePolyPolygonRgn

区域的作用:

iRgnType = CombineRgn(hDestRgn, hSrcRgn1, hSrcRgn2, iCombine);

这一函数将两个源区域(hSrcRgn1, hSrcRgn2)组合起来并用句柄hDestRgn指向组合成的目标区。这3个区域句柄必须都有效,但是hDestRgn所指向的原来的区域被破坏掉了。


iCombine含有的值 新区域

RGN_AND 两个源区域的公共部分

RGN_OR 两个源区域的全部

RGN_XOR 两个源区域的全部除去公共部分

RGN_DIFF hSrcRgn1不在hSrcRgn2中的部分

RGN_COPY hSrcRgn1的全部(忽略hSrcRgn2)


从CombineRgn返回的iRgnType值是下列之一:

NULLREGION:表示得到一个空区域

SIMPLEREGION:表示得到一个简单的矩形、椭圆或多边形

COMPLEXREGION:表示得到一个多个矩形、椭圆或多边形的组合

ERROR:表示出错了

区域的句柄可用的4个绘图函数:

FillRgn(hdc, hRgn, hBrush); 类似FillRect

FrameRgn(hdc, hRgn, hBrush, xFrame, yFrame); 类似FrameRect

InverRgn(hdc, hRgn); 类似InvertRect

PaintRgn(hdc, hRgn); 用设备描述表中的当前画刷填充所指的区域。

所有这些函数都假设区域是逻辑坐标定义的

删除一个区域

DeleteObject(hRgn);

Windows的2个作用于区域而不是矩形的函数

InvalidateRgn(hwnd, hRgn, bErase); 类似于InvalidateRect

ValidateRgn(hwnd, hRgn); 类似于ValidateRect

上面两个函数也会以WM_PAINT消息作出反应

下面开始说明剪裁区域了

首先是创建剪裁区域

SelectObject(hdc, hRgn);

SelectClipRgn(hdc, hRgn);

上面两个函数都是将一个区域选进设备描述表来创建自己的剪裁区域,这个剪裁区域使用设备坐标。

对剪裁区域的操作函数:

ExcludeClipRect 用于将一个矩形从剪裁区域里排除掉

IntersectClipRect 用于创建一个新的剪裁区域,他是前一个剪裁区域与一个矩形的交集

OffsetClipRgn 用于将剪裁区域移动到客户区的另一部分

注意:

GDI会为剪裁区域创建一个副本,所以在将新创建的区域选进设备描述表后,用户可以删除这个区域。

CombineRgn(hDestRgn, hSrcRgn1, hSrcRgn2, iCombine); 中使用的3个区域句柄必须都是有效的,即都要是创建了的。

在调用CombineRgn函数后,源区域即可以删除了,删除不会影响新合成的区域