In MFC, the CDC class wraps the Windows device context and the associated GDI member functions for working with the current display into one package. The Windows graphics system uses pens and brushes to set the appearance of graphics objects and provides several hundred functions for creating the points, lines, shapes and bitmaps associated with a graphical output. Pens define the style, thickness and colour of the pixels drawn, while a brush determines the fill colour of shapes. When Windows creates its first display device context, it comes with a limited number of pens, brushes, fonts and palettes known as stock objects..
If the application requires a change to the device context such as a new pen, then this new pen must be created and selected into the device context. Selecting a new graphics object does not change any pre-existing display elements but only any new graphic output.
Creating Custom Pens
The default pen draws solid black lines that are 1 pixel wide. The CDC member function CreatePen() deals with creating custom pens. The prototype of this function is
BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor );
Were.
nPenStyle -can be any one of the following values: PS_SOLID, PS_DOT, PS_DASHDOT, PS_DASHDOTDOT, PS_NULL, PS_INSIDEFRAME,
nWidth – Specifies the width of the pen
crColor – Contains an RGB colour for the pen.
If the function succeeds, the return value is a handle that identifies a logical pen. If the function fails, the return value is NULL.
For further reading
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdicreatepen
Create Custom Brushes
Brushes are used to fill in any closed objects. They have colour, style and can be bitmaps. The CBrush class encapsulates GDI brushes and supplies various member functions to deal with the creation of custom brushes. The prototype for the CreateSolidBrush() function is
BOOL CreateSolidBrush(COLORREF crColor);
where
crColor is a COLORREF structure that specifies the RGB colour of the brush. Return Nonzero if successful; otherwise 0.
For further reading on brush creation
https://docs.microsoft.com/en-us/cpp/mfc/reference/cbrush-class?view=vs-2019
Selecting Objects
Before any graphics object can be used it must be ‘selected’ into the current device context (DC) using the CDC member function SelectObject(). The new object will then replace the previous graphic object of the same type. The prototype of the SelectObject function for both a Pen() and a Brush() is
CPen* SelectObject(CPen* pPen);
CBrush* SelectObject(CBrush* pBrush);
Where
pPen – A pointer to a CPen object to be selected.
pBrush – A pointer to a CBrush object to be selected.
SelectObject will return a pointer to the previous graphics objects which may be useful should the application need to use the previous selection
For further reading
https://docs.microsoft.com/en-us/cpp/mfc/reference/cdc-class?view=vs-2019#selectobject
Using Stock Objects
The CDC member function SelectStockObject() retrieves a handle to a stock objects. The prototype of this function
virtual CGdiObject* SelectStockObject(int nIndex);
Where the parameter nIndex can be one of the following values: BLACK_BRUSH, DKGRAY_BRUSH ,DC_BRUSH ,GRAY_BRUSH ,HOLLOW_BRUSH ,LTGRAY_BRUSH ,NULL_BRUSH ,WHITE_BRUSH ,BLACK_PEN ,DC_PEN ,NULL_PEN ,WHITE_PEN, ANSI_FIXED_FONT ,ANSI_VAR_FONT ,DEVICE_DEFAULT_FONT ,DEFAULT_GUI_FONT ,OEM_FIXED_FONT ,SYSTEM_FONT ,SYSTEM_FIXED_FONT , DEFAULT_PALETTE
If the function succeeds, the return value is a handle to the requested logical object. If the function fails, the return value is NULL
To select a stock object such as BLACK_PEN into the current device context
SelectObject(GetStockObject(BLACK_PEN));
Since stock objects are pre-created system resources there is no need to delete the object handle once they are no longer required.
For further reading on stock objects
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getstockobject
SaveDC and RestoreDC.
Each time an application requests a device context its attributes are reset to the system default and the default pen and brush will be used. To avoid this reinitialisaton, the current device context state can be saved and restored with the CDC member functions SaveDC() and RestoreDC().
Deleting GDI Objects
Customs pens and brushes, like other objects created from GDI Object classes, are resources consuming space in memory. It is therefore important that they are deleted when no longer required. If a GDI object is created on the stack it will automatically be deleted when it goes out of scope. If a GDI object is created on the heap it must be explicitly deleted by a call to the object member function DeleteObject(). Stock objects, even if they are “created” with CreateStockObject never need to be deleted. Failure to delete GDI objects leads to a “memory leak” and gradual depletion of available system memory.
Dealing with Colour Values
The Windows graphics system uses the RGB colour model to specify colour values. Each possible color is defined by red, green, and blue parameters using values from 0 through 255 with a higher value representing a brighter colour. The COLORREF type is part of the Windows API that uses a single 32-bit value to specify an RGB colour. The GDI contains several macros to combine RGB values into a single 32-big value and to turn a COLORREF data into its RGB components –
//converts rgb to colourref value
COLORREF RGB(BYTE byRed, BYTE byGreen, BYTE byBlue);
//converts colourref value to RGB equivalent
int iRed= GetRValue(COLORREF rgb);
int iGreen =GetGValue(COLORREF rgb);
int iBlue =BYTE GetBValue(COLORREF rgb);
A full description of all the CDC member functions covering graphics output can be found at the following-
https://docs.microsoft.com/en-us/cpp/mfc/reference/cdc-class?view=vs-2019