Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Simple MDI application using Managed c++ classes.

0.00/5 (No votes)
27 Sep 2002 2  
An article to explain how to write simple MDI application using managed c++ classes.

Introduction

In the world of MFC programming it is very easy to start writing an MDI application. But there is no such AppWizard available to write MDI applications using Managed C++ classes. In this article I have explained how to write a simple MDI application using managed C++ classes. I have tried to write this application similar to MFC document-view architecture application.

Screenshot

Managed c++ MDI Application.

Start

Create a "Managed C++ Application" project using Visual Studio .NET "New Project" wizard. This will create a blank project with only main() function written. Include following common header lines to stdafx.h file.

#using <mscorlib.dll>
#using <System.dll>
#using <System.Windows.Forms.dll>
#using <System.Drawing.dll>

#using namespace System::Windows::Forms;
#using namespace System::ComponentModel;
#using namespace System::Drawing;
#using namespace System::IO;
#using namespace System;

Right click on the project name in workspace window and select Add->Add class. Add following classes to the project as we see how they work. Please refer source code for definition of these classes.

The Application class : CTextPadApp

InitInstance method of this class calls Application::Run() function to start the main frame window (of class CTextPadFrame). Please refer TextPadApp.h for definition of this class.

bool CTextPadApp::InitInstance()
{
    ...    
    m_MainFrame = new CTextPadFrame();
    m_MainFrame->Create();
    
    Application::Run(m_MainFrame);
    ...
}

The Main frame class : CTextPadFrame

This class represents the MDI main frame window of our application. CTextPadFrame is derived from .NET framework's System::Windows::Forms::Form class which gives basic windows functionality to the class. The main frame window class contains the array of documents System::Collections::ArrayList* m_DocArray, created and managed by it's member functions. The Create() function sets properties of the main frame window and also creates menu and a document-view pair.

//set main frame window properties

IsMdiContainer = true;
Text    = S"TextPad";
Visible = true;
...

IsMdiContainer = true; makes this window the MDI parent frame window.

//This function creates document and a view/window associated with it. 

CTextPadDoc* CTextPadFrame::CreateDocument(void)
{
    //create a document and a view associated with each other

    //create the doc and then pass it's pointer to the view.

    try
    {
        m_TextPadDoc    =    new CTextPadDoc();
        if(m_TextPadDoc)
        {
            m_DocArray->Add(m_TextPadDoc);
            CTextPadDoc::iDocs++;
        }
        else
            return 0;
        
        m_TextPadView = new CTextPadView(m_TextPadDoc);
        if(m_TextPadView)
        {
            if(! (m_TextPadView->Create(this)) )
            {
                MessageBox::Show("Error creating window.");
                return 0;
            }
        }
        else
            return 0;

        m_TextPadDoc->SetView(m_TextPadView);
        String *strTitle = new String("Default.txt");
        m_TextPadView->SetViewTitle(strTitle);
        return m_TextPadDoc;    
    }

    catch(Exception *x)
    {
        MessageBox::Show(x->ToString());
        return 0;
    }
    
}

The CreateDocument() function actually allocates instances of the document and view class. Document and view contain pointers to each other as their member variables.

Menu handlers

As there is only one menu for view and the main frame, all menu handlers are written in main frame window class CTextPadFrame. Managed C++ uses delegates for handling events.

//CTextPadFrame declares following event handlers

void OnNewDocument(Object *pSender,EventArgs* pArgs);
void OnFileSaveDocument(Object *pSender,EventArgs* pArgs);
void OnFileOpenDocument(Object *pSender,EventArgs* pArgs);
void OnExit(Object *pSender,EventArgs* pArgs);
void OnHelpAbout(Object *pSender,EventArgs* pArgs);


//In CTextPadFrane::Create function we assign pointer to the handler 

//function to delegates defined in the menu class.


m_FileMenu->MenuItems->Add(m_FileNewMenu);
m_FileNewMenu->Click += new EventHandler(this,&CTextPadFrame::OnNewDocument);
m_FileMenu->MenuItems->Add(m_FileOpenMenu);
m_FileOpenMenu->Click += new EventHandler(this,&CTextPadFrame::OnFileOpenDocument);
m_FileMenu->MenuItems->Add(m_FileSaveMenu);
m_FileSaveMenu->Click += new EventHandler(this,&CTextPadFrame::OnFileSaveDocument);
m_FileMenu->MenuItems->Add(m_FileExitMenu);
m_FileExitMenu->Click += new EventHandler(this,&CTextPadFrame::OnExit);

The View class : CTextPadView

This class represents the view or child window of our MDI application and is derived from System::Windows::Forms::Form class. CTextPadFrame::CreateDocument() function calls Create() function of this class to create and initialize the child window. CTextPadView::Create() receives pointer to the main frame window as a parameter. MdiParent = ParentWnd; statement makes this view window a MDI child window.

bool CTextPadView::Create(Form *ParentWnd)
{
    ...
    ...
    MdiParent = ParentWnd;
    
    //shows the window

    Show();
        
    //create the text control

    m_TextBox = new TextBox();
    if(m_TextBox)
    {
        m_TextBox->Multiline   = true;
        m_TextBox->ScrollBars  = ScrollBars::Both;
        m_TextBox->Font        = new System::Drawing::Font( 
                                 new FontFamily( S"Times New Roman"), 10.0f );
        m_TextBox->Dock        = DockStyle::Fill;
        Controls->Add(m_TextBox);    
    }
    ...
    ...                
    return true;
}

The child window contains the TextBox control and m_TextBox->Dock = DockStyle::Fill changes TextBox size to always fill the client area.

The Document class : CTextPadDoc

The document class does the crucial work of opening and saving files. It has OpenDocument() and SaveDocuments() functions which are called by menu handlers of main frame window. It uses :

* FileStream class to open a file for reading or writing.
* StreamReader to read String (text) from an opened file and
* StreamWriter to write String to opened file.
//Read a file

StreamReader *sReader    = new StreamReader(fileStream);
if(sReader)
{
    m_strTextData = sReader->ReadToEnd();
        
    sReader->Close();
    fileStream->Close();
            
    m_AssociatedView->SetTextToTextBox(m_strTextData);
    bIsDirtyFileName = false;
}
//code to write to a file

StreamWriter *sWriter    = new StreamWriter(fileStream);
if(sWriter)
{
    String *strViewText=m_AssociatedView->GetTextFromTextBox();
                
    if(strViewText != 0)
        sWriter->Write(strViewText);
                
    sWriter->Close();
    fileStream->Close();
}

m_AssociatedView->SetTextToTextBox(m_strTextData) and m_AssociatedView->GetTextFromTextBox() functions set or get text from the text-box contained in the view window.

Build

Add few lines to your main() function as shown below.

// This is the entry point for this application

#ifdef _UNICODE
    int wmain(void)
#else
    int WinMain()
#endif
{
    CTextPadApp *theApp= new CTextPadApp();
    bool bAppInit=theApp->InitInstance();

    return 0;
}

That's it! Build and run the application.

Conclusion

It's very easy to write MFC document-view like application using managed c++ classes. If we follow some structured way of writing applications we can write more complex MDI applications using managed C++ classes.

Please feel free to write me on this article.

Hrishikesh Lele

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here