MFC笔记(三)

 

设备上下文和图形设备接口

Windows操作系统为用户提供了与具体设备无关的图形设备接口(GDI, Graphic  Device Interface),用它来管理图形操作,它利用驱动程序使显示器、打印机等输出设备与应用程序分离。在编程过程中,我们不必关心硬件的具体实现,可以直接进行抽象操作。

         设备上下文(DC, DeviceContext)是显示器、打印机等物理设备的逻辑模型,被称为设备描述表、设备环境或设备文本。设备上下文定义了绘图所需要的一套图形对象以及他们的属性,这些属性包括画笔、画刷、位图、调色板等。而真正的绘图函数在GDI中,包括画线、画椭圆、填充图形等。形象的讲,DC就是普通绘图所以需的一些物质条件,包括使用什么样的笔、什么样的纸等;而GDI则是画家的思想,利用DC中提供的物质条件进行作画:画线、画椭圆、填充图形等。

 

设备上下文类 CDC

在MFC中,设备上下文和图形设备接口被封装在一起,建立了CDC类。CDC是CObject的知己诶派生类,封装了windows API中的绝大部分GDI函数。

 

1、  数据成员:CDC类中包含两种类型的设备上下文,m_hDC和m_hAttribDC,创建CDC对象时它们指向相同的设备。CDC在执行所有与输出GDI有关的调用时使用m_hDC,执行大部分与属性GDI有关的调用时使用m_hAttribDC.

2、  构造与初始化函数

Attach()将windows的设备上下文与CDC对象联系在一起;

CreateCompatibleDC() 创建一个内存设备上下文与另一个设备上下文兼容,用户可以使用它在内存中准备图像;

CreateDC() 为一个特定的设备创建设备上下文;

Detach() 将CDC对象鱼windows设备上下文分离;

GetCurrentBitmap()  返回一个指向CBitmap对象的指针;

GetCurrentBrush()  返回一个指向选定CBrush对象的指针

SetAttribDC()  设置m_hAtttribDC

SetOutputDC()   设置m_hDC

 

3、  选择GDI绘图对象

CDC类提供了两个函数将对象选进设备上下文中:

(1)      SelectObject函数,常用于装入一些自定义的GDI对象。有许多模型:

CPen* SelectObject(CPen* pPen);

CBrush* SelectObject(CBrush* pBrush);

CBitmap* SelectObject(CBitmap*  pBitmap);

函数的参数为指向当前选定的画笔、画刷、图像等CGdiObject对象的指针,这些函数的返回值是指向被替换的CGdiObject对象的指针。

(2)      SelectStockObject函数,为使用方便,CDC类把一些经常用到的CGdiObject对象进行预定义并存储了起来,可以使用SelectStockObject将这些预定义的库存对象选进设备上下文。

Virtual  CGdiObject*SelectStockObject(int nIndex);

函数参数为nIndex, 取值和参数说明:

取值

说明

BLACK_BRUSH

黑色画刷

DKGRAY_BRUSH

深灰色画刷

GRAY_BRUSH

灰色画刷

ANSI_FIXED_FONT

ANSI修正系统字体

SYSTEM_FONT

系统字体

等等。。

4、  绘图函数

(1)      设置当前位置

在CDC类中,许多情况下画笔都是从当前位置开始绘图,使用成员函数GetCurrentPosition()来获得画笔当前位置,CPoint GetCurrentPosition() const;

使用MoveTo函数可以改变当前位置的坐标,则当前位置可以被设置到任何位置。CPoint  MoveTo(int x, inty);  CPoint MoveTo(POINT point);

(2)      画直线

BOOL  LineTo(intx,  int y);

BOOL  LineTo(POINTpoint);

这个函数使用当前画笔从当前位置绘制一条线到参数中制定的位置(x, y) 或point,并把终点设置成当前位置。如果在两个任意点之间画线,则必须先使用MoveTo函数将当前位置移动到其中一点,然后使用LineTo函数。

(3)      画矩形

BOOL Rectangle(int  x1,  int y1,   int  x2, int  y2);

BOOL Rectangle(LPRECT lpRect);

Rectangle函数绘制出的矩形角是方的,可以使用RoundRect来绘制圆角矩形;

BOOL  RoundRect(int  x1, int  y1,  int x2,  int  y2, int x3,  int y3);

BOOL  RoundRect(LPCRECTlpRect,  POINT point);

(4)      画弧

BOOL   Arc(int x1,int  y1, int x2,  int y2, int  x3, int y3, int x4,  int y4);

BOOL  Arc(LPRECTlpRect, POINT start,  POINT end);

其中参数x1, y1, x2, y2 或lpRect确定了弧线所在椭圆的外接矩形,(x3, y3)或start是弧线的起点,(x4, y4)或end是弧线的终点。

