首页 > 代码库 > Windows编程基础之Rect

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);

说明:

  1. Rect什么情况下是空的?(IsRectEmpty返回TRUE的条件)

    Rect的left<=right或者top<=bottom,有一个条件成立即可。

  2. Rect缩放是双向的,参数是有符号的,整数表示放大,负数表示缩小;但均会在x或者y方向上同时加上dx或dy偏移量。
  3. UnionRect函数返回的矩形是包含两个源矩形最小的矩形区域(不要求两个元矩形相交)。
  4. 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)。

?

注:版权所有,请勿用于商业用途,转载请注明原文地址。本人保留所有权利。

Windows编程基础之Rect