Building an MDI Interface with Windows Forms


Many traditional desktop applications that deal with documents provide a multiple document interface (MDI) to allow the user to work with multiple documents simultaneously. The MDI interface is implemented in MFC using the CMDIFrameWnd and CMDIChildWnd classes. Using Windows Forms, all the functionality for all window types, including the MDI frame window and child windows, is provided in the System::Windows::Forms::Form class.

Creating an MDI interface with Windows Forms starts with the same steps you followed to create the SimpleWindowsForm in the previous section. Start by creating a C++ managed application named MDIWindowsForms and copy the code from Listing 7.3 into the new MDIWindowsForms.cpp file. As was mentioned before, the class declaration needs to be inserted above your _tmain function. In order to avoid any confusion, you should rename the class and its constructor and destructor from SimpleWindowsForm to MDIWindowsFrame. This application will also use the same namespaces as the SimpleWindowsForm project, so add the appropriate #using statements to import the DLLs and reference the same namespaces with the using keyword. As you did in the SimpleWindowsForm project, insert the code to launch your Windows Form from the _tmain function.

In order for a Windows Form to become an MDI frame window, you must set a single property, IsMdiContainer, in the Form class to True. Once that property is set in the InitForm() method, the Windows Form acts as an MDI frame window or container for MDI child windows. Your MDIForms.cpp file should be similar to Listing 7.6.

Listing 7.6 Creating the Skeleton Code for an MDI Windows Form
 1: // This is the main project file for VC++ application project  2: // generated using an Application Wizard.  3:  4: #include "stdafx.h"  5:  6: #using <mscorlib.dll>  7: #include <tchar.h>  8: #include <windows.h>  9: 10: #using <System.DLL> 11: #using <System.Drawing.DLL> 12: #using <System.Windows.Forms.DLL> 13: 14: using namespace System; 15: using namespace System::Drawing; 16: using namespace System::Windows::Forms; 17: 18: __gc class MDIWindowFrame : public Form 19: { 20: protected: 21:   void InitForm(); 22: 23: public: 24:   MDIWindowFrame (); 25:   virtual ~MDIWindowFrame () {} 26: }; 27: 28: MDIWindowFrame::MDIWindowFrame () 29: { 30:   // Initialize the Windows Form 31:   InitForm (); 32: } 33: 34: void MDIWindowFrame::InitForm() 35: { 36:    // Initialize Form attributes 37:    Size = System::Drawing::Size(200, 110); 38:    Text = "MDI Window Frame"; 39: 40:    // this form will be a MDI window 41:    IsMdiContainer = true; 42: } 43: 44: // This is the entry point for this application 45: int _tmain(void) 46: { 47:    Application::Run( new MDIWindowFrame() ); 48:    return 0; 49: } 

Creating a MDI Child Window

For the purposes of this example, there is only one type of MDI child window. The MDI child window is a window with a rich-text edit control and appears as a simple text editor window. Adding all the features that would normally go into such an application is beyond the scope of this hour's lesson. However, you will understand how to create an MDI child window.

To create the MDI child window, you will have to create another class for it. As with the other Windows Forms in this hour, the MDI child window form starts with the same basic class shown in Listing 7.3. Change the class name from SimpleWindowsForm to MDIChildForm throughout the class definition, making sure you change the constructor and destructor names also.

Add a protected declaration for a System::Windows::Forms::RichTextBox object pointer named m_pRichTextBox to the class definition. In the InitForm() method, this member pointer is assigned to a new RichTextBox object and then initialized, as shown in Listing 7.7.