ArcTo函数也是CDC类提供的画弧函数,和Arc函数的不同之处在于ArcTo函数将当前位置移动至弧线的终点。

(5)      画椭圆/圆

BOOL Ellipse(int x1, int y1, int x2, int y2);

BOOL Ellipse(LPRECT lpRect);

使用外接矩形确定椭圆位置。

(6)      画多边形

BOOL   Polyline(LPPOINT  lpPoint, int nCount);

参数lpPoint是一个指向POINT结构或CPoint对象的数组的指针, nCount表示数组中元素的个数。该函数从数组中的第一个点画起,连接数组中其他点。它不使用也不更新当前点的位置。

Polygon()函数用于绘制多边形;BOOL Polygon(const POINT* lpPoint, const DWORD* lpPolyPoints,  int nCount);

和绘制折线的函数类似,但在最后连接成闭合图形。

(7)      设置背景

默认情况下,绘制图形或输出文本时,背景颜色为白色。CDC提供了SetBackColor()函数来设置新的背景颜色。

Virtual COLORREF SetBackColor(COLORREF  crColor);

若将背景色改为红色:SetBackColor(RGB(255,255,0));

         还有画弦、画饼形。

5、  文本处理函数

(1)      文本绘制

CDC类提供了DrawText函数在指定的矩形内绘制格式文本,函数原型如下:

                   Virtualint  DrawText(LPCTSTR  lpszString, int  nCount,  LPRECT lpRect,  UINT nFormat);

                   Int  DrawText(const CString& str,  LPRECT lpRect, UINT nFormat);

参数lpszString是一个指向被绘制的字符串的指针,如果nCount 为 -1,这个字符串必须是一个完整的字符串(以\0 结尾)。参数nCount指定了字符串中字符的个数。参数lpRect是一个指向包含文本所在矩形区域的RECT结构或CRect对象的指针。参数str是一个CString对象,包含即将被绘制的字符串,参数nFormat用于定制文本的格式。

         CDC还提供了功能更为强大的文本绘制函数DrawTextEx。

Virtual int DrawTextEx(LPTSTR lpszString, int nCount,  LPRECT  lpRect, UINT nFormat, LPDRAWTEXTPARAMS lpDTParams);

(2)      文本输出

Virtual  BOOLTextOut(int x, int  y,  LPCTSTR lpszString,  int  nCount);

BOOL TextOut(int  x, int  y, CString & str);

         参数(x, y)指定文本输出的起始位置;参数lpszString是一个指向即将输出文本的字符串的指针;参数nCount指定字符串中字符的个数;参数str是一个CString 对象,包含了即将输出的字符串。

         CDC还提供了更为强大的文本输出函数 TextOutEx()

(3)      设置文本属性

SetTextColor用于设置文本颜色。Virtual  COLORREF SetTextColor(COLORREF crColor);

SetBkColor设置文本的背景颜色,SetBkMode设置背景模式;SetTextAlign设置文本对齐标志。

 

6、  CDC的派生类

(1)      CClientDC类

一般情况下,窗口的客户区域并不包括边框、标题栏,因此如果创建了一个CClientDC对象,该设备上下文的映射区域也仅限于客户区域,即用户只能在客户区域内绘图。

CClientDC对象封装了一个只表示窗口客户区的设备上下文的处理。在CClientDC的构造函数中调用GetDC函数,在析构函数中调用ReleaseDC函数。

(2)      CMetaFileDC类

CMetaFileDC对象将绘制封装到Windows图元文件中,它允许用户为以后的重新绘制提供了一系列的绘图命令。

(3)      CPaintDC类

CPaintDC主要用于OnPaint函数中,如果重载OnPaint函数,就需要使用它。

CPaintDC类的构造函数自动调用BeginPaint函数,它的析构函数会自动调用EndPaint函数,因此,如果设备环境是在堆栈中创建,则会自动调用EndPaint函数。

(4)      CWindowDC类

和CClientDC类相似,但CWindowDC对象封装整个窗口(包括其框架)的设备上下文,因此可以在应用程序的整个窗口上画图。CWindowDC类的构造函数调用GetWindowDC函数,析构函数调用ReleaseDC函数。

 

7、  CGdiObject类及其派生类

由于windows提供了在设备上下文中使用的多种绘图工具,如画笔、画刷、字体、位图等,为此MFC提供了等效于windows绘图工具的图形对象类CGdiObject,它有多个派生类,分别对应于不同的GDI 对象。

通常创建CGdiObject的派生类的对象,构造方法可以使用两步构造,如:

CPen  mPen;

mPen.CreatePen(PS_DOT, 5, RGB(0, 0, 0));

在绘图操作需要GDI对象时,通常需要执行四个步骤的操作:

(1)      使用一步构造或两步构造方法初始化GDI对象

(2)      选择对象并将其放到当前的设备上下文中,使用SelectObject和SelectStockObject

