1、坐标空间和转换
Win32 API使用四种坐标空间:世界坐标系空间、页面空间、设备空间、物理设备空间。
世界坐标系空间、页面空间统称逻辑空间。
如果程序调用了SetWorldTransform函数,那么输出映射就从世界坐标系空间开始,否则,从页面空间开始。通常,主要处理的是从页面空间到设备空间的转换。设备空间到物理设备空间的转换由系统控制,一般不用考虑。
映射方式主要是确定应该如何将页面空间的一个坐标点转换为设备空间的一个设备坐标点。
页面空间到设备空间的转换所用的是两个矩形的宽和高的比率(转换因子),页面空间中的矩形称为“窗口”,设备空间中的矩形称为“视口”;Windows把“窗口原点”映射到“视口原点”,把“窗口范围”映射到“视口范围”,就完成了转换。
窗口坐标是基于逻辑坐标的,可以是像素、毫米、英寸等,视口坐标是基于设备坐标的,即像素。
GDI函数运用默认页面空间到设备空间的转换:页面空间上给出的一个点映射到设备空间的一个点,即一对一映射。
几乎所有的GDI函数使用的坐标值都是逻辑坐标,例如dc->TextOut(0, 100, "text");中的(0, 100)就是逻辑坐标,程序执行后,在窗口中真正显示文本时,该坐标值需要被转换为设备单位,而且转换结果由映射方式、窗口和视口的原点、窗口和视口的范围控制。
Windows对所有的消息、所有的的非GDI函数和一些GDI函数使用设备坐标。
Windows默认的映射方式为MM_TEXT,在此映射模式下逻辑单位和设备单位相同,逻辑坐标(0,100)转换为设备坐标后仍未(0,100)。映射模式可以通过SetMapMode()来改变。
视口坐标 = (窗口坐标-窗口原点坐标)*视口范围/窗口范围+视口原点坐标
窗口坐标 = (视口坐标-视口原点坐标)*窗口范围/视口范围+窗口原点坐标
因为在MM_TEXT映射方式下,逻辑单位和设备单位是一样的,而且窗口范围和视口范围都是1×1的,所以有:
视口坐标 = (窗口坐标-窗口原点坐标)+视口原点坐标
窗口坐标 = (视口坐标-视口原点坐标)+窗口原点坐标
通过消息,例如鼠标左键单击消息得到的坐标点是以设备坐标为单位的,即以像素为单位的值,因为默认映射方式是MM_TEXT,所以逻辑单位和设备单位是一样的,因此,在前面的章节程序中我们没有显示的进行坐标转换,还是直接使用得到的设备坐标调用GDI函数进行绘图操作。
CDC提供了两个函数SetViewportOrg()和SetWindowOrg()来改变视口和窗口的原点。如果将视口原点设置为(10,10),则逻辑点(0,0)就会被映射为设备点(10,10);如果将窗口原点设为(10,10),则逻辑点(10,10)会被映射为设备点(0,0)。
注意:不管对窗口和视口的原点如何改变,设备点(0,0)始终是客户区的左上角。
2、集合类CPtrArray
CStringArray可以用来存储CString类型的对象,其容量可以动态增加。
CObArray可以用来存储CObject类及其派生类的对象,其容量可以动态增加。
CPtrArray可以用来存储void*类型的指针,其容量可以动态增加。
3、OnDraw和OnPaint
在基于单文档的MFC程序中,图形的绘制可以在OnDraw函数中进行,因为在CView类的OnPaint函数中会调用OnDraw函数,可是如果我们添加了视类CXXXView的WM_PAINT消息响应函数后,程序就不会调用父类CView的OnPaint函数,故也不会再调用OnDraw函数。
4、元文件和兼容设备描述表
保存图形和重绘图形的另外两种方法:使用元文件和兼容设备描述表(兼容DC)。
元文件设备上下文类:CMetaFileDC。一个元文件DC包含了一系列图形绘制的命令,在程序中可以重放这些命令,以便创建所需的图形或文本。还可以把保存图形绘制命令的元文件保存为磁盘文件,以便在以后需要时可以随时打开该文件。
兼容DC前面已经讲过,主要是利用兼容DC在内存中准备一幅图像,然后将该图像复制到目的窗口中。在这里也可以利用兼容DC来保存图形,然后在OnDraw函数中将兼容DC保存的图形复制到目的窗口中。