CRectTracker类的使用
CRectTracker(俗称“橡皮筋”类)是一个非常有意思的类。你在Windows中经常看到这样的情况:它可以用做显示边界,你也可以扽它的八个角用来放大缩小,或做框选使用。如何通过编程来实现这种功能呢?这就是CRectTracker类的作用。下图是这个程序运行的结果:

下面让我们来从头做一个新的工程文件,来慢慢掌握它的功能吧。
建立一个单文档的工程文件,将其命名为RectTracke。单击finish完成工程的建立;先编译一下,第一次生成obj文件吧,在它生成的过程中,我们继续往下讲解;
第一步:
在CRectTrackeDoc类中生成一个公有的数据成员:m_RectTracker;之所以设成公有,因为要在View中调用它。
class CRectTrackeDoc : public CDocument
{
protected: // create from serialization only
CRectTrackeDoc();
DECLARE_DYNCREATE(CRectTrackeDoc) // Attributes
public:
CRectTracker m_RectTracker;
接着我们来初始化它,在CRectTrackeDoc构造函数中:
CRectTrackeDoc::CRectTrackeDoc()
{
// TODO: add one-time construction code here
m_RectTracker.m_rect.SetRect(,,,); //矩形位置 m_RectTracker.m_nStyle = CRectTracker::dottedLine | CRectTracker::resizeInside;
}
其中: m_rect是CRectTracker中用来控制四边形的大小位置的数据成员, SetRect使用的是View的坐标; m_nStyle是CRectTracker的类型,CRectTracker::resizeInside和CRectTracker::resizeOutside是说明在m_rect的内部还是外部画区域(它们是互异的),CrectTrakcer::dottedLine是用点划线来画四边形的区域边界。 其他的值还有: CRectTracker::solidLine:用来画实线边界;(和dottedLine是互异的) CRectTracker::hatchedBorder:边界带抛面线; CRectTracker::hatchInside:内部带抛面线; 你可以运行前面的例子,上述参数都有使用。你也可以在第二步中逐一使用它们来加深理解它们各自的含义;
第二步:
在CRectTrackeView 类中添加一个公有成员变量bDraw,用来判断是否需要在矩形框中画椭圆
class CRectTrackeView : public CView
{
protected: // create from serialization only
CRectTrackeView();
DECLARE_DYNCREATE(CRectTrackeView) // Attributes
public:
CRectTrackeDoc* GetDocument();
BOOL bDraw;
在构造函数中初始化bDraw = false,表示初始时不在矩形宽中画椭圆,只有鼠标左键按下时,bDraw为true.才进行画椭圆操作
CRectTrackeView::CRectTrackeView()
{
// TODO: add construction code here
bDraw = FALSE;
}
第三步:
接着我门在视图中画一个蓝色的椭圆; 在CRectView的OnDraw中继续我们的工作:
void CRectTrackeView::OnDraw(CDC* pDC)
{
CRectTrackeDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc); CBrush brush(RGB(,,));
CBrush * oldBrush = pDC->SelectObject(&brush);
CRect rect; pDoc->m_RectTracker.GetTrueRect(&rect); //得到CRectTracker中的m_rect的大小,将其传递给rect; if(bDraw)
{
pDC->Ellipse(&rect);
} pDoc->m_RectTracker.Draw(pDC); //这句画才真正的将这个四边形画出来; pDC->SelectObject(oldBrush); // TODO: add draw code for native data here
}
这个时候运行程序,将会看到在视类客户区200,200,100,100的位置出现一个矩形区域,因为bDraw参数为false,此时并没有画出椭圆。如下图:

第四步:
如何像例子中的那样随着鼠标的移动自动在椭圆的周围改变光标呢?很简单只要将下面的代码加入到CRectTrackeView::OnSetCursor()就可以了:它调用了CRectTracker中的SetCursor()函数。 注意:OnSetCursor是一个消息响应函数,当鼠标在改矩形区域中的时候,会产出消息,并调用OnSetCursor函数。
BOOL CRectTrackeView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default CRectTrackeDoc* pDoc = GetDocument(); if((pWnd == this) && (pDoc->m_RectTracker.SetCursor(this,nHitTest)))
{
return TRUE;
} return CView::OnSetCursor(pWnd, nHitTest, message);
}
编译运行一下,鼠标变化了。
第五步:
添加鼠标左键按下消息响应函数,该函数功能呢:当在矩形区域内点击左键并拖动的时候,则在矩形区域内把椭圆绘制出来, 当在矩形区域外点击鼠标左键并拖动的时候,则重新绘制一个矩形区域。运行结果如第一张图。
void CRectTrackeView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default //判断鼠标点击的区域是在哪里,在在矩形区域内,还是区域外
int nRetCode = GetDocument()->m_RectTracker.HitTest(point); if(nRetCode < ) //不在矩形区域
{
//给temp变量初始化
CRectTracker temp;
temp.m_rect.SetRect(,,,);
temp.m_nStyle = CRectTracker::dottedLine | CRectTracker::resizeInside; //TrackRubberBand函数直到鼠标左键提起的时候才会返回,并把左键提起的位置也记录了下来
//该函数过程中,不会产生鼠标移动消息
temp.TrackRubberBand(this,point,TRUE);
//使得矩形为正确的坐标,不会出现负的坐标
temp.m_rect.NormalizeRect();
//此时把bDraw设为false
bDraw = FALSE;
CClientDC dc(this);
//把新的矩形区域绘制出来
temp.Draw(&dc);
}
else //在矩形区域内
{
//Track和TrackRubberBand类似,直到鼠标左键提起的时候才会返回,并把左键提起的位置也记录了下来
//该函数过程中,不会产生鼠标移动消息
GetDocument()->m_RectTracker.Track(this,point,TRUE);
//设置为true,则需要在矩形内绘制椭圆
bDraw = TRUE; //窗口无效,调用Onpaint函数
Invalidate(TRUE);
} CView::OnLButtonDown(nFlags, point);
}
编译运行,当你按下鼠标并拖动,你将看到效果了。
我们如何让鼠标画一个“橡皮筋”区域呢? 在CRectTracker类中的成员函数就是:TrackRubberBand(this,point,TRUE); 注意其中的三个参数:
第一个参数,画“橡皮筋”的窗体的指针,当然是this; 第二个参数,画“橡皮筋”的起始点。 让我们注意第三个参数,它非常有意思。当你使用 FALSE时(TRUE 值是缺省的),你的“橡皮筋”只能从左上到右下的画,不允许反向。也就是不能够从下往上绘图。编译运行一下FALSE这个值。
特别值得注意的是:在TrackRubberBand的过程中是以右键的抬起为结束的,这其间并没有CView的MouseMove发生。这一点一定要记住!这时鼠标画过的区域已经记录在temp的m_rect 中了,你可以根据它进行后续的判断工作。至于下面的正规化语句函数的作用与CRect中的正规化函数的作用一致:使四边形的四个角的坐标符合右大于左,底大于顶的坐标值。它主要是为了防止你使用TrackRubberBand 的FALSE参数而引起的可能出现的错误。
HitTest(CPoint point)的功能:当你鼠标被按下的时候,你可以调用这个函数,它将返回鼠标点在了四边形的什么位置:

