![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
To access the contents, click the chapter and section titles.
Fast Track Visual C++ 6.0 Programming
Now weve stored the characters the user has typed. The next step is to display them in OnDraw(). Displaying Text in MDIIn the OnDraw() function, we display the text in the text[] array. First, we set up a loop over all the lines in the text[] array. void CMDIView::OnDraw(CDC* pDC) { CMDIDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); for(int loop_index = 0; loop_index <= pDoc->number_lines; loop_index++){ ⇐ . . . } ⇐ } To display multiline text, we need to determine how high each line is on the screen, and we do that with a TEXTMETRIC structure. The tmHeight member of that structure indicates how high each line of text is in the current font. We set up the TEXTMETRIC structure for the current device context as follows: void CMDIView::OnDraw(CDC* pDC) { CMDIDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); TEXTMETRIC tm; ⇐ pDC->GetTextMetrics(&tm); ⇐ for(int loop_index = 0; loop_index <= pDoc->number_lines; loop_index++){ . . . } } We can loop over the text lines, displaying each line in its correct screen position, as shown in the following example: void CMDIView::OnDraw(CDC* pDC) { CMDIDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); TEXTMETRIC tm; pDC->GetTextMetrics(&tm); for(int loop_index = 0; loop_index <= pDoc->number_lines; loop_index++){ pDC->TextOut(0, loop_index * tm.tmHeight, pDoc->text[loop_index]); ⇐ } } Run the program now, as shown in Figure 2.2. As you type text, such as This is the text, one word per line, that text appears in the documents MDI child window. Open a new view into the document now using the New Window item in the Window menu. Our text, This is the text, appears in the second view as well as the first. However, if you type additional text into the second view, that text appears in the second view only. Although the text is being stored in the document, the first view is not updated as we type, which is a problem. Its time to fix this problem, which we do by coordinating the views. Coordinating MDI ViewsYou can coordinate views by updating them with the UpdateAllViews() function. This function takes three arguments: a pointer to the view doing the updating (so it is not updated); a long value, which is called a hint; and a pointer to an object, which is also part of that hint. We see how to use hints in a moment, but for now, set these last two parameters to 0. Heres how we use UpdateAllViews(): void CMDIView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { CMDIDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if(nChar != '\r'){ pDoc->text[pDoc->number_lines] += nChar; Invalidate(); } else{ pDoc->number_lines++; } pDoc->UpdateAllViews(this, 0L, NULL); ⇐ CView::OnChar(nChar, nRepCnt, nFlags); }
With the preceding code, all the views connected to this document are updated when the user types anything. To update all the views, the document calls each views OnUpdate() function, and by default, that function simply calls the views OnDraw() function. This means that we can type into either view and the other one will be automatically updated, as shown in Figure 2.3. Each time a view is updated this way, however, the entire view is redrawn. Theres a more efficient way of doing things: making use of hints. Using View HintsYou may recall that the UpdateAllViews() function takes two hint parameters: a long integer and a pointer. Using hints, you can indicate to the other views exactly what part of the view needs to be updated. For example, the pointer can point to a data object that holds the new data.
By using hints in our MDI program, we can pass the line number thats been modified to the other views, and they can redisplay only that line. This is of minimal importance if youre only displaying a few lines of text, but if you have a 1000-line document, you shouldnt redraw the whole document each time the user types a new key. To pass the number of the modified line to other views, then, we convert that number to a long integer and pass it to UpdateAllViews(). void CMDIView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { CMDIDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if(nChar != '\r'){ pDoc->text[pDoc->number_lines] += nChar; Invalidate(); } else{ pDoc->number_lines++; } pDoc->UpdateAllViews(this, (long) pDoc->number_lines, NULL); ⇐ CView::OnChar(nChar, nRepCnt, nFlags); } Now we can make use of that hint in other views, and we do that in the OnUpdate() function. Using OnUpdate() in MDI ProgramsTo decipher the hint were passing to other views, we use ClassWizard to override the OnUpdate() function. void CMDIView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { // TODO: Add your specialized code here and/or call the base class } In this case, we want to redraw the line whose number is passed to us in the lHint parameter. To do that, we first need a device context for this view, and we get that with the CClientDC class. void CMDIView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { CClientDC dc(this); ⇐ . . . } To accurately place the line on the screen, we need to know the lines height, and we get that with a TEXTMETRIC structure. We set up a pointer to the document so we can read the lines new text as follows: void CMDIView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { CClientDC dc(this); TEXTMETRIC tm; ⇐ CMDIDoc* pDoc = GetDocument(); ⇐ ASSERT_VALID(pDoc); ⇐ dc.GetTextMetrics(&tm); ⇐ . . . } Now we simply redisplay the line referred to by the hintand only that linethis way: void CMDIView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { CClientDC dc(this); TEXTMETRIC tm; CMDIDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); dc.GetTextMetrics(&tm); dc.TextOut(0, (int) lHint * tm.tmHeight, pDoc->text[lHint]); ⇐ }
|
![]() |
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement. |