VC++ Programming @ UESTC
1
Chapter 5 The Graphics Device Interface,
Color and Fonts
This hands-on chapter shows you how to build a MFC
library application working with only the view element.
How to use Graphics Device Interface (GDI)
How to use Resource Editor
Debug Target vs,Release Target
Understand Diagnostic Macros
Understand the Precompiled Headers
VC++ Programming @ UESTC
2
Windows Class and C++ Object and how to related
them together
Device Context Classes revisited
GDI Objects
Windows Color Mapping
Fonts
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
3
typedef struct tagWNDCLASS
{
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
} WNDCLASS;
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
4
The MFC classes wrap Windows object handles with C++
objects,
For example,each C++ device context object has an
associated HDC handle.
Associate the two wrapper class and the handle to the
windows object by calling Attach,
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
5
For example:
CWnd myWnd;
myWnd.Attach(hWnd);
This makes an entry in the permanent map associating
myWnd and hWnd,
When myWnd is deleted,the destructor will automatically
destroy the hWnd by calling the Windows DestroyWindow
function.
If this is not desired,the hWnd must be detached from
myWnd before the myWnd object is destroyed (normally
when leaving the scope at which myWnd was defined),
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
6
Device context is the key GDI element that represents a
physical device.
The MFC CDC class has all the member functions that
you’ll need for drawing.
Except for the CMetaFileDC class,derived classes are
distinct only in their constructor and destructor.
For display and printer device context objects,framework
attaches the handle to the object,
For memory device context,you must call a member
function to attach the handle after construction.
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
7
The Display Context Classes CClientDC and CWindowDC
CClientDC does not include menu bar,toolbar,status bar
and scroll bar.
CWindowDC is more applicable to the frame windows than
it is to the view windows
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
8
Properly handle CDC object to release the windows
resource.
1,Construct object object the stack
void CMyView::OnLButtonDown(UINT nFlags,
Cpoint point) {
CRect rect;
CClientDC dc(this); // from stack
dc.GetClipBox(rect); }// dc automatically released
2,Use CWnd::GetDC ….,OnLButtonDown(….) {
Crect rect;
CDC* pDC = GetDC(); ….
ReleaseDC(pDC); }
3,You must not to destroy CDC object passed by
OnDraw,Let framework does it for you.
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
9
The State of the Device Context
What you see on screen or printer depends on the current
state of device context.
1,Attached GDI drawing objects such as pens,bruhes and
fonts.
2,The mapping mode that determines the scale of items
then they are drawn.
3,Various details such as alignment parameters and polygon
filling mode.
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
10
GDI Objects
CGdiObject is the abstract base class for the GDI classes.
Derived Classes for Windows GDI Objects
Class Windows handle type
CPen HPEN
CBrush HBRUSH
CFont HFONT
CBitmap HBITMAP
CPalette HPALETTE
CRgn HRGN
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
11
One-stage construction,Construct and initialize the object in
one stage,all with the constructor.
Two-stage construction,Construct and initialize the object in
two separate stages,The constructor creates the object and
an initialization function initializes it,
CFont and CRgn reqires a second initialization.
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
12
Destroy GDI object.
Failure to delete a GDI object is a serious problem.
The derived class destructor delete the Windows
GDI objects that are attached to the C++ objects.
To delete a GDI object,first separate it from the
device context.
Use CDC::SelectObject() to disconnect GDI
objects from the device context.
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
13
Void CMyView::OnDraw(CDC* pDC){
CPen newPen(PS_DASHDOTDOT,2,(COLORREF) 0);
Cpen * pOldPen = pDC->SelectObject(&newPen);// save old
pen
pDC->Move(10,10);
pDC->:Lineto(110,10);
pDC-SelectObject(pOldPen); // newPen is disconnected
} // newPen automatically destroyed on exit
CDC.SelectObject() returns a pointer to the previously selected
object.
Windows Pen may be shared by many applications
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
14
Windows contain many stock GDI object which are part of windows,
Windows ignores requests to delete stock objects.
Programmers may use SelectStockObject to deselect your own nonstock
GDI object prior to its destruction,
Void CMyView::OnDraw(CDC* pDC){
CPen newPen(PS_DASHDOTDOT,2,(COLORREF) 0);
pDC->SelectObject(&newPen);
pDC->Move(10,10);
pDC->:Lineto(110,10);
pDC-SelectStockObject(BLACK_PEN); // newPen is
disconnected
} // newPen automatically destroyed on exit
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
15
The Lifetime of a GDI Selection
1,For the display DC,you get a,fresh” device
context at the beginning of each message handler
function.
2,For long-life device context such as printers and
memory buffers,you must convert the temporary
GDI objects pointer to Windows Handles with
the GetSafeHdc member function,
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
16
Void CMyView:,SwitchToCourier*CDC* pDC){
m_pPrintFont->CreateFont(30,10,0,0,400,FALSE,FALSE,
0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
DEFAULT_PITCH|FF_MODERN,”Couier New”);
CFont* pOldFont=pDC->SelectObject(m_pPrintFont);
m_hOldFont = (HFONT) pOldFont->GetSafeHandle();}
Void CMyView::SwitchToOriginal(CDC* pDC){
if (m_hOldFont){
pDC->SelectObject(Cfont::FromHandle(m_hOldFont));}}
m_hOldFont is CMyView data member of type HFONT,
FromHandle() is static function returns object pointer.
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
17
Windows Color Mapping
1,Standard Video Graphics Array Video Cards,4
bit color codes,16 colors at a time.
2,256-color Video Cards,20 standard pure colors
3,16-Bit-Color Video Cards,1MB video memory
card support 8-bit color at 1024*768 pixel
resolution; 2MB Video cards support 16-Bit color,
5-bit each for red,green and blue.
4,24-Bit-Color Video Cards,you need 2.5MB
video memory to support 24bit color at 1024*768
pixel resolution.
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
18
Fonts
1,Device-independent TrueType fonts;
2,Device-dependent fonts such as Windows display System
fonts and LaserJet LinePrinter font;
Fonts are GDI Objects
Built-in printer fonts are defined in terms of points; One
point=20 twips; We use MM_TWIPS to set printer mode.
Displaying Fonts:
The pixel width of the characters depends on the font,
the mapping mode and the resolution of the output device.
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
19
Logic display size may not be the same as physical size.
When use a fixed mapping mode,the display driver uses the
physical display size to do the mapping.
For a MS Windows NT 4.0 at the resolution of 640*480
pixel,physical display 12.60-by-9.45inches; logical size is
6.67-by-5.0 inches.
CDC::GetDeviceCaps() returns various display
measurements that are important to your graphics
programming.
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
20
Ex05A sets up a view window with the logic twips mapping
mode,A text string is displayed in 10 point size with the
Arial TrueType font.
void CEx05aView::OnPrepareDC(CDC* pDC,CPrintInfo*
pInfo)
{
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetWindowExt(1440,1440);
pDC->SetViewportExt(pDC-
>GetDeviceCaps(LOGPIXELSX),
-pDC->GetDeviceCaps(LOGPIXELSY));
}
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
21
pDC->SetWindowExt(1440,1440):
Sets the x- and y-extents of the window associated with
the device context
pDC->SetViewportExt(pDC>GetDeviceCaps(LOGPIXELSX),
-pDC->GetDeviceCaps(LOGPIXELSY));
Sets the x- and y-extents of the viewport of the device context.
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
22
void CEx05aView::OnDraw(CDC* pDC)
{
int nPosition = 0;
for (int i = 6; i <= 24; i += 2) {
ShowFont(pDC,nPosition,i);
}
}
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
23
void CEx05aView::ShowFont(CDC* pDC,int& nPos,int nPoints){
TEXTMETRIC tm;
…..
fontText.CreateFont(-nPoints * 20,0,0,0,400,FALSE,FALSE,0,
ANSI_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
DEFAULT_PITCH | FF_SWISS,"Arial");
CFont* pOldFont = (CFont*) pDC->SelectObject(&fontText);
pDC->GetTextMetrics(&tm);
pDC->TextOut(0,nPos,strText);
pDC->SelectObject(pOldFont);
nPos -= tm.tmHeight + tm.tmExternalLeading;
}
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
24
Ex05B shows multiple fonts with mapping mode
MM_ANISOTROPIC with the scale dependent on the window
size.
void CEx05bView::OnPrepareDC(CDC* pDC,CPrintInfo* pInfo) {
CRect clientRect;
GetClientRect(clientRect);
pDC->SetMapMode(MM_ANISOTROPIC); // +y = down
pDC->SetWindowExt(400,450);
pDC->SetViewportExt(clientRect.right,clientRect.bottom);
pDC->SetViewportOrg(0,0);
}
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
25
void CEx05bView::OnDraw(CDC* pDC){
CFont fontTest1,fontTest2,fontTest3,fontTest4;
fontTest1.CreateFont(50,0,0,0,400,FALSE,FALSE,0,
ANSI_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
DEFAULT_PITCH | FF_SWISS,"Arial");
……
fontTest2.CreateFont(50,0,0,0,400,FALSE,FALSE,0,
ANSI_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
DEFAULT_PITCH | FF_MODERN,"Courier"); // notTrueType
….
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
26
fontTest3.CreateFont(50,10,0,0,400,FALSE,FALSE,0,
ANSI_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH | FF_ROMAN,NULL);

fontTest4.CreateFont(50,0,0,0,400,FALSE,FALSE,0,
ANSI_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH | FF_MODERN,
"LinePrinter");
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
27
Pay attention to the fontest2,the courier font stops
shrinking after a certain size,
FF_MODERN Fonts with constant stroke width (fixed-
pitch),with or without serifs,Fixed-pitch fonts are usually
modern faces,Pica,Elite,and Courier New are examples.
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
28
Ex05C allows the user to move an ellipse with a
mouse by,capturing” the mouse,using a scrolling
window with the MM_LOENGLISH mapping
mode,
const CSize m_sizeEllipse; // logical
CPoint m_pointTopLeft; // logical,top
left of ellipse
rectangle
CSize m_sizeOffset; // device,from rect
top left to capture point
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
29
void CEx05cView::OnLButtonDown(UINT nFlags,CPoint point) {
CRect rectEllipse(m_pointTopLeft,m_sizeEllipse); // still logical
CRgn circle;
….
dc.LPtoDP(rectEllipse); // Now it's in device coordinates
circle.CreateEllipticRgnIndirect(rectEllipse);
if (circle.PtInRegion(point)) {
// Capturing the mouse ensures subsequent LButtonUp message
SetCapture(); m_bCaptured = TRUE;
CPoint pointTopLeft(m_pointTopLeft);
dc.LPtoDP(&pointTopLeft);
m_sizeOffset = point - pointTopLeft; // device coordinates
// New mouse cursor is active while mouse is captured
::SetCursor(::LoadCursor(NULL,IDC_CROSS));}
}
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
30
MFC does not,wrap” some Win32 functions,By
convention,use scope resolution operate,,when calling
Win32 function.
void CEx05cView::OnLButtonUp(UINT nFlags,CPoint point)
{
if (m_bCaptured) {
::ReleaseCapture();
m_bCaptured = FALSE;
}
}
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
31
void CEx05cView::OnMouseMove(UINT nFlags,CPoint point) {
if (m_bCaptured) {
CClientDC dc(this);
OnPrepareDC(&dc);
CRect rectOld(m_pointTopLeft,m_sizeEllipse);
dc.LPtoDP(rectOld);
InvalidateRect(rectOld,TRUE);
m_pointTopLeft = point - m_sizeOffset;// in device coord
dc.DPtoLP(&m_pointTopLeft); // back to logic cord
CRect rectNew(m_pointTopLeft,m_sizeEllipse);
dc.LPtoDP(rectNew);
InvalidateRect(rectNew,TRUE);
}
} // invalidate the two union of the rectangles.
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
32
void CEx05cView::OnDraw(CDC* pDC){
CBrush brushHatch(HS_DIAGCROSS,RGB(255,0,0));
CPoint point(0,0); // logical (0,0)
pDC->LPtoDP(&point); // In device coordinates,
pDC->SetBrushOrg(point); // align the brush with
// the window origin
pDC->SelectObject(&brushHatch);
pDC->Ellipse(CRect(m_pointTopLeft,m_sizeEllipse));
pDC->SelectStockObject(BLACK_BRUSH); // Deselect
brushHatch
pDC->Rectangle(CRect(100,-100,200,-200)); // Test
invalid rect
}
Chapter 5 The Graphics Device Interface,
Color and Fonts
VC++ Programming @ UESTC
33
Exception,
pDC->LPtoDP(&point); // In device coordinates,
pDC->SetBrushOrg(point); // align the brush with
// the window origin
CDC member functions require logical coordinates.
Chapter 5 The Graphics Device Interface,
Color and Fonts