Click here to Skip to main content
15,879,326 members
Articles / Desktop Programming / MFC
Article

Hello C++/CLI - Part 2

Rate me:
Please Sign up or sign in to vote.
4.02/5 (19 votes)
21 Dec 2006CPOL9 min read 100.9K   1.8K   34   18
Second part of the series: leaving Platform SDK behind, and MDI Forms.

Introduction

Hi there!

Welcome to the second part of my article series. Unless you have already done so, I suggest reading the first part for starters, as this second part will rely quite heavily on the fact that you already have the necessary tools and technologies installed.

In this part of the series, we will delve on the following issues. For some of you readers, it might feel strange that the writing of pure .NET applications doesn't come until now, but like the first part stated, this series is meant for those developers who already have a grasp on how Windows applications were written before the Whidbey compiler generation.

Our topics for tonight's discussion (yes, this article was written during the night) are as follows:

  • Leaving the Platform SDK out - Writing "pure" .NET applications using C++/CLI.
  • Writing more complex GUI with Windows Forms - The MDI example.

Without further delay, let's get started!

Ditching the Platform SDK

A few people who have read my first article sent in e-mails asking how they should proceed if they didn't want to use the Platform SDK. Like most of you already know, the VC++ Express contains a set of wizards, from which you can even find a Windows Forms application wizard. But, like you have already noted, I don't like using those wizards. Yes, they generate efficient skeletons, but the whole concept of learning how C++/CLI works requires that we sometimes write our applications from ground up.

So, go ahead, fire up your VC++ and create a new project. Its type should be .NET and the template Empty Project sounds suitable. For the name, give in Hello_CLI_3. The wizard will generate the folders for the solution and then you're dropped into the Solution Explorer view.

Settings for a "pure" .NET application

Now, as we are in the process of writing a pure .NET application, there are certain project settings that need to be altered in order for the builds to get targeted correctly. Here is a list of the settings, their locations, and the values they should be set to: (to access project properties, right-click on the project name, and choose Properties.)

  • Linker -> System, SubSystem: Windows.
  • Linker -> Advanced, Entry Point: Main.

Back in the Solution Explorer, it's time to add support for the .NET Framework. This time, we will do it completely manually, so right-click on the project name and choose .NET References. Locate a button called Add New Reference and click on it. From the list that is presented, add the System.dll and System.Windows.Forms.dll into your project, then click on OK, and close the Properties window.

The actual code

Now, it's time to add actual code into our project. Add a new source file, and name it Main.cpp. Into this file, paste the following code fragment:

MC++
using namespace System;

int Main(void)
{
    // Display a simple messagebox
    System::Windows::Forms::MessageBox::Show( L"Welcome to C++/CLI", "TestApp", 
            System::Windows::Forms::MessageBoxButtons::OK );

    // End the application
    return 0;
}

Go ahead, compile and execute this program. You can see it starts up, pops a message box, and closes down. There it is, our very own, pure .NET application, alive and kicking. Like you can see, I prefer to use the full namespace of every class I use. This helps me learn where and how which object resides. Naturally, you could, at the start of the file, place the following line:

MC++
using namespace System::Windows::Forms;

The result of this would be that you wouldn't need to include this namespace in the code anymore. You could just call MessageBox::Show(), and specify MessageBoxButtons::OK as the parameter.

Remember how we defined the entry point of the application in the linker settings? Now, you can see the effect. If we did not define this entry point, the linker would look for the WinMain entry point again. Using this approach, the .NET Framework is used to initialize the application and the thread, then call our entry-point function to allow the execution to begin.

Writing a more complex GUI - The MDI example

On our next section, we will dive into the process of writing a bit more complicated user interface. Our interface will present us with a MDI Frame form, a toolbar, and a single child form.

To get started, again create a new blank .NET project, naming it Hello_CLI_4. And following the familiar steps from above, setup the settings for the linker. Then add .NET References, this time only System.dll is needed. Add a new source file, and write the Main function, making it only return, and nothing else.

Designing the parent form

Now, it's time to introduce the Forms. Add a new UI -> Windows Form item into the project. Name this form as Form_P. After a few minutes of thinking, you are presented with the Form Designer. Now, go to Solution Explorer and delete the Form_P.cpp file. This one is not needed for our purposes.

Back in the Form Designer, right-click on the Form and choose Properties. From the Properties window, scroll to Appearance -> Text and change this property to The MDI Example. Next, scroll again to find Window Style -> IsMDIContainer and set this one to True. You can instantly see how our Form starts to look different. For a reference, here's a picture of what the form should look like when these settings are done.

