📄 ch06.htm
字号:
<P>Step 3: Default settings</P>
<P>Step 4: Unselect all check boxes</P>
<P>Step 5: Default settings</P>
<P>Step 6: Select CScrollView from the B<U>a</U>se Class drop-down box as in Figure 6.7.</P>
<P>The New Project Information dialog box should resemble Figure 6.8. Click OK to create the project.</P>
<A HREF="Hfig08.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch06/Hfig08.gif"><b>Fig. 6.8</b></A>
<P><I>Create a scroll application with AppWizard.</I></P>
<P>This application generates very simple lines of text. You only need to keep track of the number of lines that are in the scrolling view at the moment. To do this, add a variable to the document class by following these steps:</P>
<ol>
<li><P> In ClassView, expand the classes, then right-click CScrollDoc.</P>
<li><P> Choose Add Member Variable from the shortcut menu</P>
<li><P> Fill in <font color="#008000">int</font> as the variable type</P>
<li><P> Fill in <font color="#008000">m</font><font color="#008000"><U>_</U></font><font color="#008000">NumLines</font> as the variable declaration</P>
</ol>
<P>Variables associated with a document are initialized in <font color="#008000">OnNewDocument()</font>. In ClassView, expand CScrollDoc, then double-click <font color="#008000">OnNewDocument()</font> to expand it. Replace the TODO comments with this line
of code:</P>
<pre><font color="#008000"> m_NumLines = 5;</font></pre>
<P>To arrange for this variable to be saved with the document and restored when the document is loaded, you must serialize it. Edit <font color="#008000">CScrollDoc::Serialize()</font> as shown in Listing 6.9.</P>
<P><I>Listing 6.9—CScrollDoc::Serialize()</I></P>
<pre><font color="#008000">void CScrollDoc::Serialize(CArchive& ar)</font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> if (ar.IsStoring())</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> ar << m_NumLines;</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> else</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> ar >> m_NumLines;</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000">}</font></pre>
<P>Now all you need to do is use <font color="#008000">m_NumLines</font> to draw the appropriate number of lines. Expand the view class, <font color="#008000">CMyScrollView</font>, in ClassView, then double-click <font color="#008000">OnDraw()</font>.
Edit it until it is the same as Listing 6.10. This is very similar to the <font color="#008000">ShowFonts()</font> code from the Paint1 application earlier in this chapter.</P>
<P><I>Listing 6.10 CMyScrollView::OnDraw()</I></P>
<pre><font color="#008000">void CMyScrollView::OnDraw(CDC* pDC)</font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> CScrollDoc* pDoc = GetDocument();</font></pre>
<pre><font color="#008000"> ASSERT_VALID(pDoc);</font></pre>
<pre><font color="#008000"> // get the number of lines from the document</font></pre>
<pre><font color="#008000"> int numLines = pDoc->m_NumLines;</font></pre>
<pre><font color="#008000"> // Initialize a LOGFONT structure for the fonts.</font></pre>
<pre><font color="#008000"> LOGFONT logFont;</font></pre>
<pre><font color="#008000"> logFont.lfHeight = 24;</font></pre>
<pre><font color="#008000"> logFont.lfWidth = 0;</font></pre>
<pre><font color="#008000"> logFont.lfEscapement = 0;</font></pre>
<pre><font color="#008000"> logFont.lfOrientation = 0;</font></pre>
<pre><font color="#008000"> logFont.lfWeight = FW_NORMAL;</font></pre>
<pre><font color="#008000"> logFont.lfItalic = 0;</font></pre>
<pre><font color="#008000"> logFont.lfUnderline = 0;</font></pre>
<pre><font color="#008000"> logFont.lfStrikeOut = 0;</font></pre>
<pre><font color="#008000"> logFont.lfCharSet = ANSI_CHARSET;</font></pre>
<pre><font color="#008000"> logFont.lfOutPrecision = OUT_DEFAULT_PRECIS;</font></pre>
<pre><font color="#008000"> logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;</font></pre>
<pre><font color="#008000"> logFont.lfQuality = PROOF_QUALITY;</font></pre>></P>
<pre><font color="#008000"> logFont.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;</font></pre>
<pre><font color="#008000"> strcpy(logFont.lfFaceName, "Times New Roman");</font></pre>
<pre><font color="#008000"> // Create a new font and select it into the DC.</font></pre>
<pre><font color="#008000"> CFont* font = new CFont();</font></pre>
<pre><font color="#008000"> font->CreateFontIndirect(&logFont);</font></pre>
<pre><font color="#008000"> CFont* oldFont = pDC->SelectObject(font);</font></pre>
<pre><font color="#008000"> // Initialize the position of text in the window.</font></pre>
<pre><font color="#008000"> UINT position = 0;</font></pre>
<pre><font color="#008000"> // Create and display eight example lines.</font></pre>
<pre><font color="#008000"> for (int x=0; x<numLines; ++x)</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> // Create the string to display.</font></pre>
<pre><font color="#008000"> char s[25];</font></pre>
<pre><font color="#008000"> wsprintf(s, "This is line #%d", x+1);</font></pre>
<pre><font color="#008000"> // Print text with the new font.</font></pre>
<pre><font color="#008000"> pDC->TextOut(20, position, s);</font></pre>
<pre><font color="#008000"> position += logFont.lfHeight;</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> // Restore the old font to the DC, and</font></pre>
<pre><font color="#008000"> // delete the font the program created.</font></pre>
<pre><font color="#008000"> pDC->SelectObject(oldFont);</font></pre>
<pre><font color="#008000"> delete font;</font></pre>
<pre><font color="#008000">}</font></pre>
<P>Build and run the Scroll application, and you should see a display like Figure 6.9. There are no scroll bars, because all the lines fit in the window.</P>
<A HREF="Hfig09.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch06/Hfig09.gif"><b>Fig. 6.9</b></A>
<P><I>At first, the Scroll application displays five lines of text and no </I><I>scroll bars.</I></P>
<P>To increase the number of lines whenever the user clicks the window, you need to add a message handler to handle left mouse clicks, then write the code for the handler. Right-click <I>CMyScrollView</I> in ClassView, and choose Add Windows Message
Handler. Double-click <font color="#008000">WM_LBUTTONDOWN</font> to add a handler, then click the Edit Existing button to change the code. Listing 6.11 shows the completed handler: it simply increases the number of lines, then calls <font
color="#008000">Invalidate()</font> to force a redraw. Like so many message handlers, it finishes by passing the work on to the base class version of this function.</P>
<P><I>Listing 6.11 CMyScrollView::OnLButtonDown()</I></P>
<pre><font color="#008000">void CMyScrollView::OnLButtonDown(UINT nFlags, CPoint point) </font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> CScrollDoc* pDoc = GetDocument();</font></pre>
<pre><font color="#008000"> ASSERT_VALID(pDoc);</font></pre>
<pre><font color="#008000"> // Increase number of lines to display.</font></pre>
<pre><font color="#008000"> pDoc->m_NumLines += 5;</font></pre>
<pre><font color="#008000"> // Redraw the window.</font></pre>
<pre><font color="#008000"> Invalidate();</font></pre>
<pre><font color="#008000"> CScrollView::OnLButtonDown(nFlags, point);</font></pre>
<pre><font color="#008000">}</font></pre>
<P>So that you can watch scroll bars disappear as well as appear, why not implement a way for the user to decrease the number of lines in the window? If left-clicking increase the number of lines, it makes sense that right-clicking would decrease it. Add
a handler for <font color="#008000">WM_RBUTTONDOWN</font> just as you did for <font color="#008000">WM_LBUTTONDOWN</font>, and edit it until it is just like Listing 6.12. This function is a little more complicated, because it ensures that the number of
lines is never negative.</P>
<P><I>Listing 6.12 CMyScrollView::OnRButtonDown()</I></P>
<pre><font color="#008000">void CMyScrollView::OnRButtonDown(UINT nFlags, CPoint point) </font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> CScrollDoc* pDoc = GetDocument();</font></pre>
<pre><font color="#008000"> ASSERT_VALID(pDoc);</font></pre>
<pre><font color="#008000"> // Decrease number of lines to display.</font></pre>
<pre><font color="#008000"> pDoc->m_NumLines -= 5;</font></pre>
<pre><font color="#008000"> if (pDoc->m_NumLines < 0)</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> pDoc->m_NumLines = 0;</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> // Redraw the window.</font></pre>
<pre><font color="#008000"> Invalidate();</font></pre>
<pre><font color="#008000"> CScrollView::OnRButtonDown(nFlags, point);</font></pre>
<pre><font color="#008000">}</font></pre>
<P>If you build and run Scroll now, and click the window, you can increase the number of lines, but scroll bars do not appear. You need to add some lines to <font color="#008000">OnDraw()</font> to make that happen. Before you do, it would be a good idea
to review the way that scroll bars work. There are three places that you can click on a vertical scroll bar: the <I>thumb</I> (some people call it the elevator), above the thumb, or below it. Clicking the thumb does nothing, but you can click and hold to
drag it up or down. Clicking above it moves you one page (screenful) up within the data. Clicking below it moves you one page down. What’s more, the size of the thumb is a visual representation of the size of a page in proportion to the entire
document. Clicking the up arrow at the top of the scroll bar moves you up one line in the document, and clicking the down arrow at the bottom moves you down one line.</P>
<P>What all this means is that the code that draws the scroll bar and handles the clicks needs to know the size of the entire document, the size of a page, and the size of a line. You don’t have to write code to draw scroll bars, or code to handle
clicks on the scroll bar, but you do have to pass along some information about the size of the document and the current view. The lines of code you need to add to <font color="#008000">OnDraw()</font> are in Listing 6.13; add them after the for loop and
before the old font is selected back into the DC.</P>
<P><I>Listing 6.12 Lines to add to OnDraw()</I></P>
<pre><font color="#008000"> // Calculate the document size.</font></pre>
<pre><font color="#008000"> CSize docSize(100, numLines*logFont.lfHeight);</font></pre>
<pre><font color="#008000"> // Calculate the page size.</font></pre>
<pre><font color="#008000"> CRect rect;</font></pre>
<pre><font color="#008000"> GetClientRect(&rect);</font></pre>
<pre><font color="#008000"> CSize pageSize(rect.right, rect.bottom);</font></pre>
<pre><font color="#008000"> // Calculate the line size.</font></pre>
<pre><font color="#008000"> CSize lineSize(0, logFont.lfHeight);</font></pre>
<pre><font color="#008000"> // Adjust the scrollers.</font></pre>
<pre><font color="#008000"> SetScrollSizes(MM_TEXT, docSize, pageSize, lineSize);</font></pre>
<P>This new code must determine the document, page, and line sizes. The document size is the width and height of the screen area that could hold the entire document. This is calculated using the number of lines in the entire document, and the height of a
line. (<font color="#008000">CSize</font> is an MFC class that was created especially for storing the widths and heights of objects.) The page size is simply the size of the client rectangle of this view, and the line size is the height of the font. By
se
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -