《MFC那点儿事》の设备上下文DC

设备上下文DC是一个Windows数据结构,它包含了某个设备的绘制属性。通常,绘制调用都是借助于上下文对象,而这些设备上下文对象封装了用于画线、形状、文本等的Windows API。设备上下文是设备无关的,所以它既可以用于绘制屏幕,也可以用于绘制打印机甚至元文件。设备上下文在内存中创建,而内存经常受到扰动,所以它的地址是不固定的。因此,一个设备上下文句柄不是直接指向设备上下文对象,而是指向另外一个跟踪设备上下文地址的指针。

 

设备上下文可分为4种:

1)显示设备上下文

主要用于显示设备上的绘制操作,当应用绘制客户区时,它需要调用BeginPaintGetDCGetDCEx函数获取显示设备上下文。绘制结束后,需要调用EndPaintReleaseDC函数释放它。

2)打印机设备上下文

应用程序以合适的参数(如打印机驱动名、打印机名等)调用函数CreateDC,完成打印任务后,就会调用DeleteDC,以删除打印机设备上下文。

3)内存设备上下文

主要为特定的设备存储位图,它支持在位图上进行绘制操作。通常通过调用CreateCompatibleDC来获取内存设备上下文,当系统处理这个调用时,它将在内存中创建一个和原始设备颜色格式兼容的位图。

内存设备上下文将系统内存用作显示表面,通常使用内存设备上下文预先在系统内存中绘制复杂的图形,然后再快速地将其复制到实际的设备上下文的显示表面上,而绘制图形的结果仍保存在内存设备上下文的DDB中。

4)信息设备上下文

主要用于获取默认设备的数据。如调用函数CreateIC,以便为打印机的特定模型创建信息设备上下文,然后调用函数GetCurrentObjectGetObject来获取默认的画笔和画刷的属性。在使用完信息设备上下文之后,需调用DeleteDC以删除设备上下文。

 

MFC中,CDC类封装了绘图所需要的所有成员函数,以及各种类型的Windows设备上下文的全部功能。

CDC类有两个成员变量:m_hDCm_hAttribDC,它们都是Windows设备上下文句柄。在创建CDC对象时,它们指向同一个设备。CDC设备使用m_hDC对其所有的成员函数作输出调用;而使用m_hAttribDC对其所有成员函数作属性调用。一般情况下,这两个成员变量的值是一样的,如果需要的话,可以将它们初始化为不同的设备句柄,如在使用CMetaFileDC类时(CMetaFileDC从物理设备上获取设备信息,而输出却在元文件上,所以m_hDCm_hAttribDC是不同的)。

构造函数如下:

CDC::CDC()

{

         m_hDC = NULL;

         m_hAttribDC = NULL;

         m_bPrinting = FALSE;

}

在实践中,CDC不像派生类那样使用::GetDC()等函数来获取一个设备上下文,而是创建一个设备上下文,如CDC::CreateCompatibleDC等。

析构函数:

CDC::~CDC()

{

         if(m_hDC != NULL)

                   ::DeleteDC(Detach());

}

 

 

具体使用时,MFC提供了以下四个CDC派生类

1CPaintDC—封装了对BeginPaintEndPaint的调用

Windows应用程序中,通常在绘制图像之前调用BeginPaint,然后在设备上下文中进行一系列绘制操作,最后调用EndPaint函数结束绘制。类CPaintDC正是封装了该过程:在构造CPaintDC对象时,其构造函数自动调用BeginPaint函数;在销毁CPaintDC对象时,其析构函数自动调用EndPaint函数。

在基于框架的应用中,一般在视图类的OnDraw成员函数中处理有关重绘的操作。通过OnPrepareDC成员函数,框架自动向OnDraw成员函数传递一个类型为CPaintDC的设备上下文对象,并且在此对象上进行绘制,而对象的构造和销毁则由框架自动完成。

CPaintDC的构造函数:

CPaintDC::CPaintDC(CWnd* pWnd)

{

         ASSERT_VALID(pWnd);

         ASSERT(::IsWindow(pWnd->m_hWnd));

         if(!Attach(::BeginPaint(m_hWnd = pWnd->m_hWnd, &m_ps)))

                   AfxThrowResourceException();

}

析构函数:

CPaintDC::~CPaintDC()

{

         ASSERT(m_hDC != NULL);

         ASSERT(::IsWindow(m_hWnd));

         ::EndPaint(m_hWnd, &m_ps);

         Detach();

}

 

2CClientDC—管理窗口客户区对应的显示设备上下文

CClientDC构造函数中,通过调用GetDC函数而非BeginPaint来获取设备上下文;在析构函数中调用ReleaseDC而非EndPaint

CClientDC::CClientDC(CWnd* pWnd)

{

         ASSERT(pWnd == NULL || ::IsWindow(pWnd->m_hWnd));

         //Attach用于将设备上下文句柄和设备上下文类绑定

         if(!Attach(::GetDC(m_hWnd = pWnd->GetSafeHwnd())))

                   AfxThrowResourceException();

}

 

CClientDC::~CClientDC()

{

         ASSERT(m_hDC != NULL);

         ::ReleaseDC(m_hWnd, Detach());//先解除设备上下文资源与C++类对象的绑定

}

 

3CWindowDC—管理与整个窗口对应的显示设备上下文,包括它的框架和控件

构造函数如下:

CWindowDC::CWindowDC(CWnd* pWnd)

{

         ASSERT(pWnd == NULL || ::IsWindow(pWnd->m_hWnd));

         if(!Attach(::GetWindowDC(m_hWnd = pWnd->GetSafeHwnd())))

                   AfxThrowResourceException();

}

释放设备上下文使用的是ReleaseDC,析构函数和CClientDC完全一样。此类对象主要用于窗口的非客户区,如在响应消息WM_NCPAINT时,就可以在非客户区上进行绘制,不过一般很少使用该类。

 

4CMetaFileDC—与带有元文件的设备上下文相关联

 

在设备上下文中可以完成如下操作:枚举现有的图形对象、选入新的图形对象、删除现存的图形对象、保存当前的图形对象以及它们的属性、恢复先前保存的图形对象以及它们的属性以及其他操作等。

你可能感兴趣的:(mfc)