11.04.2014 Views

Advanced MFC Programming

Advanced MFC Programming

Advanced MFC Programming

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Chapter 9. Font<br />

POINT pt;<br />

CClientDC dc(NULL);<br />

CFont *ptrFtOld;<br />

CString szStr;<br />

CSize sizeExtent;<br />

ASSERT(m_ftDraw.GetSafeHandle());<br />

ptrFtOld=dc.SelectObject(&m_ftDraw);<br />

szStr=m_szText.Left(m_nCaretIndex);<br />

sizeExtent=dc.GetTextExtent(szStr);<br />

dc.SelectObject(ptrFtOld);<br />

}<br />

pt.x=sizeExtent.cx;<br />

pt.y=0;<br />

return pt;<br />

The caret position is calculated through using function CDC::GetTextExtent(…), which will return the<br />

vertical and a horizontal size of a text string. We need a DC to select the current font in order to calculate<br />

the text dimension. In the sample, first a DC that does not belong to any window is created, then the current<br />

font is selected into this DC, and function CString::Left() is called to obtain a sub-string whose last<br />

character is located at the current caret position. The horizontal size obtained from function CDC::<br />

GetTextExtent(…) for the sub-string is the caret’s horizontal position. Because we have only one line text,<br />

the vertical position of the caret is always 0.<br />

This function may be called within the member functions of CGDIView to retrieve the current caret<br />

position. The other two functions, CGDIDoc::ForwardCaret() and CGDIDoc::BackwardCaret() can be<br />

called to move the caret forward or backward. They are implemented as follows:<br />

void CGDIDoc::ForwardCaret()<br />

{<br />

m_nCaretIndex++;<br />

if(m_nCaretIndex > m_szText.GetLength())<br />

{<br />

m_nCaretIndex=m_szText.GetLength();<br />

}<br />

GetCGDIView()->RedrawCaret();<br />

}<br />

void CGDIDoc::BackwardCaret()<br />

{<br />

m_nCaretIndex--;<br />

if(m_nCaretIndex < 0)<br />

{<br />

m_nCaretIndex=0;<br />

}<br />

GetCGDIView()->RedrawCaret();<br />

}<br />

Instead of calculating the actual position of the caret, we just increment or decrement the caret index.<br />

The range of this index is from 0 to the total number of characters (If there are five characters, we have six<br />

possible positions for displaying the caret). If the index goes beyond the limit, we set it back to the<br />

boundary value.<br />

At the end of above two functions, function CGDIDoc::GetCGDIView() is called to access class<br />

CGDIView, then CGDIView::RedrawCaret() is called to update the caret. This will cause the caret to be<br />

displayed in a new position. To access a view from the document, we need to call function CDocument::<br />

GetFirstViewPosition() and then call CDocument::GetNextView(…) repeatedly until we get the correct<br />

view. For an SDI application, we need to call this function only once. However, some applications may<br />

have more than one view attached to the document (Like an MDI application). In this case, we need to use<br />

RUNTIME_CLASS macro to judge if the class is the one we are looking for. In the sample, CGDIDoc::<br />

GetCGDIView() is implemented as a general function, it can also be used in an MDI application to obtain a<br />

specific view from the document. The following is its implementation:<br />

CGDIView *CGDIDoc::GetCGDIView()<br />

253

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!