[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)。
?
注:版权所有,请勿用于商业用途,转载请注明原文地址。本人保留所有权利。