Windows编程基础之Rect
[Windows编程基础之Rect]
作者:Tocy 时间:2014-09-20
整理本文的最初目的是理清IsRectEmpty和IsRectNull函数的区别,但是在浏览msdn时发现有很多关于Rect函数都没有用过,因此整理下,以作记录并加深记忆。
Rect,矩形区域,通常我们会使用四个坐标表示,一种表示法是矩形区域某个顶点坐标+区域宽高,一种表示法是使用矩形区域中相对的两个顶点。Windows下采用第二种表示,定义如下:
typedef struct tagRECT {
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT;
使用Rect的左上角坐标(left, top)和右下角坐标(right, bottom)来表示。Rect相关的API可以参考如下链接,http://msdn.microsoft.com/zh-cn/library/dd162899.aspx。注意坐标值是有符号的,其单位是逻辑单位,具体含义需要参考窗口映射模式及调用函数。
Win32 API提供如下函数可以操作Rect结构:
|
功能 |
原型 |
|
创建RECT |
BOOL SetRect( _Out_ LPRECT lprc, _In_ int xLeft, _In_ int yTop, _In_ int xRight, _In_ int yBottom); |
|
复制RECT |
BOOL CopyRect(_Out_ LPRECT lprcDst, _In_ const RECT *lprcSrc); |
|
RECT是否相等 |
BOOL EqualRect(_In_ const RECT *lprc1, _In_ const RECT *lprc2); |
|
RECT是否为空 |
BOOL IsRectEmpty(_In_ const RECT *lprc); |
|
设置空RECT |
BOOL SetRectEmpty(_Out_ LPRECT lprc); |
|
RECT缩放 |
BOOL InflateRect(_Inout_ LPRECT lprc, _In_ int dx, _In_ int dy); |
|
RECT平移 |
BOOL OffsetRect(_Inout_ LPRECT lprc, _In_ int dx, _In_ int dy); |
|
点是否在Rect内 |
BOOL PtInRect(_In_ const RECT *lprc, _In_ POINT pt); |
|
Rect求交集 |
BOOL IntersectRect(_Out_ LPRECT lprcDst, _In_ const RECT *lprcSrc1, _In_ const RECT *lprcSrc2); |
|
Rect求并集 |
BOOL UnionRect(_Out_ LPRECT lprcDst, _In_ const RECT *lprcSrc1, _In_ const RECT *lprcSrc2); |
|
Rect求差集 |
BOOL SubtractRect(_Out_ LPRECT lprcDst, _In_ const RECT *lprcSrc1, _In_ const RECT *lprcSrc2); |
说明:
-
Rect什么情况下是空的?(IsRectEmpty返回TRUE的条件)
Rect的left<=right或者top<=bottom,有一个条件成立即可。
-
Rect缩放是双向的,参数是有符号的,整数表示放大,负数表示缩小;但均会在x或者y方向上同时加上dx或dy偏移量。
-
UnionRect函数返回的矩形是包含两个源矩形最小的矩形区域(不要求两个元矩形相交)。
-
SubtractRect函数从字面上理解是从rcSrc1中去掉rcSrc2中的区域,为了计算方便这就要求rcSrc2必须与rcSrc1在x或y方向上完全一样(宽度或者高度一样,亦即rcSrc1去掉rcSrc1与rcSrc2的交集区域还是矩形),否则可能出现不规则图形,这样就无法处理了(若发生类似情况,该函数会直接返回rcSrc1) 。
测试代码如下:
#include <windows.h> #include <iostream> using std::cout; using std::endl; void print_rect(const RECT & rc) { cout << "left = " << rc.left << " top = " << rc.top << " right = " << rc.right << " bottom = " << rc.bottom << endl; } void union_rect_test(); void substract_rect_test(); int main(int argc, char * argv[]) { RECT rcSrc; cout << "ԬRect⊔\n"; SetRect(&rcSrc, 10,10,100,100); print_rect(rcSrc); cout << "\nRect˵Ų⊔\nŴspan>; InflateRect(&rcSrc, 5,5); print_rect(rcSrc); cout << "\n˵С"; InflateRect(&rcSrc, -5,-5); print_rect(rcSrc); union_rect_test(); substract_rect_test(); return 0; } void union_rect_test() { cout <<"\nRect⊔\nrc1 "; RECT rcSrc1; SetRect(&rcSrc1, 10,10,100,100); print_rect(rcSrc1); cout << "rc2 "; RECT rcSrc2; SetRect(&rcSrc2, 150,150, 200,200); print_rect(rcSrc2); RECT rcDst; SetRectEmpty(&rcDst); UnionRect(&rcDst, &rcSrc1, &rcSrc2); cout << "union rect "; print_rect(rcDst); } void substract_rect_test() { cout << "\nRect⊔\nrc1"; RECT rcSrc1; SetRect(&rcSrc1, 10,10,100,100); print_rect(rcSrc1); cout << "rc2 "; RECT rcSrc2; SetRect(&rcSrc2, 10,50, 200,200); print_rect(rcSrc2); RECT rcDst; SetRectEmpty(&rcDst); SubtractRect(&rcDst, &rcSrc1, &rcSrc2); cout << "substract rect(rc1-rc2) "; print_rect(rcDst); SetRect(&rcSrc2, 50,50, 200,200); cout << "֘⊔\nrc1 "; print_rect(rcSrc1); cout << "rc2 "; print_rect(rcSrc2); SetRectEmpty(&rcDst); SubtractRect(&rcDst, &rcSrc1, &rcSrc2); cout << "substract rect(rc1-rc2) "; print_rect(rcDst); }
在windows下测试结果如下图。可对比验证下说明3和4的部分。

MFC中提供CRect用于替换RECT,并添加部分函数,简化相关操作。可参考链接,http://msdn.microsoft.com/zh-cn/library/h58f4c7y.aspx。CRect提供了IsRectNull函数,用于判断Rect的left、top、right、bottom是否全是0(即null rect是指左上角坐标、右下角坐标均在坐标原点的rect)。
注:版权所有,请勿用于商业用途,转载请注明原文地址。本人保留所有权利。
----------------------------------------------------------------------------------------------------------------------------
本文作者:Tocy e-mail: zyvj@qq.com
版权所有@2015-2020,请勿用于商业用途,转载请注明原文地址。本人保留所有权利。

浙公网安备 33010602011771号