Listing 7.7 The InitForm() Method for the MDIChildForm Class
 1: void MDIChildForm::InitForm()  2: {  3:    m_pRichTextBox = new System::Windows::Forms::RichTextBox;  4:  5:    m_pRichTextBox->Anchor =  (AnchorStyles)  6:                              (AnchorStyles::Top |  7:                              AnchorStyles::Bottom |  8:                              AnchorStyles::Left |  9:                              AnchorStyles::Right ); 10: 11:    m_pRichTextBox->Name = "RichTextBox"; 12:    m_pRichTextBox->Size = get_ClientSize(); 13: 14:    m_pRichTextBox->TabIndex = 0; 15: 16:    Controls->Add( m_pRichTextBox ); 17: 18:    // Initialize Form attributes 19:    Text = "Untitled"; 20: } 

This form takes advantage of a nice feature of Windows Forms the ability to anchor controls to one or more sides of a sizeable window. This allows you to write forms that are sizeable and maintain orderly control layout. The size of the control is initially set to the client size of the form and then anchored so that as the client area is sized, the control is sized to match.

Once the new control object is added to the form, it is complete and ready to use as an MDI child window. Because most MDI applications create a single child window when they are launched, this application will do the same.

In order to create the child window, you must first declare and create an instance of the MDIChildForm class you created earlier. Once this has been done, you have to associate the parent window (MDIWindowFrame) with this new child to ensure proper communication between the two windows. MDIChildForm, because it derives from the Form class, contains a member variable called MdiParent, which is used to make this association. MdiParent in this case is your main MDIWindowFrame class instance, referenced through something called the this pointer. Once that association has been made, you call the Show function provided by the Form base class for your child window. Listing 7.8 demonstrates how to create, associate with a parent window, and show the initial MDI child window.

Listing 7.8 Revised InitForm Method to Display an Initial MDI Child Window
void MDIWindowsFrame::InitForm() {     AutoScaleBaseSize = System::Drawing::Size(5, 13);     ClientSize = System::Drawing::Size(292, 273);     // Add the MDI client area control to the form     Controls->Add( new System::Windows::Forms::MdiClient );     MDIChildForm* pChild = new MDIChildForm;     pChild->MdiParent = this;     pChild->Show();     // this form will be a MDI window     IsMdiContainer = true; } 

Compile your project now and run it. If everything is working correctly, you should see the main window and a single child window, similar to Figure 7.2.

Figure 7.2. The MDI Windows Form application with an initial MDI child window.


Adding a Menu

Because this is supposed to be a Multiple Document Interface application, you need to add a way to create another child window within the main window. You'll do this by first adding a menu to the main Windows Form.

Adding a menu to any Windows Forms is similar to how the controls were added to the SimpleWindowsForm. Without a resource file to describe the menu, it has to be built by allocating menu items and adding them to a menu bar and setting all attributes for each menu item through the source code. Because this code can get large, it is a good idea to create a separate method called from the InitForm() method to create the menu. This keeps the InitForm() method tidy. Therefore, the first step is to add a protected method, CreateMenu(), to the MDIWindowFrame class. You can add the method manually, making sure to add both the declaration and the definition of the method, or you can use the Add Method Wizard. Using the Class View, navigate to the MDIWindowFrame class, right-click it, and select Add, Add Function. In the dialog that is displayed, enter void for the return type and set the function name to CreateMenu. There will be no parameters for this function, so click Finish to add the method to the class.

Because this is a simple MDI application, the menu will only contain a few basic menu items. For each menu item, you need to allocate a new MenuItem class. Although it is not necessary to keep a pointer to each menu item allocated within the class, it is useful to have if you modify any of the menu items at runtime. Listing 7.9 shows the MDIWindowFrame class declaration with the declared MainMenu and MenuItem members.

Listing 7.9 The MDIWindowFrame Class with Declared Member Data for the Menu and Menu Items
 1: __gc class MDIWindowFrame : public Form  2: {  3: protected:  4:  5:    MainMenu*  m_pMainMenu;  6:    MenuItem*  m_pFileMenu;  7:    MenuItem*  m_pFileSeparator;  8:    MenuItem*  m_pFileNewMenu;  9:    MenuItem*  m_pFileExitMenu; 10:    MenuItem*  m_pWindowMenu; 11:    MenuItem*  m_pWindowCascadeMenu; 12:    MenuItem*  m_pWindowTileMenu; 13:    MenuItem*  m_pWindowCloseMenu; 14:    MenuItem*  m_pHelpMenu; 15:    MenuItem*  m_pHelpAboutMenu; 16: 17: protected: 18:    void InitForm(); 19:    void CreateMenu(); 20: 21: public: 22:    MDIWindowFrame(); 23:    virtual ~MDIWindowFrame() {} 24: }; 

The menu is created in the InitForm() method. However, instead of placing all the menu-initialization code in InitForm(), you'll create a separate method, CreateMenu(), that is called from InitForm(). This allows you to keep things better organized. As you can see in Listing 7.10, the menu-initialization code in the CreateMenu() method is somewhat lengthy.

Listing 7.10 The CreateMenu() Method, Which Initializes the Main Menu Within the MDIWindowForm Class
 1: void MDIWindowFrame::CreateMenu()  2: {  3:    // Allocate menu items  4:    m_pMainMenu          = new System::Windows::Forms::MainMenu;  5:    m_pFileMenu          = new System::Windows::Forms::MenuItem;  6:    m_pFileSeparator     = new System::Windows::Forms::MenuItem;  7:    m_pFileNewMenu       = new System::Windows::Forms::MenuItem;  8:    m_pFileExitMenu      = new System::Windows::Forms::MenuItem;  9:    m_pWindowMenu        = new System::Windows::Forms::MenuItem; 10:    m_pWindowCascadeMenu = new System::Windows::Forms::MenuItem; 11:    m_pWindowTileMenu    = new System::Windows::Forms::MenuItem; 12:    m_pWindowCloseMenu   = new System::Windows::Forms::MenuItem; 13:    m_pHelpMenu          = new System::Windows::Forms::MenuItem; 14:    m_pHelpAboutMenu     = new System::Windows::Forms::MenuItem; 15: 16:    // 17:    // MainMenu 18:    // 19:    MenuItem* pMenuItems[] = new MenuItem*[3]; 20:    pMenuItems[0] = m_pFileMenu; 21:    pMenuItems[1] = m_pWindowMenu; 22:    pMenuItems[2] = m_pHelpMenu; 23:    m_pMainMenu->MenuItems->AddRange( pMenuItems ); 24: 25: 26:    // 27:    // FileMenu 28:    // 29:    pMenuItems = new MenuItem*[3]; 30:    pMenuItems[0] = m_pFileNewMenu; 31:    pMenuItems[1] = m_pFileSeparator; 32:    pMenuItems[2] = m_pFileExitMenu; 33:    m_pFileMenu->MenuItems->AddRange( pMenuItems ); 34: 35:    m_pFileMenu->Index = 0; 36:    m_pFileMenu->Text = "&File"; 37: 38:    // FileNewMenu 39:    m_pFileNewMenu->Index = 0; 40:    m_pFileNewMenu->Text = "&New"; 41:    m_pFileNewMenu->add_Click( new EventHandler( this, FileNew_Click ) ); 42: 43:    // Separator 44:    m_pFileSeparator->Index = 1; 45:    m_pFileSeparator->Text = "-"; 46: 47:    // FileExitMenu 48:    m_pFileExitMenu->Index = 2; 49:    m_pFileExitMenu->Text = "E&xit"; 50:    m_pFileExitMenu->add_Click( new EventHandler( this, FileExit_Click ) ); 51: 52:    // 53:    // WindowMenu 54:    // 55:    pMenuItems[0] = m_pWindowCascadeMenu; 56:    pMenuItems[1] = m_pWindowTileMenu; 57:    pMenuItems[2] = m_pWindowCloseMenu; 58:    m_pWindowMenu->MenuItems->AddRange( pMenuItems ); 59: 60:    m_pWindowMenu->Index = 1; 61:    m_pWindowMenu->MdiList = true; 62:    m_pWindowMenu->Text = "&Window"; 63: 64:    // WindowCascadeMenu 65:    m_pWindowCascadeMenu->Index = 0; 66:    m_pWindowCascadeMenu->Text = "&Cascade"; 67:    m_pWindowCascadeMenu->add_Click( 68:        new EventHandler( this, WindowCascade_Click ) ); 69: 70:    // WindowTileMenu 71:    m_pWindowTileMenu->Index = 1; 72:    m_pWindowTileMenu->Text = "&Tile"; 73:    m_pWindowTileMenu->add_Click( new EventHandler( this, WindowTile_Click ) ); 74: 75:    // WindowCloseMenu 76:    m_pWindowCloseMenu->Index = 2; 77:    m_pWindowCloseMenu->Text = "Close &All"; 78:    m_pWindowCloseMenu->add_Click( 79:        new EventHandler( this, WindowCloseAll_Click ) ); 80: 81:    // 82:    // HelpMenu 83:    // 84:    m_pHelpMenu->MenuItems->Add( m_pHelpAboutMenu ); 85:    m_pHelpMenu->Index = 2; 86:    m_pHelpMenu->Text = "&Help"; 87: 88:    m_pHelpAboutMenu->Index = 0; 89:    m_pHelpAboutMenu->Text = "&About..."; 90:    m_pHelpAboutMenu->add_Click( new EventHandler( this, HelpAbout_Click ) ); 91: 92: } 

Starting with the main menu bar, you have to instantiate a new instance of the appropriate class for each element in the menu. The main menu bar is instantiated as a MainMenu class. You then instantiate each menu item, starting with the top-level menu items and working down into each of the submenus. Even the separator in the File menu is a menu item that you instantiate. After you create each of the MenuItem classes, you add them to the appropriate parent, which is the main menu for the top-level menu items and the top-level menu item for the submenu items.

Each MenuItem object has an event handler assigned to it with the add_Click() method for handling the Click event. Anytime the user selects a menu item with the mouse or keyboard, the assigned handler for the Click event is called. The first thing you need to do to add the event handlers to the class is to declare them in the class declaration. Each event takes two parameters a pointer to an Object and a pointer to an EventArgs object. Add the event handler declarations to the protected area of the class declaration using the following code snippet as a guide:

 void FileExit_Click( Object* pSender, EventArgs* pArgs ); void FileNew_Click( Object* pSender, EventArgs* pArgs ); void HelpAbout_Click( Object* pSender, EventArgs* pArgs ); void WindowCascade_Click( Object* pSender, EventArgs* pArgs ); void WindowCloseAll_Click( Object* pSender, EventArgs* pArgs ); void WindowTile_Click( Object* pSender, EventArgs* pArgs ); 

Listing 7.11 shows the definitions of the each of the menu item event handlers.

Listing 7.11 The MenuItem Object's Click Event Handlers for the Main Menu
 1: void MDIWindowFrame::FileExit_Click( Object* pSender, EventArgs* pArgs )  2: {  3:    // Close the application  4:    Close();  5: }  6:  7: void MDIWindowFrame::FileNew_Click( Object* pSender, EventArgs* pArgs )  8: {  9:    MDIChildForm* pChild2 = new MDIChildForm; 10: 11:    pChild2->MdiParent = this; 12:    pChild2->Show(); 13: } 14: 15: void MDIWindowFrame::WindowCascade_Click( Object* pSender, EventArgs* pArgs ) 16: { 17:    LayoutMdi( MdiLayout::Cascade ); 18: } 19: 20: void MDIWindowFrame::WindowTile_Click( Object* pSender, EventArgs* pArgs ) 21: { 22:    LayoutMdi( MdiLayout::TileHorizontal ); 23: } 24: 25: void MDIWindowFrame::WindowCloseAll_Click( Object* pSender, EventArgs* pArgs ) 26: { 27:    int nCount = MdiChildren->get_Length(); 28: 29:    for( int i = 0; i<nCount; i++ ) 30:       MdiChildren[0]->Close(); 31: } 32: 33: void MDIWindowFrame::HelpAbout_Click( Object* pSender, EventArgs* pArgs ) 34: { 35: } 

The last thing to do before you can test your menu is to add the menu to the main Windows Form. When you add controls to a Windows Form, certain events are fired based on layout changes. However, during the initial stages of building the form, this can produce undesirable results. You can temporarily suspend firing these events by calling the SuspendLayout function at the beginning of the InitForm function. To turn layout events back on, simply call ResumeLayout before you return from the function.

Adding a menu to a form is a little different from adding other types of controls. Because forms usually have menus associated with them, the Forms class contains a Menu property. To associate a menu to the form, it's a simple matter of setting that property to point to the menu you created with CreateMenu, the m_pMainMenu variable. Listing 7.12 shows the revised InitForm function.

Listing 7.12 The InitForm() Method with Menu Assignment
 1: void MDIWindowFrame::InitForm()  2: {  3:    SuspendLayout();  4:  5:    CreateMenu();  6:  7:    // Associate main menu control with the Form  8:    Menu = m_pMainMenu;  9: 10:    AutoScaleBaseSize = System::Drawing::Size(5, 13); 11:    ClientSize = System::Drawing::Size(292, 273); 12: 13:    // Add the MDI client area control to the form 14:    Controls->Add( new System::Windows::Forms::MdiClient ); 15: 16:    IsMdiContainer = true; 17:    Name = "MDIWindowFrame"; 18:    Text = "MDI Application"; 19: 20:    ResumeLayout(false); 21: } 

The main menu is assigned to any Windows Form window by setting the Form.Menu property to the MainMenu class you instantiated and initialized with the menu items in the CreateMenu() method. In order for the MDI child windows to display, you need to add a MdiClient control to the Controls array, as shown on line 18.

Your menu should now be fully functional. Compile your application and run the executable. Selection File, New from the menu bar will create another MDI child window. You can also put the windows in a cascade or tile layout by using the Window menu.

Adding a Toolbar

The process of creating a toolbar is similar to how the menu was created. The main toolbar control is created and then each of the toolbar elements is created as a new object and added to the toolbar control. Again, as with the menu, this is best done in the toolbar's own method. Therefore, declare and create a new method named CreateToolbar(), where you will create the toolbar with the code shown in Listing 7.13.

Listing 7.13 The CreateToolbar() Method Definition Showing the Creation of the Toolbar Control
 1: void MDIWindowFrame::CreateToolbar()  2: {  3:    m_pMainToolbar   = new System::Windows::Forms::ToolBar;  4:    m_pFileNewButton = new System::Windows::Forms::ToolBarButton;  5:    m_pToolbarImages = new  6:    System::Windows::Forms::ImageList();  7:  8:    //  9:    // MainToolbar 10:    // 11:    m_pMainToolbar->Appearance = 12:    System::Windows::Forms::ToolBarAppearance::Flat; 13:    m_pMainToolbar->AutoSize = false; 14:    m_pMainToolbar->Buttons->Add(m_pFileNewButton); 15: 16:    m_pMainToolbar->DropDownArrows = true; 17:    m_pMainToolbar->ImageList = m_pToolbarImages; 18:    m_pMainToolbar->Name = "MainToolbar"; 19:    m_pMainToolbar->ShowToolTips = true; 20:    m_pMainToolbar->Size = System::Drawing::Size(292, 25); 21:    m_pMainToolbar->TabIndex = 1; 22: 23:    m_pMainToolbar->add_ButtonClick( 24    new ToolBarButtonClickEventHandler( this, ToolbarButton_Click ) ); 25: 26:    // FileNewButton 27:    m_pFileNewButton->ImageIndex  = 0; 28:    m_pFileNewButton->ToolTipText = "Create new MDI Child"; 29: 30:    // ToolbarImages 31:    m_pToolbarImages->ColorDepth = 32:    System::Windows::Forms::ColorDepth::Depth8Bit; 33: 34:    m_pToolbarImages->ImageSize = System::Drawing::Size(16, 16); 35:    m_pToolbarImages->Images->Add( 36:    new System::Drawing::Icon( "FileNew.ico" ) ); 37: 38:    m_pToolbarImages->TransparentColor = 39:    System::Drawing::Color::Transparent; 40: } 

The toolbar control is created by instantiating a new ToolBar class. ToolBarButton objects are added to the toolbar to represent the buttons in the toolbar control. In this case, there is a single toolbar button.

This toolbar control has a flat appearance and tooltips. These properties are set during the initialization of the toolbar control. Toolbars are also associated with an ImageList object to provide the images for the toolbar buttons. The images are indexed by the order they are added to the ImageList object. The index is assigned to the toolbar button's ImageIndex property to identify which icon to use for the toolbar button.

The ImageList object itself is initialized by setting its image size, color depth, and transparent color properties. Using the Add() method, you can add images to the ImageList object. In this case, only a single icon image is added.

Looking back at Listing 7.13, notice that the toolbar has an event, ButtonClick, that a handler is assigned to with the add_ButtonClick() method. Any time a button on the toolbar is clicked by the user, this event is raised and the handler is called. Listing 7.14 shows the definition of the handler for the ButtonClick event.

Listing 7.14 The Toolbar ButtonClick Event Handler
 1: void MDIWindowFrame::ToolbarButton_Click( Object* pToolbar,  graphics/ccc.gifToolBarButtonClickEventArgs* pArgs )  2: {  3:    //Check to see which button was pressed  4:    if (m_pMainToolbar->Buttons->IndexOf(pArgs->Button) == 0 )  5:    {  6:       MDIChildForm* pChild = new MDIChildForm;  7:  8:       pChild->MdiParent = this;  9:       pChild->Show(); 10:    } 11: } 

Because the toolbar in this example only has a single button, the check to see which button was clicked is not necessary. However, it shows what code is required to check which button is clicked when there is more than one button on the toolbar. To determine which button was clicked, you use the Button property of the ToolBarButtonClickEventArgs parameter as an index into your toolbar's Buttons collection. The value returned from the IndexOf function of the Buttons collection tells you which button was clicked. Because there is only one button on the toolbar, the value will always be 0.

Finally, the following statements are added to the InitForm() method to call the CreateToolbar() method and add the toolbar control to the Windows Form:

 CreateToolbar() Controls->Add( m_pMainToolbar ); 

Adding an About Dialog

Finally, all applications need to have an About dialog. This sample application is no exception. Therefore, you will learn how to create a modal dialog from a Windows Form.

As with the other Windows Forms up to this point, start with the class shown in Listing 7.3 but this time change the class name to AboutDialog. The About dialog has a message and an OK button, so declare protected Label and Button pointer member data items within the AboutDialog class. In order to handle the OK button's Click event, also declare a protected event handler named OnOK(), as shown in Listing 7.15.

Listing 7.15 The AboutDialog Class Definition
 1: __gc class AboutDialog : public Form  2: {  3: protected:  4:    Label*  m_pAbout_L;  5:    Button* m_pOK_B;  6:  7: protected:  8:    void InitForm();  9:    void OnOK(Object* pSender, EventArgs* pEventArgs); 10: 11: public: 12:    AboutDialog(); 13:    virtual ~AboutDialog() {} 14: }; 

The AboutDialog Windows Form is initialized in the InitForm() method, just like the other Windows Forms in this example. This form is very similar to the one you worked with in the first example in this hour in that it only has a label and button control on the form. Listing 7.14 shows the InitForm() method for the AboutDialog class.

Listing 7.16 The AboutDialog Class's InitForm() and OnOK() Method Definitions
 1: AboutDialog::AboutDialog()  2: {  3:    InitForm();  4: }  5: void AboutDialog::InitForm()  6: {  7:    // Allocate controls  8:    m_pAbout_L = new Label;  9:    m_pOK_B    = new Button; 10: 11:    // m_pAbout_L Initialization 12:    m_pAbout_L->Location = Point(8, 20); 13:    m_pAbout_L->TabIndex = 1; 14:    m_pAbout_L->TabStop = false; 15:    m_pAbout_L->Text = S"MDI Windows Form"; 16:    m_pAbout_L->Size = System::Drawing::Size(120, 16); 17: 18:    // m_pOK_B Initialization 19:    m_pOK_B->Location = Point(100, 50); 20:    m_pOK_B->TabIndex = 2; 21:    m_pOK_B->TabStop = true; 22:    m_pOK_B->Text = "OK"; 23:    m_pOK_B->Size = System::Drawing::Size(70, 20); 24:    m_pOK_B->add_Click( new EventHandler( this, OnOK ) ); 25: 26: 27:    // Add controls to the Form 28:    Controls->Add( m_pAbout_L ); 29:    Controls->Add( m_pOK_B ); 30: 31:    // Initialize Form attributes 32:    Size = System::Drawing::Size(200, 110); 33:    Text = "About"; 34:    FormBorderStyle = FormBorderStyle::FixedDialog; 35:    MaximizeBox = false; 36:    MinimizeBox = false; 37: } 38: 39: void AboutDialog::OnOK(Object* /*pSender*/, EventArgs* /*pEventArgs*/) 40: { 41:    Close(); 42: } 

The new Label object is assigned a size and location along with the contents to display in the About dialog. The Button object is assigned a size and location also, along with a handler for the Click event. When the user clicks the OK button, it will call the OnOK() method and close the dialog, as expected.

There are a few initialization settings for the Windows Form that make it have the characteristics of a dialog. First, the FormBorderStyle property is set to a fixed dialog border so that it isn't sizeable. Additionally, the minimize and maximize boxes are removed from the form by setting the corresponding properties to False.

The About dialog is displayed from the Help, About menu item's Click event handler, as shown earlier in Listing 7.8. A new instance of the AboutDialog class is created, and the ShowDialog() method is called.

Compiling and Running the MDI Application

At this point, the application is ready to compile and run. When it is compiled and executed, you can open multiple MDI child windows and use the Window menu items to adjust them. Selecting the Help, About menu item displays the About dialog as expected (see Figure 7.3).

Figure 7.3. The MDI Windows Form application with all types of windows being displayed.


As stated earlier, the source code for this example can be found in its entirety on the Sams Web site for your convenience.


Sams Teach Yourself Visual C++. NET in 24 Hours
Sams Teach Yourself Visual C++.NET in 24 Hours
ISBN: 0672323230
EAN: 2147483647
Year: 2002
Pages: 237

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: