VC学习笔记:简单绘图
VC学习笔记:简单绘图
SkySeraph Oct.29th 2009 HQU
Email-zgzhaobo@gmail.com QQ-452728574
Latest Modified Date:Oct.31th 2010 HQU 重新整理
//说明:学习《孙鑫视频》第四课 笔记 2009.10.29HQU
绘线及相关
建立单文档工程,为View类(不能是MainFrame)添加消息函数OnLButtonDown、OnLButtonUp
①先增加成员变量m_ptOrigin,CPoint型,用来保存坐标原点,在View构造函数里把其赋值为0,在OnLButtonDown里m_pOrigin=point
②
CMyView::OnLButtonUp(UINT nFlags,CPoint point)
{
//法一:利用SDK全局函数/API函数 在View类OnLButtonUp中
HDC hdc;//获取设备描述表
hdc=::GetDC(m_hWnd);
//利用全局函数而不是CWnd成员函数;m_hWnd是view窗口句柄,在CWnd派生出来的类中,都有一个数据成员保存了窗口句柄,
//CDC类也有同样的功能 m_hWnd是一个保护的变量,是用来构造m_hWnd对象的CWnd指针的HWND。
MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);//移动线条起点
LineTo(hdc,point.x,point.y);//画线
::ReleaseDC(m_hWnd,hdc);//配对使用;在WM_PAINT中不能用
//法二:利用CDC类 此类提供了一个数据成员m_hDC用来保存于CDC类相关的句柄,类似于m_hWnd
CDC *pDC=GetDC();//定义CDC类指针
pDC->MoveTo(m_ptOrigin);
pDC->LineTo(point);
ReleaseDC(pDC);
//法三:利用CClientDC ,创建的是视图窗口的DC对象,作图只能在视图的客服区内作图
CClientDC dc(GetParent()); //=CClientDC dc(this); //结束时会自释放DC
//CClientDC构造函数CClientDC( CWnd* pWnd );中得知需要一个指针
//类CClientDC派生于CDC,在构造时调用了Windows函数GetDC,在析构时调用了ReleaseDC。这意味着和CClientDC对象相关的设备上下文是窗口的客户区。
dc.MoveTo(m_ptOrigin); //CClientDC类型的变量dc是一个对象,采用点操作符来调用该对象的函数
dc.LineTo(point);
//法四:利用CWindowDC //通过选择窗口对象的指针,可以创建各种窗口的DC甚至是整个屏幕窗口的DC对象,作图也只能在窗口的客服区内作图
CWindowDC dc(GetDesktopWindow());//整个屏幕
//CWindowDC dc(GetParent());//=CWindowDC dc(this); //视图客户区内作图,结束时会自释放DC
//CWindowDC类是从CDC继承的。它在构造的时候调用Windows函数GetWindowDC,在销毁的时候调用ReleaseDC。
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
//绘制彩色线条 使用画笔 可以选择/改变颜色,粗细,宽度等属性
CPen pen(PS_DOT,1,RGB(0,255,0));
CClientDC dc(this);
CPen *pOldPen=dc.SelectObject(&pen);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
dc.SelectObject(pOldPen);
CView::OnLButtonUp(nFlags,point);
}
画刷
法一 简单画刷
CBrush brush(RGB(255,0,0));
CClientDC dc(this);
dc.FillRect(CRect(m_ptOrigin,point),&brush);
//注:此处只是用指定的画刷填充一块区域,因此并不需要把话刷选入设备描述表中。设备描述表中存在一个默认的白色的画刷
法二bitmap填充/位图画刷
CBrush brush(RGB(255,0,0));
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
CBrush brush(&bitmap);
法三:透明画刷
CClientDC dc(this);
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); // CBrush::FromHandle是静态成员函数
//FromHandle给出一个Windows HBRUSH对象句柄时,返回一个指向CBrush对象的指针。即将画刷的句柄转换为对象的指针。
CBrush *pOldBrush=dc.SelectObject(pBrush);
dc.Rectangle(CRect(m_ptOrigin,point));
dc.SelectObject(pOldBrush);
静态成员 原理说明 实例
- 例子1.0
#include "iostream"
class Point
{
public:
void output() {}
static void init() {} //静态函数,不属于某个具体的对象,即在未产生Point任何对象时,这个类已经存在于程序的代码区
}
void main()
{
/*法一
Point pt; //构造对象
pt.init();
pt.output();
*/
//法二
Point::init();/
Point::output();//错误
}
说明:法一正确;法二执行错误,原因:
//静态成员函数和静态成员变量属于类本身,在类加载的时候,即为它们分配了空间,故可以用类名::函数名或类名:变量名来访问;
//而非静态成员函数和非静态成员属于对象的方法和数据,也就是应该先产生类的对象,然后通过类的对象去引用。
- 修改1.1:
class Point
{
public:
void output() {}
static void init() {x=0;y=0;}
private:
int x,y;
}
void main()
{ Point::init();//错误:在静态成员函数中不能调用非静态成员
}
说明:在静态成员函数中不能调用非静态成员(静态成员函数和静态成员变量);反之在非静态成员函数中可以调用静态成员,可以在修改void output(){ init(); };检验
内存模型:无论采取什么样的操作,程序代码都是在内存中执行的,只有在内存中占有一席之地,我们才能访问它。
- 修改1.2
在int x,y;前加static,编译无错,链接时出错
说明:对于静态成员变量,必须对其进行初始化,且必须在类外进行此操作
加上:int Point::x=0;int Point::y=0; OK!
任意画线,画扇形
①先增加消息处理函数OnMouseMove。
②再设定一个bool型变量(当鼠标左键按下为true,弹起为false):在View构造函数里m_bDraw=0,在OnLButtonDown里m_bDraw=TRUE&在OnLButtonUp里m_bDraw=FALSE
③任意画连续的线
CClientDC dc(this); if(m_bDraw==TRUE)
{ dc.MoveTo(m_ptOrigin); dc.LineTo(point); m_ptOld=point; }
④增加颜色的连续的线
CPen pen(PS_SOLID,1,RGB(255,0,0));
CPen *pOldPen=dc.SelectObject(&pen); {……}
dc.SelectObject(pOldPen);
⑤画扇形
先增加一个CPoint型成员变量m_ptOld,在左键按下的时候赋其值给m_ptOld
…{dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptOld);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
m_ptOld=point; }…
⑥带边线的扇形:只需要把第三句dc.MoveTo(m_ptOrigin);改为dc.MoveTo(m_ptOld);既可。
⑦设置绘图模式的函数:dc.SetROP2(R2_BLACK);
补充 知识点
- CWnd类定义了一个HWND类型的成员变量m_hWnd用于保存当前窗口的句柄,且该句柄具有public类型访问权限。由继承性原理,CWnd子类都拥有这一成员变量。
- 在单文档中view挡在MainFrame的前面。此时如果编写针对MainFrame的mouseClick事件,将不会有反应。
在框架类当中收不到鼠标左键点击的消息原因:View类始终是覆盖在Frame类中上的。也就是说,所有操作,包括鼠标移动,鼠标单击等都只能由视图类来完成。
CDC、HDC、pDC区别
① CDC *pDC 和 HDC hdc有什么不同, 类似的有CWnd *pWnd和HWnd?
pDC是类指针,HDC是windows句柄
通过pDC获得hdc: HDC hdc=pDC->GetSafeHdc();
通过hdc获得pDC: CDC *pDC=new CDC; pDC->Attach(hdc);
②hDC和CDC有本质区别
HDC是WINDOWS的一种数据类型,是设备描述句柄。而CDC是MFC里的一个类,它封装了几乎所有的关于HDC的操作。
也可以这样说,HDC定义的变量指向一块内存,这内存用来描述一个设备的相关的内容,所以也可以认为HDC定义的是一个指针;
而CDC类定义一个对象,这个对象拥有HDC定义的一个设备描述表,同时也包含与HDC相关的操作的函数。这与HPEN和CPen,POINT与CPoint之间的差别是一样的。
CDC是对hDC的相关操作进行封装,例如CDC的一个TextOut函数隐去其错误检测,完全可以简化到这样程度CDC:TextOut( int x, int y, const CString& str )
{
TextOut( m_hDC, x, y, (LPCTSTR)str, str.GetLength() );
}
m_hDC就是CDC的成员变量HDC m_hDC;
CDC有一个operator HDC() const { return m_hDC; }
你可以把它当成一个HDC使用
③ this是dc输出目标窗口的指针,通过它可以得到窗口句柄,对象带参构造这有什么奇怪的呢?
CPaintDC 无效区dc,相当于BeginPaint, EndPaint
CClientDC 客户区dc,相当于GetDC, ReleaseDC
CWindowDC 整窗口dc, 相当于GetWindowDC, ReleaseDC
CDC 任何dc, 相当于CreateDC, DeleteDC
④
HDC就是最原始的 DC 句柄,很多API的第一个参数就是一个HDC类型,比如
HDC hDC = ::GetDC( m_hWnd);
::MoveToEx( hDC, 0,0, NULL );
::LineTo( hDC, 0, 100, );
::ReleaseDC( m_hWnd, hDC );
在MFC中,为了将API封装成一个类来操作,因此多出来了一个CDC。所以在MFC中,都是
CDC dc = GetDC();
dc.MoveTo( 0,0 );
dc.LineTo( 0,100 );
this->ReleaseDC( &dc );
但这样还不够,因为 CDC还要你自己去释放,所有MFC中又多出来一个CClientDC, 这样你就可以这样了:
CClientDC dc(this);
dc.MoveTo( 0,0 );
dc.LineTo( 0,100 );
CClientDC的析构函数自己会释放自己。
DC不是什么对象,就是设备上下文的简称。与CClientDC一样,还有CWindowDC,CPaintDC,只是它们的绘制范围不一样。
但弄到底,都只是HDC的一些封装而已,你可以在CDC类中直接引用 m_hDC,这就是那个原始的HDC句柄了。
Author: SKySeraph
Email/GTalk: zgzhaobo@gmail.com QQ:452728574
From: http://www.cnblogs.com/skyseraph/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,请尊重作者的劳动成果。
转载于:https://www.cnblogs.com/skyseraph/archive/2010/10/31/1865748.html
VC学习笔记:简单绘图相关推荐
- VC学习笔记:文本图形
VC学习笔记:文本图形 SkySeraph OCT.30th 2010 HQU Email-zgzhaobo@gmail.com QQ-452728574 Latest Modified Dat ...
- Python基础知识学习笔记——Matplotlib绘图
Python基础知识学习笔记--Matplotlib绘图 整理python笔记,以防忘记 文章目录 Python基础知识学习笔记--Matplotlib绘图 一.绘图和可视化 1.导入模块 2.一个简 ...
- VC学习笔记 -单选按钮控件(Ridio Button)的使用
在VC++编程过程中,查资料是一个苦差事,案边放了一摞书左翻右翻好是烦人.一赌气就把一些常用的小技巧自己总结了一下,虽费了些功夫,但对以后编程很有好处.现拿出来与大家共享,以后积累多了,作一个CHM电 ...
- RxJava学习笔记---简单使用
如果觉得一篇文章写得好,不要放到收藏夹里面,马上把它看完,如果两天内还没开始看,那就可以删掉了 如果觉得一样技术很好,那就马上去学,不要拖延,不要找借口.如果你一周内还没开始行动,还不如坦荡点放弃 恰 ...
- 孙鑫VC学习笔记:第七讲
七.对话框 2006年8月5日 14:25 因为笔记是用OneNote做的,上传以后为看不到图片,于是我截图放到相册上面, 相册地址为:http://photo.163.com/photos/good ...
- VC学习笔记---ATL MFC CLR三个库的区别
MFC.ATL和CLR是VC2005内置的三大库,涵盖了Windows的各种开发方法和开发应用.当然关于C++开发的库不止这三个,不过这三个是微软推荐. 从编程所处层次而言,WIN32为最底层,其次是 ...
- Python学习笔记简单数据类型之字符串
1.字符串: (1).字符串就是一系列字符,串起来形成的一种简单数据类型.在Python中,用引号括起来的都是字符串,包括单引号,双引号,其中字符串可以灵活的运用起来,字符串中可以包括引号和撇号,示例 ...
- 孙鑫VC++学习笔记(转载至程序员之家--虎非龙)[11--15] .
第11课 1.创建4个菜单,为其添加消息响应,用成员变量保存绘画类型.添加LButtonDown和Up消息. 2.当窗口重绘时,如果想再显示原先画的数据,则需要保存数据.为此创建一个新类来记录绘画类型 ...
- 孙鑫VC++学习笔记(转载至程序员之家--虎非龙)[11--15]
第11课 1.创建4个菜单,为其添加消息响应,用成员变量保存绘画类型.添加LButtonDown和Up消息. 2.当窗口重绘时,如果想再显示原先画的数据,则需要保存数据.为此创建一个新类来记录绘画类型 ...
最新文章
- 在文本框中提示用户输入内容格式的方法
- 欢迎使用markdown编辑器20181206
- 缓存核心知识小抄,面试必备,赶紧收藏!
- Spring mvc HandlerMapping 实现机制
- c语言修改windows系统时间,c语言实现系统时间校正工具代码分享
- css设置a连接禁用样式_使用CSS禁用链接
- linux中的memory management和page mapping
- 前端学习(2462):打包优化
- MathType 换行后无法对齐,怎么都对不齐!!!强迫症晚期(见图)
- 事后分析报告(M2阶段)
- Android自动打包、签名、优化、上传ANT脚本
- ASS 字幕格式规范
- centos8安装和启动中文智能拼音
- 如何在拍照时摆POSS
- eclipse 设置全部的背景颜色
- 一起来学习Java浮点类型
- socketTCP协程文件+信息传递 - TCP聊天文件服务器v1.9 - 划时代的版本更新(4.6万字)
- 应用程序无法正常启动0xc000007b的解决方法(PhotoScan为例)
- 双色球的篮球购买保本的买法计算!
- kingcms php 漏洞,kingcms任意php文件删除(可截断时升级为任意文件删除 )
热门文章
- Symfony1.4.11学习笔记(四):数据模型
- [蛋蛋无厘头日记]约会ing~~
- python安装jupyterlab_【python】jupyter lab安装与配置
- Dubbo场景场景配置用法详解
- 预览ExtJS 4.0的新功能(四):焕然一新的Store/Proxy
- matlab程序 surf算法,【求大神帮忙,surf算法源代码解析】
- linux下java基于UDP编程聊天_基于Linux下的UDP编程
- python pip下载本地依赖包,并在离线环境中安装,并解决报错ERROR: Could not find a version that satisfies the requirement报错
- Flink java wordcount案例(批处理、流处理)
- linux查看后台执行的所有任务与对应的命令