《VC++深入详解》第四章 简单绘图
来源:互联网 发布:高中生心理健康数据 编辑:程序博客网 时间:2024/04/29 19:28
这一章延续上对MFC框架的介绍,以一个画图例子程序讲解如下知识点:
1、ClassWizard的使用
2、MFC消息响应机制
3、设备描述表DC的一些封装以及常见绘图API
在本章例子中,我们先后尝试在框架窗口和视类窗口中响应鼠标左键按下消息,实际发现仅后者中能予以响应,这是因为视类窗口始终覆盖在框架窗口之上。
为一个窗口增加消息响应可以通过MFC Wizard来,也可以自行添加代码,主要修改有两个方面:
1、消息响应函数的声明和定义
2、将消息映射加入消息映射表,其实就是通过宏(ON_COMMAND、ON_WM_LBUTTONDOWN等)来完成。消息映射表是类的静态成员,它存放该类对于消息的响应情况。MFC在类的定义中使用宏DECLARE_MESSAGE_MAP来定义该static成员,只是宏的方式让这一切变得神秘起来。
#define DECLARE_MESSAGE_MAP() \private: \ static const AFX_MSGMAP_ENTRY _messageEntries[]; \
protected: \
<span style="white-space:pre"></span> static AFX_DATA const AFX_MSGMAP messageMap;
下面引用一个来自《深入浅出MFC》中的插图,更易说明情况。
这里我们先来看看MFC里消息的分类,然后看看各类消息的路由区别。
1、命令消息WM_COMMAND 来自菜单、快捷键、工具栏按钮的消息。它们均以WM_COMMAND的方式呈现,那我们如何区分呢?在SDK程序里,主要依靠WParam参数,在MFC里依靠识别码来区分。
2、除了WM_COMMAND外其他的WM开头的消息都称为标准消息
3、Notification控件通知消息,为的是通知控件的父窗口。
对于标准消息,它的路由很简单,即从子类到父类。比如若CMyView未响应某个标准消息,则交由CView响应,后者若未响应则交给CWnd。
对于命令消息,它的路由情况复杂一些,依旧引用《深入浅出MFC》中的例图(经典书籍,本人水平太次,粗读一遍仍未领会贯通)
框架窗口在收到命令消息WM_COMMAND后,先给自己的View视类窗口一个机会,视类窗口若处理了该消息,则消息路由结束,如上图线路1所示。若未处理,则交给Document文档类处理,后者若未处理,则框架窗口就自己尝试处理,不成的话交给应用程序类(只要集成于CCmdTarget都可以处理命令消息),都不成的话交由DefWindowProc走默认的处理流程。
对于控件通知消息,一般都由父类窗口予以响应。
第一章中,我们使用HDC句柄实现了图形的绘制,当时调用的方式是
HDC hdc = GetDc(hWnd)
TextOut(hdc, 0, 0, "XXX", strlen("XXX"))
ReleaseDc(hWnd, hdc)
本章我们学习了几个更上层的封装DC类,比如CClientDC CWindowDC, 前者对HDC进行简单封装将GetDc 和 ReleaseDc放入构造与析构之中。
后者功能更强大,可以在非客户区甚至桌面进行绘图,只要给予其相应的窗口句柄即可。这里学习一个API:GetDesktopWindow
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point) {//<span style="white-space:pre"></span>CClientDC dc(this);//CClientDC dc(GetParent());CWindowDC dc(GetDesktopWindow());//CWindowDC dc(GetParent());dc.MoveTo(m_ptOrigin);dc.LineTo(point);
}
通过DC句柄的成员函数SelectObject可以把GDI对象选入设备描述表中,实现对默认对象的更改,注意的是在绘图完成后,我们一般将更改之前的设备描述表予以恢复,不能只图自己方便。
红笔:
CPen pen(PS_DOT,1,RGB(255,0,0));CClientDC dc(this);CPen* pOldPen = dc.SelectObject(&pen);dc.MoveTo(m_ptOrigin);dc.LineTo(point);dc.SelectObject(pOldPen);
画刷:
有的GDI绘图函数提供了画刷接口,不需要我们选入设备描述表,比如:
CBrush brush(RGB(255,0,0));//创建并获得设备描述表CClientDC dc(this);//利用红色画刷填充鼠标拖曳过程中形成的矩形区域dc.FillRect(CRect(m_ptOrigin,point),&brush);有的则没有提供接口,我们只能通过选入的方式来得到自己想要的设备特性,比如:
//创建并获得设备描述表CClientDC dc(this);//创建一个空画刷CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//将空画刷选入设备描述表CBrush *pOldBrush = dc.SelectObject(pBrush);//绘制一个矩形dc.Rectangle(CRect(m_ptOrigin,point));//恢复先前的画刷dc.SelectObject(pOldBrush);
注意到上面的API:GetStockObject,在第一章设计窗口类时,曾经使用它获得一个黑色的画刷句柄。这里NULL_BRUSH将是一个透明的画刷句柄。
由于SelectObject需要的是画刷指针,我们使用FromHandle来从句柄获得指针。
通过本章的学习,进一步加深了MFC消息机制的理解,基本绘图方法的掌握。
- 《VC++深入详解》第四章 简单绘图
- 孙鑫《vc ++深入详解》第四章简单绘图
- VC++深入详解第四章——简单绘图
- 《VC++深入详解》学习笔记 第四章 简单绘图
- VC++深入详解 第4章 简单绘图
- VC++深入详解笔记——4.简单绘图
- 孙鑫VC++深入详解(3):简单绘图
- VC++深入详解-第四章学习心得
- 《VC++深入详解》学习笔记[3]——第4章 简单绘图
- 第四章、简单绘图
- 第四章,简单绘图
- 第四章-简单绘图
- vc学习笔记之简单绘图(第四章)
- 孙鑫《vc ++深入详解》第十章绘图控制
- 《VC++深入详解》学习笔记 第十章 绘图控制
- VC++深入详解笔记——10. 绘图控制
- 孙鑫VC++深入详解(9):绘图控制
- [连载]vc++深入详解(孙鑫)视频笔记-第四课
- 关于Qt控制台程序
- stdafx 头中的STRICT定义说明
- iOS UITableView NSIndexPath属性讲解
- hdu 1050 Moving Tables(暴力)
- 利用SAE搭建微信公众平台(一)
- 《VC++深入详解》第四章 简单绘图
- 黑马程序员---ARC
- iOS 文件操作
- 菜鸟程序员的博客开始更新了以及声明
- 算法笔记八:基数排序
- 传统线程同步通信技术(三)
- ubuntu下Java JDK 和eclipse的安装
- Spring MVC 绑定参数
- mysql导出数据库几种方法