In Windows, the graphics device interface (GDI) is responsible for displaying graphics and formatted text on both the screen and the printer. A device context is a Windows data structure containing information about the drawing attributes of the output device. The process of writing text and drawing images to the screen is know as ‘painting’ and before an application can output any information to an output device it must obtain a device context for that output device.

MFC provides the class CDC which encapsulates the device context and provides graphic drawing functionality containing over member 100 functions for drawing text, lines, shapes and setting associated drawing attributes

System Generated Repaint Requests

Windows does not keep a record of the application window content so if by some action, a part of this client area is overwritten then widows will inform the application that this client area needs to ‘repainted’ by posting a WM_PAINT message to the application window. The region of the application client that needs updating is known as an “invalid area”. Windows maintains the size and coordinates of this region for each individual window.

Before an application can ‘repaint’ the screen it must obtain a device context for the client area of the window screen. Windows then fills the device context structure with the attribute values of the device being written to. In MFC, the CDC class wraps a Windows device context and the associated GDI member functions for working with the the ON_WM_PAINT() into one package CPaintDC. The constructor function for CPaintDC is

CPaintDC(CWND *window).

Where window is a pointer to the window whose client area the device context object will access. To get a DC for the invoking windows use the ‘this’ pointer

In order to respond to the WM_PAINT message, an MFC function will need to have a ON_WM_PAINT() entry in the applications message map and then write an associated OnPaint() message handler.

Other Useful Device Context Related Functions

In addition to repainting the screen in response to an ON_WM_PAINT message, the application can also request a device context as a result of some action performed by the user that does not result in the generation of the On_Paint message.

CClientDC

Creates a client-area device context that is not associated with OnPaint. The constructor function for the CClientDC() is

CClientDC (CWND *window)

Where window is a pointer to the window from which the device context is being obtained. To invoke a DC for the invoking windows use this as a parameter. In order to access the entire screen use a NULL pointer.

CWindowDC

Provides a DC to the entire window, including both its client and nonclient area. The nonclient area covers the windows borders, title bar, menu bar, minimize/maximize button, and exit button. The Non-client area is generally under the control of the operating system. The constructor function for CWindowDC() is

CWindowDC (CWND *Window).

Where window is a pointer to the window from which the device context is being obtained. To gain access to the entire screen use the NULL character.

InvalidateRect

Allows an application to manually invalidate a windows region and tells windows that it needs to repaint that region. The prototype for this function is

void InvalidateRect(LPCRECT lpRect,BOOL bErase = TRUE);

where
lpRect – is a pointer to a RECT structure that contains the client coordinates of the update region. If this parameter is NULL, the entire client area is set for update.
bErase – Specifies whether the background within the update region is to be erased when the update region is processed. If this parameter is TRUE, the background is erased when the BeginPaint function is called. If this parameter is FALSE, the background remains unchanged.

ValidateRect

Allows an application to manually validate a Windows region. The prototype for this function is

void ValidateRect(LPCRECT lpRect);

Where lpRect is a pointer to a RECT structure that contains the client coordinates of the rectangle to be removed from the update region. If the RECT structure is NULL then the entire client area is removed from the update rectangle.


The following short program demonstrates the OnPaint() message by keeping a running total of the number of times the client area has been repainted. The repaint request can be generated by dragging another window over the application window or by clicking the minimise and maximise icon.

#include <afxwin.h>
class CSimpleApp : public CWinApp
{
public:
BOOL InitInstance();
};

class CMainFrame : public CFrameWnd
{
public:
CMainFrame();
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
};

BOOL CSimpleApp::InitInstance(){
m_pMainWnd = new CMainFrame();
m_pMainWnd->ShowWindow(m_nCmdShow);
return TRUE;
}

CMainFrame::CMainFrame()
{
Create(NULL, TEXT("MFC Device context"));
}
BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()
CSimpleApp MFCApp1;

//traps paint message
afx_msg void CMainFrame::OnPaint()
{ 
static int repaintcount;//keeps count of repaint
CString convertInt;
repaintcount++;
convertInt.Format(TEXT("%d"),repaintcount);//converts repaintcount integer to string
CPaintDC dc (this); //gets current device context
dc.TextOut(0,0,TEXT(convertInt));//writes a character string at the specified location
}


Download