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 />

Two local variables nSelIndexBgn and nSelIndexEnd are declared here, they are used to store the<br />

values of CGDIDoc::m_nSelIndexBgn and CGDIDoc::m_nSelIndexEnd retrieved from the document. If the<br />

value of CGDIDoc::m_nSelIndexEnd is less than the value of CGDIDoc::m_nSelIndexBgn (In this case, the<br />

selection is made from right to left), we need to swap their values.<br />

If there is no currently selected text, we simply call CDC::TextOut(…) as usual to output the plain text.<br />

Otherwise we swap the two indices if m_nSelIndexEnd is less than m_nSelIndexBgn, and set the text<br />

alignment by calling function CDC::SetTextAlign(…) using TA_UPDATECP flag. This will cause the output<br />

origin to be updated to the end of the text after each CDC::TextOut(…) call. If we do not set this alignment,<br />

the coordinates passed to function CDC::TextOut(…) indicate a position relative to the upper-left corner of<br />

the window. With TA_UPDATECP alignment style, when we call function CDC::TextOut(…), the coordinates<br />

passed to this function will be interpreted as a position relative to the new origin (which is the end of the<br />

text that is output by function CDC::TextOut(…) last time). This is very useful if we want to output several<br />

segments of strings. In the sample, the old alignment flag is stored in variable uTextAlign, and is restored<br />

after the text is output.<br />

We divide the text string into three segments: the first segment starts from the beginning of the text and<br />

ends at the beginning of the selection. We output this sub-string using normal text and background colors.<br />

The second segment is the selected portion, before drawing this sub-string we need to swap the text and<br />

background colors so that the selected part will be drawn highlighted. The rest part is the third sub-string,<br />

which is also drawn using the normal text and background colors. Each time function CDC::TextOut(…) is<br />

called, the output coordinates are specified as (0, 0). If the alignment flag is not set to TA_UPDATECP, the<br />

three segments will all be drawn starting from the same origin.<br />

Setting Selection Indices<br />

Now we can change the values of CGDIDoc::m_nSelIndexBgn and CGDIDoc::m_nSelIndexEnd to<br />

highlight any portion of the text string. From user’s point of view, this should happen when the mouse is<br />

clicked and dragged over the text. In order to implement this, we need to respond to WM_LBUTTONDWON,<br />

WM_LBUTTONUP and WM_MOUSEMOVE messages.<br />

When left button is pressed down, we need to first reset the values of CGDIDoc::m_nSelIndexBgn and<br />

CGDIDoc::m_nSelIndexEnd to -1, because we need to unselect any currently highlighted text. Then we can<br />

update the value of CGDIDoc::m_nSelIndexBgn to the current caret index. When mouse moves with the left<br />

button held down, we need to set the value of CGDIDoc::m_nSelIndexEnd to the current caret index (the<br />

caret will move with the mouse cursor). The same thing needs to be done when mouse’s left button is<br />

released. For these purposes, a new function ResetSelection() is declared in class CGDIDoc, which will be<br />

called to reset the selection indices. Also, function CGDIDoc::SetCaret(…) is modified. The following is a<br />

portion of the updated class CGDIDoc:<br />

……<br />

……<br />

class CGDIDoc : public CDocument<br />

{<br />

public:<br />

}<br />

void SetCaret(CPoint);<br />

void ResetSelection()<br />

{<br />

m_nSelIndexBgn=m_nSelIndexEnd=-1;<br />

UpdateAllViews(NULL);<br />

}<br />

Function CGDIDoc::ResetSelection() is implemented inline, it just resets the values of<br />

m_nSelIndexBgn and m_nSelIndexEnd to -1, then updates the view window. The following shows the<br />

modified portion of function CGDIDoc::SetCaret(…):<br />

……<br />

void CGDIDoc::SetCaret(CPoint point)<br />

{<br />

dc.SelectObject(ptrFtOld);<br />

m_nCaretIndex=nIndex;<br />

266

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

Saved successfully!

Ooh no, something went wrong!