Brief Full Advanced Search Search Tips
|  |  | To access the contents, click the chapter and section titles. Fast Track Visual C++ 6.0 Programming (Publisher: John Wiley & Sons, Inc.) Author(s): Steve Holzner ISBN: 0471312908 Publication Date: 09/01/98 Search this book:
Previous | Table of Contents | Next
#### Registering Editor’s Files with Windows Registering our file type with Windows is easy: We use EnableShellOpen() and RegisterShellFileTypes() in Editor.cpp’s InitInstance() function after we’ve registered our document template.
        CMultiDocTemplate* pDocTemplate;
        pDocTemplate = new CMultiDocTemplate(
            IDR_EDITORTYPE,
            RUNTIME_CLASS(CEditorDoc),
            RUNTIME_CLASS(CChildFrame), // custom MDI child frame
            RUNTIME_CLASS(CEditorView));
        AddDocTemplate(pDocTemplate);

        EnableShellOpen();                  ⇐
        RegisterShellFileTypes();           ⇐
Now, when the user clicks a file with the .ed extension, that file opens in the Editor application. The Editor Icon The icon used for .ed files will be IDR_MAINFRAME, and you can edit that icon by opening it in the Icon Editor by clicking it in the ResourceView’s icon folder. We’ve completed our data storage work in Editor for the moment, so let’s now turn to the view. Our first step is to add a caret to a view. #### Adding a Caret to a View We’re letting the user click the mouse in various locations in the view and then type text at the chosen location. That process is much easier if we place a caret—a flashing insertion point—into the view. Some views, such as CEditView, come with a caret already supported, but the standard CView class does not. However, we can create our own cursor with the device context CreateSolidCaret() function, and we do that in OnDraw() because we are passed a pointer to the view’s device context in that function. We start by creating a new flag in the view class, m_CaretFlag. If this flag is true, the caret already has been created and installed; if false, it has not. If the caret has not been created yet, we create it; when we do, we need to tailor it to the size of the characters in the view, so we fill a TEXTMETRIC structure.
    void CEditorView::OnDraw(CDC* pDC)
    {
        if(!m_CaretFlag){
         TEXTMETRIC textmetric;

         pDC->GetTextMetrics(&textmetric);
             .
             .
             .
        }
    }
Next, we create the caret with CreateSolidCaret(), making it a quarter character wide and a full character tall.
    void CEditorView::OnDraw(CDC* pDC)
    {
        if(!m_CaretFlag){
         TEXTMETRIC textmetric;

         pDC->GetTextMetrics(&textmetric);

         CreateSolidCaret(textmetric.tmAveCharWidth/4, textmetric.tmHeight);
            .
            .
            .
        }
    }
We keep track of the caret in a new CPoint object that we add to the view (a CPoint object has two data members, x and y), then use SetCaretPos() to set the caret position to (0, 0), and ShowCaret() to show the blinking caret.
    void CEditorView::OnDraw(CDC* pDC)
    {
        if(!m_CaretFlag){
         TEXTMETRIC textmetric;

         pDC->GetTextMetrics(&textmetric);
         CreateSolidCaret(textmetric.tmAveCharWidth/4, textmetric.tmHeight);
         caret.x = caret.y = 0;                  ⇐

         SetCaretPos(caret);                     ⇐

         ShowCaret();                            ⇐

         m_CaretFlag = true;                     ⇐
        }
    }
Now our caret is installed. If characters need to be displayed, we do so using TextOut().
    void CEditorView::OnDraw(CDC* pDC)
    {
        if(!m_CaretFlag){
         TEXTMETRIC textmetric;

         pDC->GetTextMetrics(&textmetric);

         CreateSolidCaret(textmetric.tmAveCharWidth/4, textmetric.tmHeight);
         caret.x = caret.y = 0;

         SetCaretPos(caret);

         ShowCaret();

         m_CaretFlag = true;
        }

        CEditorDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);

        CString out_string(pDoc->m_data.GetText());                          ⇐

        pDC->TextOut(pDoc->m_data.GetX(), pDoc->m_data.GetY(), out_string);  ⇐
          .
          .
          .

    }
Finally, we have to make sure the blinking caret appears at the end of the string of text in the view. #### Updating the Caret’s Position To move the caret to the end of the text string on the screen, we can use the device context function GetTextExtent() to determine how long our string is. Before moving the caret, we first hide it, then find its new position, set the caret to that position, and show the caret again.
    void CEditorView::OnDraw(CDC* pDC)
    {
        if(!m_CaretFlag){
         .
         .
         .
        }

        CEditorDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);

        CString out_string(pDoc->m_data.GetText());

        pDC->TextOut(pDoc->m_data.GetX(), pDoc->m_data.GetY(), out_string);

        HideCaret();                                      ⇐

        caret.x = pDoc->m_data.GetX() + (pDC->GetTextExtent(pDoc-
    >m_data.GetText())).cx;                               ⇐
        caret.y = pDoc->m_data.GetY();                    ⇐

        SetCaretPos(caret);                               ⇐

        ShowCaret();                                      ⇐
    }
Our process is now complete and our program now supports a caret insertion point, as shown in Figure 5.1. Our next step is to add mouse support. Moving the Caret If you don’t hide the caret before moving it, you often leave behind its image on the screen. Figure 5.1 Supporting a caret. #### Adding Mouse Support When the user clicks the view, we want to move the insertion point to the mouse location to allow the user to enter text there, so we need to add OnLButtonDown() to the view class.
    void CEditorView::OnLButtonDown(UINT nFlags, CPoint point)
    {
        // TODO: Add your message handler code here and/or call default
    }
We start OnLButtonDown() by hiding the caret and updating its position.
    void CEditorView::OnLButtonDown(UINT nFlags, CPoint point)
    {
        HideCaret();

        CEditorDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);

        pDoc->m_data.SetX(point.x);                  ⇐
        caret.x = point.x;                           ⇐
        pDoc->m_data.SetY(point.y);                  ⇐
        caret.y = point.y;                           ⇐
    }
Next, we show the caret again, clear the text, invalidate the screen, and set the modified flag.
    void CEditorView::OnLButtonDown(UINT nFlags, CPoint point)
    {
        HideCaret();

        CEditorDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);

        pDoc->m_data.SetX(point.x);
        caret.x = point.x;
        pDoc->m_data.SetY(point.y);
        caret.y = point.y;

        ShowCaret();                         ⇐

        pDoc->m_data.SetText(””);            ⇐

        Invalidate();                        ⇐

        pDoc->SetModifiedFlag(true);         ⇐

        pDoc->UpdateAllViews(this);          ⇐
        CView::OnLButtonDown(nFlags, point);
    }
Now the Editor program lets the user click the mouse in the view and move the insertion point, as we see in Figure 5.2. To indicate that the view accepts text input, we can change its default cursor (the caret indicates text input, and the cursor indicates mouse input) from the default arrow cursor to an I-beam cursor, which is a more standard cursor with text entry.
Previous | Table of Contents | Next

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