以上就是CRectTracker类的用法。
CRectTracker类的使用的更多相关文章
- CRectTracker类的使用--橡皮筋窗口
CRectTracker(俗称“橡皮筋”类)是一个非常有意思的类.你在Windows中经常看到这样的情况:它可以用做显示边界,你也可以扽它的八个角用来放大缩小,或做框选使用.如何通过编程来实现这种功能 ...
- MFC 相关类、函数
timeSetEvent()函数 CRectTracker类的使用 SetLocalTime设置本地时间 AdjustTokenPrivileges启用权限
- Java类的继承与多态特性-入门笔记
相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...
- MFC类目录及头文件(转)
类 描述 头文件 CAnimateCtrl 自动化通用控件 afxcmn.h CArchive afx.h CArchiveException afx.h CArray afxtempl.h CAsy ...
- C++ 可配置的类工厂
项目中常用到工厂模式,工厂模式可以把创建对象的具体细节封装到Create函数中,减少重复代码,增强可读和可维护性.传统的工厂实现如下: class Widget { public: virtual i ...
- Android请求网络共通类——Hi_博客 Android App 开发笔记
今天 ,来分享一下 ,一个博客App的开发过程,以前也没开发过这种类型App 的经验,求大神们轻点喷. 首先我们要创建一个Andriod 项目 因为要从网络请求数据所以我们先来一个请求网络的共通类. ...
- ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库
在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...
- ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core
背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...
- .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类
.NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件功能比较简单,有的则比较复杂,并且依赖其它组件.除 ...
随机推荐
- 图说Oracle基础知识(一)
本文主要对Oralce数据库操作的基础知识进行一下梳理,以便进行归纳总结.适用于未使用过Oracle数据库的读者,或需要学习Oracle数据库方面的基础知识.如有不足之处,还请指正. 关于SQL介绍的 ...
- Foundry feats. MultiverseStudio
https://www.foundry.com/news-awards/foundry-jcube-announcement 经过这么多年的过程,本周本产品终于发布了PR,这次是由Foundry独家代 ...
- react 会员登录
会员登录在我们的好多项目中都有用到,比如在后台管理系统,它的第一步就需要你进行登录,还有在我们常见的京东.淘宝.网易云音乐等一系列的软件上面都需要进行登录. 下面我们直接上代码 fetch(url,{ ...
- [转] Scala Try 与错误处理
一.概述 当你在尝试一门新的语言时,可能不会过于关注程序出错的问题, 但当真的去创造可用的代码时,就不能再忽视代码中的可能产生的错误和异常了. 鉴于各种各样的原因,人们往往低估了语言对错误处理支持程度 ...
- 以太坊 ERC20 与 ERC721 深度解密
去年11月份的一段时间,Ethereum网络突然变的特别拥堵,原因是兴起了一款以太坊养猫的Dapp游戏,超级可爱的猫形象,再加上配种,繁殖和拍卖等丰富的玩法,风靡了币圈. 一时间币圈大大小小的人都在撸 ...
- c/c++ 标准库 vector
c/c++ 标准库 vector 标准库 vector的小例子 test1~test7 #include <iostream> #include <vector> using ...
- Scrapy(爬虫框架)中,Spider类中parse()方法的工作机制
parse(self,response):当请求url返回网页没有指定回调函数,默认的Request对象的回调函数,用来处理网页返回的response,和生成的Item或者Request对象 以下分析 ...
- jQuery -- 光阴似箭(四):jQuery 遍历
jQuery -- 知识点回顾篇(四):jQuery 遍历 通过 jQuery 遍历,您能够从被选(当前的)元素开始,轻松地在家族树中向上移动(祖先),向下移动(子孙),水平移动(同胞).这种移动被称 ...
- jQuery -- 光阴似箭(三):jQuery 操作 HTML 元素和属性
jQuery -- 知识点回顾篇(三):jQuery拥有操作 HTML 元素和属性的强大方法. 1. 获取HTML 元素的内容和属性 (1) 获得内容: text().html() 以及 val() ...
- TOPWAY智能彩色TFT液晶显示模块
TOPWAY 20年来专注工业显示, 以为全球工业用户提供稳定可靠和容易使用的液晶显示模块为己任, 智能彩色TFT液晶显示模块(以下简称智能模块), 就是我们在容易使用TFT 彩色液晶显示方向上为广大 ...