Windows DC介绍

Windows程序中DC的介绍 装置内容(简称为「DC」)实际上是GDI内部保存的资料结构。装置内容与特定的显示设备(如视讯显示器或印表机)相关。 对於视讯显示器,装置内容总是与显示器上的特定视窗相关。 装置内容中的有些值是图形「属性」,这些属性定义了GDI绘图函式工作的细节。例如,对於TextOut,装置内容的属性确定 了文字的颜色、文字的背景色、x座标和y座标映射到视窗的显示区域的方式,以及显示文字时Windows使用的字体。 MSDN的解释: Device Contexts A device context is a structure that defines a set of graphic objects and their associated attributes, as well as the graphic modes that affect output. The graphic objects include a pen for line drawing, a brush for painting and filling, a bitmap for copying or scrolling parts of the screen, a palette for defining the set of available colors, a region for clipping and other operations, and a path for painting and drawing operations. The remainder of this section is divided into the following three areas. About Device Contexts Device independence is one of the chief features of Microsoft Windows. Applications can draw and print output on a variety of devices. The software that supports this device independence is contained in two dynamic-link libraries. The first, Gdi.dll, is referred to as the graphics device interface (GDI); the second is referred to as a device driver. The name of the second depends on the device where the application draws output. For example, if the application draws output in the client area of its window on a VGA display, this library is Vga.dll; if the application prints output on an Epson FX-80 printer, this library is Epson9.dll. An application must inform GDI to load a particular device driver and, once the driver is loaded, to prepare the device for drawing operations (such as selecting a line color and width, a brush pattern and color, a font typeface, a clipping region, and so on). These tasks are accomplished by creating and maintaining a device context (DC). A DC is a structure that defines a set of graphic objects and their associated attributes, and the graphic modes that affect output. The graphic objects include a pen for line drawing, a brush for painting and filling, a bitmap for copying or scrolling parts of the screen, a palette for defining the set of available colors, a region for clipping and other operations, and a path for painting and drawing operations. Unlike most of the structures, an application never has direct access to the DC; instead, it operates on the structure indirectly by calling various functions. 取得DC的各种方式 SDK's way: 1. BeginPaint case WM_PAINT: HDC hdc = BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); MSDN的解释: The BeginPaint function automatically sets the clipping region of the device context to exclude any area outside the update region. The update region is set by the InvalidateRect or InvalidateRgn function and by the system after sizing, moving, creating, scrolling, or any other operation that affects the client area. If the update region is marked for erasing, BeginPaint sends a WM_ERASEBKGND message to the window. An application should not call BeginPaint except in response to a WM_PAINT message. Each call to BeginPaint must have a corresponding call to the EndPaint function. 其中给出了本次重绘的Clip Rectangle,所有在这个rectangle之外的绘制操作都不会显示。 这两个BeginPaint和EndPaint呼叫之间中没有任何叙述,仅仅使先前无效区域变为有效。 但以下方法是错误的: case WM_PAINT: return 0 ; // WRONG !!! Windows将一个WM_PAINT讯息放到讯息伫列中,是因为显示区域的一部分无效。如果不呼叫BeginPaint和EndPaint(或者 ValidateRect),则Windows不会使该区域变为有效。相反,Windows将发送另一个WM_PAINT讯息,且一直发送下去。 2. GetDC MSDN的解释: The GetDC function retrieves a handle to a display device context (DC) for the client area of a specified window or for the entire screen. You can use the returned handle in subsequent GDI functions to draw in the DC. 与BeginPaint和EndPaint一样,GetDC和ReleaseDC函式必须成对地使用。如果在处理某讯息时呼叫GetDC,则必须在退出视窗讯息 处理程式之前呼叫ReleaseDC。不要在一个讯息中呼叫GetDC却在另一个讯息呼叫ReleaseDC。 与从BeginPaint传回装置内容代号不同,GetDC传回的装置内容代号具有一个剪取矩形,它等於整个显示区域。可以在显示区域的某 一部分绘图,而不只是在无效矩形上绘图(如果确实存在无效矩形)。与BeginPaint不同,GetDC不会使任何无效区域变为有效。如 果需要使整个显示区域有效,可以呼叫 ValidateRect (hwnd, NULL) ; 一般可以呼叫GetDC和ReleaseDC来对键盘讯息(如在字处理程式中)和滑鼠讯息(如在画图程式中)作出反应。此时,程式可以 立刻根据使用者的键盘或滑鼠输入来更新显示区域,而不需要考虑为了视窗的无效区域而使用WM_PAINT讯息。不过,一旦确实收 到了WM_PAINT讯息,程式就必须要收集足够的资讯後才能更新显示。 与GetDC相似的函式是GetWindowDC。GetDC传回用於写入视窗显示区域的装置内容代号,而GetWindowDC传回写入整个视窗的 装置内容代号。例如,您的程式可以使用从GetWindowDC传回的装置内容代号在视窗的标题列上写入文字。然而,程式同样也应该 处理WM_NCPAINT (「非显示区域绘制」)讯息。 3. CreateDC MSDN的解释: HDC CreateDC( LPCTSTR lpszDriver, // driver name LPCTSTR lpszDevice, // device name LPCTSTR lpszOutput, // not used; should be NULL CONST DEVMODE* lpInitData // optional printer data ); MFC's way 1. CDC 对HDC的包装,类似CWnd对HWND的包装.在CDC的构造函数里面并没有对m_hDC进行初始化. MSDN的解释: class CDC : public CObject Defines a class of device-context objects. Remarks The CDC object provides member functions for working with a device context, such as a display or printer, as well as members for working with a display context associated with the client area of a window. Do all drawing through the member functions of a CDC object. The class provides member functions for device-context operations, working with drawing tools, type-safe graphics device interface (GDI) object selection, and working with colors and palettes. It also provides member functions for getting and setting drawing attributes, mapping, working with the viewport, working with the window extent, converting coordinates, working with regions, clipping, drawing lines, and drawing simple shapes, ellipses, and polygons. Member functions are also provided for drawing text, working with fonts, using printer escapes, scrolling, and playing metafiles. To use a CDC object, construct it, and then call its member functions that parallel Windows functions that use device contexts. For specific uses, the Microsoft Foundation Class Library provides several classes derived from CDC . CPaintDC encapsulates calls to BeginPaint and EndPaint. CClientDC manages a display context associated with a window's client area. CWindowDC manages a display context associated with an entire window, including its frame and controls. CMetaFileDC associates a device context with a metafile. MFC中的代码实现: CDC::CDC() { m_hDC = NULL; m_hAttribDC = NULL; m_bPrinting = FALSE; } CDC::~CDC() { if (m_hDC != NULL) ::DeleteDC(Detach()); } BOOL CDC::Attach(HDC hDC) { ASSERT(m_hDC == NULL); // only attach once, detach on destroy ASSERT(m_hAttribDC == NULL); // only attach to an empty DC if (hDC == NULL) return FALSE; CHandleMap* pMap = afxMapHDC(TRUE); // create map if not exist ASSERT(pMap != NULL); pMap->SetPermanent(m_hDC = hDC, this); SetAttribDC(m_hDC); // Default to same as output return TRUE; } HDC CDC::Detach() { HDC hDC = m_hDC; if (hDC != NULL) { CHandleMap* pMap = afxMapHDC(); // don't create if not exist if (pMap != NULL) pMap->RemoveHandle(m_hDC); } ReleaseAttribDC(); m_hDC = NULL; return hDC; } 2. CPaintDC 对BeginPaint的包装 MSDN的解释: class CPaintDC : public CDC It performs a CWnd::BeginPaint at construction time and CWnd::EndPaint at destruction time. A CPaintDC object can only be used when responding to a WM_PAINT message, usually in your OnPaint message-handler member function. MFC中的代码实现: 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(); } 3. CClientDC 对GetDC的包装 MSDN的解释: class CClientDC : public CDC This means that the device context associated with a CClientDC object is the client area of a window. MFC中的代码实现: CClientDC::CClientDC(CWnd* pWnd) { ASSERT(pWnd == NULL || ::IsWindow(pWnd->m_hWnd)); if (!Attach(::GetDC(m_hWnd = pWnd->GetSafeHwnd()))) AfxThrowResourceException(); } CClientDC::~CClientDC() { ASSERT(m_hDC != NULL); ::ReleaseDC(m_hWnd, Detach()); } 4. CWindowDC 对GetWindowDC的包装 MSDN的解释: Calls the Windows functions GetWindowDC at construction time and ReleaseDC at destruction time. This means that a CWindowDC object accesses the entire screen area of a CWnd (both client and nonclient areas). MFC中的代码实现: CWindowDC::CWindowDC(CWnd* pWnd) { ASSERT(pWnd == NULL || ::IsWindow(pWnd->m_hWnd)); if (!Attach(::GetWindowDC(m_hWnd = pWnd->GetSafeHwnd()))) AfxThrowResourceException(); } CWindowDC::~CWindowDC() { ASSERT(m_hDC != NULL); ::ReleaseDC(m_hWnd, Detach()); }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值