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

?

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

时间: 2024-11-17 18:26:59

Windows编程基础之Rect的相关文章

Windows编程基础

1. 控件() 使用Windows窗体时, 就是在使用System.Windows.Forms名称空间 大多数控件 都派生于System.Windows.Forms.Control类 1.1 控件属性 Anchor 控件的容器大小发生改变时, 该如何响应 Enable 是否可接收用户输入 1.2 控件的定位.停靠和对齐 1.3 事件 3种处理事件的基本方式 <1>双击控件 <2>Properties窗口中Events列表, 单击闪电图标, 就会显示Events列表      在Ev

windows编程基础之内核对象

      学好windows编程,理解内核对象还是至关重要的(●'?'●).闲话不多说,下面先来了解一下关于内核对象的知识:       内核对象(kernel object):内核对象是用于管理进程.线程和文件等诸多种类的大量资源.       内核对象的分类:进程对象,线程对象,互斥量(mutex)对象,信号量(semaphore)对象,事件对象,作业对象,文件对象,文件映射对象,管道(pipe)对象,邮件槽(mailslot)对象,I/O完成端口对象,线程池工厂(thread pool 

MFC入门教程01 Windows编程基础

走进windows编程的世界-----入门篇

1   Windows编程基础 1.1Win32应用程序基本类型 1)  控制台程序 不须要完好的windows窗体,能够使用DOS窗体方式显示 2)  Win32窗体程序 包括窗体的程序,能够通过窗体与程序进行交互 3)  Win32库程序 提供已有的代码,供其它程序使用 动态库(DLL):是在运行的时候能够载入的. 静态库(LIB):是在编译链接是使用的程序.成为当前程序的一部分. 1.2头文件和库 1.2.1头文件 主要的头文件windows.h包括了windows经常使用的定义等,其它,

【Windows编程】系列第六篇:创建Toolbar与Statusbar

上一篇我们学习了解了如何使用Windows GDI画图,该应用程序都是光光的静态窗口,我们使用Windows应用程序,但凡稍微复杂一点的程序都会有工具栏和状态栏,工具栏主要用于一些快捷功能按钮.比如典型的windows应用程序的上面是菜单栏,从菜单栏我们可以选择应用程序提供的各种功能,但是有的功能比较常用,且不能放在第一级菜单,需要进入二级.三级甚至更多的菜单才能选择.显然这样使用起来比较麻烦,于是这时候工具栏的作用就体现出来了,一般工具栏位于菜单栏的下面,但是位于客户窗口的上面.下面就是win

《逐梦旅程 WINDOWS游戏编程之从零开始》笔记5——Direct3D编程基础

第11章 Direct3D编程基础 2D游戏是贴图的艺术,3D游戏是渲染的艺术.这句话在我学过了之前的GDI编程之后,前一句算是有所体会,现在是来理解后一句的时候了. 安装DirectX SDK配置啥的就不说了,直接进入正题,先来个典型的Direct3D程序框架图: 主要分为5个部分: 创建一个Windows窗口 Direct3D的初始化 消息循环 渲染图形 结束应用程序,清除在初始化阶段锁创建的COM对象,退出程序 至于COM (Component Object Model, 组件对象模型)

(转)Windows驱动编程基础教程

版权声明 本书是免费电子书. 作者保留一切权利.但在保证本书完整性(包括版权声明.前言.正文内容.后记.以及作者的信息),并不增删.改变其中任何文字内容的前提下,欢迎任何读者 以任何形式(包括各种格式的文档)复制和转载本书.同时不限制利用此书赢利的行为(如收费注册下载,或者出售光盘或打印版本).不满足此前提的任何转载. 复制.赢利行为则是侵犯版权的行为. 发现本书的错漏之处,请联系作者.请不要修改本文中任何内容,不经过作者的同意发布修改后的版本. 作者信息 作者网名楚狂人.真名谭文.在上海从事W

有一定基础的 C++ 学习者该怎样学习 Windows 编程?

人的心理有个奇异的特性:一项知识一旦学会之后,学习过程中面临的困惑和不解非常快就会忘得干干净净,似乎一切都是自然而然,本来就该这种.因此,关于「怎样入门」这类问题,找顶尖高手来回答,未必能比一个刚入门不久的人来回答要好.就譬如最高票的那个回答,是一个非常精通 Windows 编程的高人回答的,但这种答案能给刚開始学习的人带来多少帮助,我这里想先打一个问号. 前段时间刚辅导了一个学生学会了 Win32 GUI 编程,刚好看到这个问题,顺手就邀请他回答了.并不是是给他布置总结作业,不过希望能从他这里

有一定基础的 C++ 学习者该如何学习 Windows 编程?

人的心理有个奇妙的特性:一项知识一旦学会之后,学习过程中面临的困惑和不解很快就会忘得干干净净,似乎一切都是自然而然,本来就该这样的.因此,关于「如何入门」这类问题,找顶尖高手来回答,未必能比一个刚入门不久的人来回答要好.就譬如最高票的那个回答,是一个非常精通 Windows 编程的高人回答的,但这样的答案能给初学者带来多少帮助,我这里想先打一个问号. 前段时间刚辅导了一个学生学会了 Win32 GUI 编程,刚好看到这个问题,顺手就邀请他回答了.并非是给他布置总结作业,仅仅是希望能从他这里得到第