状态条CStatusBar
其他各类控制窗口,如列表框CList,编辑框CEdit,组合框CComboBox,按钮Cbutton等。
通常,直接使用这些类。
在MFC下窗口的销毁
窗口对象使用完毕,应该销毁。在MFC下,一个窗口对象的销毁包括HWND窗口对象的销毁和MFC窗口对象的销毁。一般情况下,MFC编程框架自动地处理了这些。
(1)对CFrameWnd和CView的派生类
这些窗口的关闭导致销毁窗口的函数DestroyWindow被调用。销毁Windows窗口时,MFC框架调用的最后一个成员函数是OnNcDestroy函数,该函数负责Windows清理工作,并在最后调用虚拟成员函数PostNcDestroy。CFrameWnd和CView的PostNcDestroy调用delete this删除自身这个MFC窗口对象。
所以,对这些窗口,如前所述,应在堆(Heap)中分配,而且,不要对这些对象使用delete操作。
(2)对Windows Control窗口
在它们的析构函数中,将调用DestroyWidnow来销毁窗口。如果在栈中分配这样的窗口对象,则在超出作用范围的时候,随着析构函数的调用,MFC窗口对象和它的Windows window对象都被销毁。如果在堆(Heap)中分配,则显式调用delete操作符,导致析构函数的调用和窗口的销毁。
所以,这种类型的窗口应尽可能在栈中分配,避免用额外的代码来销毁窗口。如前所述的CMainFrame的成员变量m_wndStatusBar和m_wndToolBar就是这样的例子。
(3)对于程序员直接从CWnd派生的窗口
程序员可以在派生类中实现上述两种机制之一,然后,在相应的规范下使用。
后面章节将详细的讨论应用程序退出时关闭、清理窗口的过程。
设备描述表
设备描述表概述
当一个应用程序使用GDI函数时,必须先装入特定的设备驱动程序,然后为绘制窗口准备设备描述表,比如指定线的宽度和颜色、刷子的样式和颜色、字体、剪裁区域等等。不像其他Win32结构,设备描述表不能被直接访问,只能通过系列Win32函数来间接地操作。
如同Windows“窗口类”一样,设备描述表也是一种Windows数据结构,用来描述绘制窗口所需要的信息。它定义了一个坐标映射模式、一组GDI图形对象及其属性。这些GDI对象包括用于画线的笔,绘图、填图的刷子,位图,调色板,剪裁区域,及路径(Path)。
表2-2列出了设备描述表的结构和各项缺省值,表2-3列出了设备描述表的类型,表2-4显示设备描述表的类型。
表2-2 设备描述表的结构
属性缺省值
Background colorBackground color setting from Windows Control Panel (typically, white)
Background modeOPAQUE
BitmapNone
BrushWHITE_BRUSH
Brush origin(0,0)
Clipping regionEntire window or client area with the update region clipped, as appropriate. Child and pop-up windows in the client area may also be clipped
PaletteDEFAULT_PALETTE
Current pen position(0,0)
Device originUpper left corner of the window or the client area
Drawing modeR2_COPYPEN
FontSYSTEM_FONT (SYSTEM_FIXED_FONT for applications written to run with Windows versions 3.0 and earlier)
Intercharacter spacing0
Mapping modeMM_TEXT
PenBLACK_PEN
Polygon-fill modeALTERNATE
Stretch modeBLACKONWHITE
Text colorText color setting from Control Panel (typically, black)
Viewport extent(1,1)
Viewport origin(0,0)
Window extent(1,1)
Window origin(0,0)
表2-3 设备描述表的分类
Display显示设备描述表,提供对视频显示设备上的绘制操作的支持
Printer打印设备描述表,提供对打印机、绘图仪设备上的绘制操作的支持
Memory内存设备描述表,提供对位图操作的支持
Information信息设备描述表,提供对操作设备信息获取的支持
表2-3中的显示设备描述表又分三种类型,如表2-4所示。
表2-4 显示设备描述表的分类
名称特点功能
Class Device
Contexts提供对Win16的向后兼容
Common
Device
Contexts在Windows系统的高速缓冲区,数量有限Applicaion获取设备描述表时,Windows用缺省值初始化该设备描述表,Application使用它完成绘制操作,然后释放
Private
Device
Contexts没有数量限制,用完不需释放一次获取,多次使用多次使用过程中,每次设备描述表属性的任何修改或变化都会被保存,以支持快速绘制
(1)使用设备描述表的步骤
要使用设备描述表,一般有如下步骤:
获取或者创建设备描述表;
必要的话,改变设备描述表的属性;
使用设备描述表完成绘制操作;
释放或删除设备描述表。
Common设备描述表通过::GetDC,::GetDCEx,::BeginPaint来获得一个设备描述表,用毕,用::ReleaseDC或::EndPaint释放设备描述表;
Printer设备描述表通过::CreateDC创建设备描述表,用::DeleteDC删除设备描述表。
Memory设备描述表通过::CreateCompatibleDC创建设备描述表,用::DeleteDC删除。
Information设备描述表通过::CreateIC创建设备描述表,用::DeleteDC删除。
(2)改变设备描述表属性的途径
要改变设备描述表的属性,可通过以下途径:
用::SelectObject选入新的除调色板以外的GDI Object到设备描述表中;
对于调色板,使用::SelectPalette函数选入逻辑调色板,并使用::RealizePalette把逻辑调色板的入口映射到物理调色板中。
用其他API函数改变其他属性,如::SetMapMode改变映射模式。
设备描述表在MFC中的实现
MFC提供了CDC类作为设备描述表类的基类,它封装了Windows的HDC设备描述表对象和相关函数。
CDC类
CDC类包含了各种类型的Windows设备描述表的全部功能,封装了所有的Win32 GDI 函数和设备描述表相关的SDK函数。在MFC下,使用CDC的成员函数来完成所有的窗口绘制工作。
CDC 类的结构示意图2-2所示。
CDC类有两个成员变量:m_hDC,m_hAttribDC,它们都是Windows设备描述表句柄。CDC的成员函数作输出操作时,使用m_Hdc;要获取设备描述表的属性时,使用m_hAttribDC。
在创建一个CDC类实例时,缺省的m_hDC等于m_hAttribDC。如果需要的话,程序员可以分别指定它们。例如,MFC框架实现CMetaFileDC类时,就是如此:CMetaFileDC从物理设备上读取设备信息,输出则送到元文件(metafile)上,所以m_hDC和m_hAttribDC是不同的,各司其责。还有一个类似的例子:打印预览的实现,一个代表打印机模拟输出,一个代表屏幕显示。
CDC封装::SelectObject(HDC hdc,HGDIOBJECT hgdiobject)函数时,采用了重载技术,即它针对不同的GDI对象,提供了名同而参数不同的成员函数:
SelectObject(CPen *pen)用于选入笔;
SelectObject(CBitmap* pBitmap)用于选入位图;
SelectObject(CRgn *pRgn)用于选入剪裁区域;
SelectObject(CBrush *pBrush)用于选入刷子;
SelectObject(CFont *pFont)用于选入字体;
至于调色板,使用SelectPalette(CPalette *pPalette,BOOL bForceBackground )选入调色板到设备描述表,使用RealizePalletter()实现逻辑调色板到物理调色板的映射。
从CDC派生出功能更具体的设备描述表
从CDC 派生出四个功能更具体的设备描述表类。层次如图2-3所示。
下面,分别讨论派生出的四种设备描述表。
CCientDC
代表窗口客户区的设备描述表。其构造函数CClientDC(CWnd *pWin)通过::GetDC获取指定窗口的客户区的设备描述表HDC,并且使用成员函数Attach把它和CClientDC对象捆绑在一起;其析构函数使用成员函数Detach把设备描述表句柄HDC分离出来,并调用::ReleaseDC释放设备描述表HDC。
CPaintDC
仅仅用于响应WM_PAINT消息时绘制窗口,因为它的构造函数调用了::BeginPaint获取设备描述表HDC,并且使用成员函数Attach把它和CPaintDC对象捆绑在一起;析构函数使用成员函数Detach把设备描述表句柄HDC分离出来,并调用::EndPaint释放设备描述表HDC,而::BeginPaint和::EndPaint仅仅在响应WM_PAINT时使用。
CMetaFileDC
用于生成元文件。
CWindowDC
代表整个窗口区(包括非客户区)的设备描述表。其构造函数CWindowDC(CWnd *pWin)通过::GetWindowDC获取指定窗口的客户区的设备描述表HDC,并使用Attach把它和CWindowDC对象捆绑在一起;其析构函数使用Detach把设备描述表HDC分离出来,调用::ReleaseDC释放设备描述表HDC。
MFC设备描述表类的使用
使用CPaintDC、CClientDC、CWindowDC的方法
首先,定义一个这些类的实例变量,通常在栈中定义。然后,使用它。
例如,MFC中CView对WM_PAINT消息的实现方法如下:
void CView::OnPaint()
{
// standard paint routine
CPaintDC dc(this);
OnPrepareDC(&dc);
OnDraw(&dc);
}
在栈中定义了CPaintDC类型的变量dc,随着构造函数的调用获取了设备描述表;设备描述表使用完毕,超出其有效范围就被自动地清除,随着析构函数的调用,其获取的设备描述表被释放。
如果希望在堆中创建,例如
CPaintDC *pDC;
pDC = new CPaintDC(this)
则在使用完毕时,用delete删除pDC:
delete pDC;
评论
查看更多