Click Here!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
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

Bookmark It

Search this book:
 
Previous Table of Contents Next


How MDI Programs Work

In the last chapter, the KeysSDI program supported the SDI interface and used the CSingleDocTemplate class to set up its document template.

BOOL CKeysSDIApp::InitInstance()

{
        .
        .
        .
    CSingleDocTemplate* pDocTemplate;
    pDocTemplate = new CSingleDocTemplate(
        IDR_MAINFRAME,
        RUNTIME_CLASS(CKeysSDIDoc),                                 ⇐
        RUNTIME_CLASS(CMainFrame),       // main SDI frame window   ⇐
        RUNTIME_CLASS(CKeysSDIView));                               ⇐
    AddDocTemplate(pDocTemplate);
        .
        .
        .

Each time you open the program, a new window, document, and view are created. If you select New in the File menu, the document is erased and reused—you can only have one document.

It’s different in our MDI program. Here, the document template is based on the CMultiDocTemplate class. In addition, the main window class is not the CMainFrame class that we used in SDI programming. In the MDI program, we use the MDI child window class, CChildFrame, as the document’s window class.

BOOL CMDIApp::InitInstance()

{
        .
        .
        .
    CMultiDocTemplate* pDocTemplate;                          
    pDocTemplate = new CMultiDocTemplate(              
        IDR_MDITYPE,
        RUNTIME_CLASS(CMDIDoc),                                  ⇐
        RUNTIME_CLASS(CChildFrame), // custom MDI child frame    ⇐
        RUNTIME_CLASS(CMDIView));                                ⇐
    AddDocTemplate(pDocTemplate);
        .
        .
        .

In this program, every time we open a new document, a new document and view are created that are connected to an MDI child window, which then appears in the MDI main frame window. If you want to use a different view class, this is the place to do it. In fact, we do just that later in this chapter when we learn how to support multiple view classes in the same program.

The rest of the InitInstance() function creates a new MDI frame window and displays it as shown in the following example (a default document already appears in its own child window in the new MDI frame window; later in this book, we open our own documents when the program first loads instead of default documents):

BOOL CMDIApp::InitInstance()

{
        .
        .
        .
    CMultiDocTemplate* pDocTemplate;                          
    pDocTemplate = new CMultiDocTemplate(              
        IDR_MDITYPE,
        RUNTIME_CLASS(CMDIDoc),                          
        RUNTIME_CLASS(CChildFrame), // custom MDI child frame      
        RUNTIME_CLASS(CMDIView));                          
    AddDocTemplate(pDocTemplate);

    // create main MDI Frame window
    CMainFrame* pMainFrame = new CMainFrame;
    if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
        return FALSE;
    m_pMainWnd = pMainFrame;

    // Parse command line for standard shell commands, DDE, file open
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);

    // Dispatch commands specified on the command line
    if (!ProcessShellCommand(cmdInfo))
        return FALSE;

    // The main window has been initialized, so show and update it.
    pMainFrame->ShowWindow(m_nCmdShow);
    pMainFrame->UpdateWindow();

    return TRUE;

}


Multiple MDI Window Programs

Nothing is stopping you from creating and registering a second document template in MDI programs. You can follow the same initialization steps in InitInstance() to display two different types of MDI frame windows, each with its own child windows, in your program. This is useful if your program is extensive and you want to organize documents not only in child windows in the same MDI frame window, but in different MDI frame windows altogether.


Now that we’ve caught a glimpse behind the scenes in MDI programming, let’s continue with our own MDI program.

Handling Data in the MDI Program

This program, MDI, will let the user type into a document and enter multiple lines of text, so we need to write the code to support that process first. In this example, we make things easy for ourselves by storing each line of text in its own CString object, and we set aside those strings in an array of CString objects named text[]. In addition, we need to keep track of the current number of lines in the document so we know where to enter new text as the user types it; we can create an integer variable named number_lines for that. Here, we allow for a maximum of 1000 lines of text:

const MAX_LINES = 1000;                  ⇐


class CMDIDoc : public CDocument
{
protected: // create from serialization only
    CMDIDoc();
    DECLARE_DYNCREATE(CMDIDoc)
// Attributes
public:
    int number_lines;                    ⇐

    CString text[MAX_LINES];             ⇐

In addition, we can initialize number_lines to 0 in the document’s constructor. CString objects are initialized to the empty string, so we don’t initialize the CString array in this case.

CMDIDoc::CMDIDoc()

{
    // TODO: add one-time construction code here
    number_lines = 0;                    ⇐

}

Next, we read keys as they’re typed by the user.

Reading Keys in MDI

We read keys by adding an OnChar() message handler with ClassWizard.

void CMDIView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)

{
    // TODO: Add your message handler code here and/or call default
  
    CView::OnChar(nChar, nRepCnt, nFlags);

}

We can add keys to the current string of text as we did in our KeysSDI program in the last chapter, but there’s a difference because here we’re handling multiline text, which means we have to watch for the Enter key. If the user types the Enter key, we have to skip to the next line of text. We start by storing simple characters; we first make sure the typed character is not the Enter key.

void CMDIView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)

{
    if(nChar != '\r'){                                 ⇐
        .
        .
        .
    }                                                  ⇐
  
    CView::OnChar(nChar, nRepCnt, nFlags);

}

Next, we store the character the user has typed in the current line of text and invalidate the view to redisplay it.

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();                                  ⇐
    }
  
    CView::OnChar(nChar, nRepCnt, nFlags);

}

If, on the other hand, the user did press the Enter key, we skip to the next line of text by incrementing number_lines.

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++;                            ⇐
    }
  
    CView::OnChar(nChar, nRepCnt, nFlags);

}


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.