The MDI Form layout

Strips, the source of control

In the .NET Framework environment, the concept of bars seems to be misplaced somewhere, and is replaced by the concept of Strips. A menu bar is represented by a MenuStrip component. A toolbar is called a ToolStrip, and a status bar is a StatusStrip. Also, the behavior of all these has changed a lot.

Let's start by adding a MenuStrip. Drag it on the form. You can easily add and remove menu topics by clicking on the Type Here section and writing a menu topic. For this example application, create a File menu and a Help menu. Under the first one, add an item called Exit, and under the second one, an item called About MDI Example. If, at some point, the program will auto-generate code fragments and drop you into the Form_P.h's code view, then don't panic. Just delete the auto-generated code section and return to the Designer view. The safest way is to use the right-click to select an item.

When done, you should be left out with something like the following image represents:

The MDI Parent form with a menu

Now is the time to name these items. As I have a solid background on Windows programming, I've grown quite fond with using the ID designations. So, click on the MenuStrip at the gradient section, and spot a small right-pointing arrow at its right end. Click on this arrow, and a quick-select Actions menu is popped open. From here, select Edit Items.

You are now taken to the Items Collection Editor window, from where you can quickly change the properties of each of the menu items. First, choose the File menu topic, browse to its Design -> Name section, and rename it to ID_FILE_MENU. Similarly, rename the Help menu topic to ID_HELP_MENU.

To access the individual menu items' properties, click on the desired menu topic, and scroll to Data -> DropDownItems and click on the More button (the one with three dots on it). You will be taken into a similar Items Collection Editor window, but this time focusing on the individual menu items. To navigate backwards, click on OK. Using this knowledge, go and change the IDs of the menu items to ID_FILE_EXIT and ID_HELP_ABOUT, respectively. Also, if you wish, then on both of the menu items, you can scroll to Behavior -> ToolTipText and enter a descriptive tooltip for both of them.

When finished, return to the Form Designer and click on the right-pointing arrow again to close the Actions menu.

Adding a StatusStrip

Adding a StatusStrip is quite a breeze. Just drag & drop it on the form. Type into the Type Here section and add a new Panel named Ready.... Right-click on this Panel and edit its properties again. To setup this Panel to display text only, and look correct, you should modify its properties according to this list:

  • Design -> Name, ID_STATUS_TEXT.
  • Appearance -> Display Style, Text.
  • Appearance -> TextAlign, MiddleLeft.
  • Behavior -> AutoSize, False.
  • Layout -> Size -> Width, 200.

Now, our parent form is completed, and you should be resulted with something like the following image represents:

The finished MDI form

Coding the functionality

Now, it's time to start working on what all stuff the form can do. The easiest way to manipulate the events is to use the Properties window. On the top of this window, you can always see the name/ID of the object currently being edited. Going through all these in an orderly fashion, add handlers to the following events for the menu items (not menu topics).

  • Click - Named like OnClicked_XXX.
  • MouseEnter - OnEnter_XXX.
  • MouseLeave - OnLeave_XXX.

First, let's tackle the Click events. For the Exit menu item, we will again exit the Form by calling:

MC++
private: System::Void OnClicked_Exit(System::Object^ sender, 
                                  System::EventArgs^ e)
{
    // Exit the form
    Application::Exit();
}

The About menu item will display a message box showing a nifty error code:

MC++
private: System::Void OnClicked_About(System::Object^ 
                                  sender, System::EventArgs^ e)
{
    // Display a message box
    MessageBox::Show( L"About-box for this application", L"About The MDI Example", 
                      MessageBoxButtons::OK );
}

The MouseEnter and MouseLeave events are used to modify the text displayed by the status strip. The idea is that when mouse enters the item, the tooltip of the menu item is displayed on the status panel. To support this functionality, the code fragment for the MouseEnter events should be as follows:

MC++
private: System::Void OnEnter_Exit(System::Object^ 
                   sender, System::EventArgs^ e)
{
    this->ID_STATUS_TEXT->Text = this->ID_FILE_EXIT->ToolTipText;
}

And for the MouseLeave, it should be:

MC++
private: System::Void OnLeave_Exit(System::Object^ 
                   sender, System::EventArgs^ e)
{
    this->ID_STATUS_TEXT->Text = L"Ready...";
}

Remember that for the Help item, the text is different. You can use the ID you gave it to access its ToolTipText property.

Wiring it up