(3)      处理完当前GDI对象后,选择旧GDI对象,将其放回设备上下文中以恢复其状态

(4)      允许框架分配的GDI对象在退出范围时被自动删除

需要注意的是,在退成程序前,必须将GDI对象从设备上下文中分离出来,将其删除。在Win32中,GDI对象占用进程的内存,虽然他在程序终止时会被自动释放,但一个没有被释放的GDI对象(例如位图对象)可能会占用很多内存。

 

8、  映射模式

WindowsGDI支持两套坐标系统:设备坐标系统和逻辑坐标系统。映射模式就是定义逻辑坐标的单位与设备坐标单位之间的关系。

设备坐标系统是物理设备上的坐标系统,设备坐标的基本单位是像素。设备坐标的原点始终在左上角,向右移动,横坐标增加;向下移动,纵坐标增加。不同的设备分辨率不同,在转换时需要注意。

在使用CDC类提供的绘图函数时,都是在逻辑坐标系中进行绘制,只有按照需要,适当的映射到设备坐标系中,才能够在显示器等输出设备上正确显示。

           相对于设备坐标系统,逻辑坐标系统更加复杂同时更加灵活。在默认的映射模式下,逻辑坐标也以像素为单位,向右移动时横坐标增加,向下移动时纵坐标增加,并且初始时坐标原点在左上角。

           Windows包含八种不同的映射模式,可以使用CDC类的SetMapMode函数设置当前的映射模式,函数模型为:

         Virtual  int SetMapMode(int  nMapMode)

   八种映射模式:

(1)      MM_TEXT模式

默认的映射模式,设备坐标系统和默认的逻辑坐标系统都采用MM_TEXT模式,它的坐标被映射成像素。X轴正方向向右,Y轴正方向向下,初始时坐标原点在左上角。但可以使用CDC类的SetViewportOrg和SetWindowOrg函数来改变坐标原点的位置,函数原型:

CPoint SetWindowOrg(int x, int y)

CPoint SetWindowOrg(POINT point)

Virtual  CPointSetViewportOrg(int x, int y)

Virtual  CPoint  SetViewportOrg(POINT point)

(2)      约束映射模式

Windows的映射模式中有六种都是约束映射模式,其中MM_TEXT也是约束映射模式的一种。他们的共同点是横纵轴单位的比例是固定的,应用程序无法改变映射到设备单位的逻辑单位数目。在这六种模式下,一个逻辑坐标单位对应的大小如下:

 

 

约束映射模式

逻辑坐标的大小

MM_HIENGLISH

0.001英寸

MM_HIMETRIC

0.01毫米

MM_LOENGLISH

0.01英寸

MM_LOMETRIC

1毫米

MM_TEXT

1个设备单位

MM_TWIPS

1/1440英寸,常用于打印机

上述六种约束模式中,除MM_TEXT外,其他五种映射模式的X轴正方向向右,Y轴正方向向下,其余都相反。

(3)      非约束映射模式

Windows提供两种映射模式:MM_ISOTROPIC和MM_ANISOTROPIC,允许改变横纵轴单位的比例。它使用两个矩形区域(窗口和视口)推导出横纵轴的比例和坐标方向。窗口使用的是逻辑坐标,视口使用设备坐标,原点可以是矩形区域的任意一个角。,

 

 

 

创建文档、窗口和视图

MFC 文档视图结构中各个类的关系:

文档保留该文档的视图列表以及指向创建该文档的文档模板的指针;视图保留指向其文档的指针,视图窗口是文档框架窗口的子窗口;文档框架窗口中保留指向当前活动视图的指针;文档模板保留期已打开文档的列表;windows跟踪所有打开的窗口,以便可以向这些窗口发送消息。所有这些关系都是在文档/视图结构的创建期间建立的,通过调用全局函数AfxGetApp,任何对象均可以获得指向应用程序对象的指针。

MFC各对象之间的访问

对象

访问其他对对象的方法

文档

使用GetFirstViewPosition和GetNextView访问文档的视图列表,调用GetDocTemplate获取文档模板

视图

调用GetDocument获取文档,调用GetParentFrame获取框架窗口

文档框架窗口

调用GetActiveView获得当前视图,调用GetActiveDocument获取当前视图的文档

MDI框架窗口

调用MDIGetActive获得当前活动的CMDIChildWnd

 

 

CArchive类与序列化

序列化是指将对象写入永久性存储媒体(如磁盘文件)或从其中读取对象的过程。MFC将CArchive对象作为被序列化对象和存储媒体之间的中间物,它时钟与CFile对象相关联,它从CFile对象中获得序列化所需的信息,包括文件名以及执行的是读取还是写入操作。

         在使用CArchive对象之前,必须先创建一个CFile对象。同时保证CArchive对象与文件打开方式一致。对于一个CArchive对象,既可以进行存储操作也可以进行读取操作,但二者无法同时进行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值