网上第一本以TXT格式的VC++深入详解孙鑫的书.全文全以TXT格式,并每一章节都分了目录,清晰易读
源代码在线查看: 04.2.3 利用mfc的cclientdc类实现画线功能.txt
4.2.3 利用 MFC的 CClientDC类实现画线功能
下面再介绍一种画线的实现方法,这里将利用 MFC提供的 CClientDC类来实现这一功能。这个类派生于 CDC类,并且在构造时调用 GetDC函数,在析构时调用 ReleaseDC
函数。也就是说,当一个 CClientDC对象在构造时,它在内部会调用 GetDC函数,获得一个设备描述表对象:在这个 CClientDC对象析构时,会自动释放这个设备描述表资源。这样的话,程序中如果使用 CClientDC类型定义 DC对象,就不需要显式地调用 GetDC函数和 ReleaseDC函数了。只需要定义一个 CClientDC对象,然后就可以利用该对象提供的函数进行绘图操作了。当该对象的生命周期结束时,会自动释放其所占用的设备资源。这就是 CClientDC对象的好处。例 4-11所示就是利用 CClientDC类实现画线功能的代码。
例 4.11
肌
灿
void CDrawView: : OnLButtonUp(U工 NT nFlags , CPoint point)
CClientDC dc(this} ;
dc .MoveTo(m-ptOrigin} ;
dc.LineTo(point} ;
. Cview: :OnLButtonUp(nFlags , point} ;
在例 4-11所示的代码中,在构造 CClientDC对象时,需要一个 CWnd类型的指针作为参数。如果这时我们想在视类窗口中绘图,就应该传递 CDrawView对象的指针。在前面讲述 C++知识时,曾经介绍过,每个对象都有一个 this指针指向自己本身。因为本例想要构造一个与视类窗口有关的 CClientDC对象,所以就把代表视类对象的 this指针作为参数传递给该对象的构造函数。
国际:这里的 CClientDC类型的性 (dc)是一个对象,因此使用点操作
符(.)来调用该对象的函数。
我们可以注意到,利用 CClientDC类绘图时,因为该对象在析构时会自动调用 ReleaseDC函数释放设备资源,所以不需要程序员再去调用这个函数了。
Build并运行 Draw程序,拖动鼠标同样可以在窗口中绘制线条。
以上几种实现方式都可以实现在程序窗口的客户区绘制线条,但是我们发现它们都不能在工具栏和菜单栏上画线。另外,例 4-11代码构造了一个与视类相关的 CClientDC对象,那么如何构造一个与视窗口的父窗口相关的 CClientDC对象呢?视窗口的父窗口就是框架窗口,即与 CMainFrame类相关联的窗口。前面的内容已经讲述过,在编写程序时,如果不知道某个函数的具体名称,可以根据函数的功能来猜测其名称。例如,这里想要获得父窗口的指针,那么我们可以猜测其函数名是不是" Get"加上 "Parent",于是以此名称在 MSDN中查找,发现确实存在一个这样的函数,仔细阅读该函数的帮助信息,发现
"‘ I 117
第4
它就是我们所需要的那个函数。读者在实际编程时,可以试试这种猜测方法,相信会大有帮助的。现在,将例 4-11所示代码中构造 CClientDC对象的代码替换为下面这行代码。
CClientDC dc(GetParent());
Build并运行 Draw程序,拖动鼠标在窗口中绘制线条,发现此时线条可以画到程序的工具栏上,如图 4.12所示。
·二~~标题。r r. l'.'J汾..
图 4 .1 2利用 CClientDC实现在框架窗口的客户区画线
前面第 3章中已经讲述过视类窗口和框架窗口的位置关系,图 4.12所示的程序界面中,整个程序窗口就是框架窗口,而工具栏以下白色区域部分才是视类窗口。视类窗口只有客户区(即视类窗口本身),而框架窗口既有客户区(即菜单栏以下部分),还有非客户区(就是程序运行界面中的标题栏和菜单栏〉。而绘图操作一般都是在窗口的客户区进行的。因此,对上述例 4-11所示代码来说,因为其构造的设备描述表与视类窗口相关,所以程序只能在视窗口的客户区中画线。而如果构造的设备描述表与框架窗口相关,那么就可以在工具栏上绘制图形了,因为工具栏属于框架窗口的客户区。
CI! 提示:工具栏是浮动的,可以利用鼠标把她动到程序窗口的任意位置处。