Our last step is to add the necessary code calls to make our form live and breathe. Save all changes and close the Form Designer and the form header file. Go back to the Solution Explorer and the source file you added. Include the header file for the form, and inside the Main function, add the familiar two calls. The resulting file should look something like this:

MC++
#include "Form_P.h"

using namespace System;
using namespace System::Windows::Forms;

int Main(void)
{
    // Enable visual styles and run the form
    Application::EnableVisualStyles();
    Application::Run( gcnew Hello_CLI_4::Form_P() );

    return 0;
}

Now, go and execute the application. Use the menu items, see how the status text changes when you enter/exit the menu item areas.

Conclusion

Phew! That was a serious amount of coding, good to know that all of you were patient enough to follow me through it all. I hope this article was helpful to you on your way to get everything started.

In the next article of the series, we'll dive even more deeper into the world of MDI Forms, adding a ToolStrip. As a sugar in the bottom, we'll also take a look of how easy the COM usage has become in the new language syntax.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Cybercom Finland Oy
Finland Finland
I live in the Frozen North, in Finland. Although the opportunities for good jobs or sunny days are scarce here, I still like it here. But at some point I'll move abroad.. Oh, and yes, there ARE polar bears in here Smile | :)

I graduated as a B.Sc in Computer Science in 2006, and currently I'm employed by Cybercom Finland Oy, a world-wide software house. I mainly develop Windows Desktop software using Qt, .Net Framework and other relevant technologies.

When I'm not knee-depth in the code, I play computer games, Go or go to the gym. I love music, in all it's forms, and dancing is close to my heart. Or then I spend time with my friends. I like friends. You can never have enough of them Smile | :)

I'm a keen player of games. Simulations and RPG are the key words. Old-time games such as Mega Man are good as well, not forgetting the block-buster hits either.

Comments and Discussions

 
GeneralSlightly off topic Pin
Jörgen Sigvardsson21-Dec-06 12:04
Jörgen Sigvardsson21-Dec-06 12:04 
GeneralRe: Slightly off topic Pin
Antti Keskinen21-Dec-06 20:20
Antti Keskinen21-Dec-06 20:20 
General[Article Updated] Pin
Antti Keskinen21-Dec-06 6:13
Antti Keskinen21-Dec-06 6:13 
GeneralRe: [Article Updated] Pin
anysiddiqui8-Mar-07 20:21
anysiddiqui8-Mar-07 20:21 
QuestionRe: [Article Updated] Pin
AgNO36-Sep-07 4:21
AgNO36-Sep-07 4:21 
GeneralC++ CodeDOM Parser Error Pin
beeth921-Dec-06 4:18
beeth921-Dec-06 4:18 
GeneralRe: C++ CodeDOM Parser Error Pin
Antti Keskinen21-Dec-06 5:54
Antti Keskinen21-Dec-06 5:54 
GeneralRe: C++ CodeDOM Parser Error Pin
beeth923-Dec-06 7:25
beeth923-Dec-06 7:25 
GeneralWhy should anyone use C++/CLI ... Pin
Anonymous27-Aug-04 9:06
Anonymous27-Aug-04 9:06 
GeneralRe: Why should anyone use C++/CLI ... Pin
Nemanja Trifunovic27-Aug-04 9:44
Nemanja Trifunovic27-Aug-04 9:44 
GeneralRe: Why should anyone use C++/CLI ... Pin
Anonymous27-Aug-04 9:54
Anonymous27-Aug-04 9:54 
GeneralRe: Why should anyone use C++/CLI ... Pin
Antti Keskinen29-Aug-04 22:08
Antti Keskinen29-Aug-04 22:08 
GeneralRe: Why should anyone use C++/CLI ... Pin
TigerNinja_6-Apr-05 15:53
TigerNinja_6-Apr-05 15:53 
GeneralRe: Why should anyone use C++/CLI ... Pin
Antti Keskinen7-Apr-05 0:49
Antti Keskinen7-Apr-05 0:49 
GeneralRe: Why should anyone use C++/CLI ... Pin
MrKalinka16-Jun-06 9:27
MrKalinka16-Jun-06 9:27 
GeneralRe: Why should anyone use C++/CLI ... Pin
Pablo Aliskevicius1-Sep-04 18:32
Pablo Aliskevicius1-Sep-04 18:32 
GeneralRe: Why should anyone use C++/CLI ... Pin
567890123427-Dec-06 4:50
567890123427-Dec-06 4:50 
GeneralRe: Why should anyone use C++/CLI ... Pin
alleyes20-Aug-09 4:42
professionalalleyes20-Aug-09 4:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.