Introduction
If you were to search the internet right now for a tutorial on .NET Forms in C++, you would realize that the amount of tutorials for this subject is painfully low, and most of them are meant for C#. If you are like me and don't like working with Win32 API, then forms are a very nice alternative.
NOTE: I am using Visual Studio 2008, if you are using a different compiler, then I suggest you experiment with it to find out how to use forms for the said compiler.
This tutorial will cover the following:
- How to configure your compiler so it will use standard C# libraries
- How to create a form
- How to run a form
- How to create events within a form
- How to use common dialogs in your form
- How to use multiple forms
Configuring Visual C++ 2008
This step is fairly simple. Go to your project properties, select Configuration Properties -> General and change the Common Language Runtime Support to /clr. That was it! Now let's start using forms!
Creating a .NET Form
Alright, first create the body of main as you would for any standard Win32 application:
#include "iostream"
#include "windows.h"
using namespace std;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
}
Great, if you have done any Win32 programming, this should look familiar to you, if not, don't worry, you don't need to understand it to use forms.
Now create a Windows Form in your project's header folder. When you select this, you should be in Designer Mode, we will talk about this later. For now, return to your main cpp file and include this form as well as the namespace that was generated.
#include "iostream"
#include "windows.h"
#include "Form1.h"
using namespace std;
using namespace TestC;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
}
Good, now let's talk about two important functions that we will put into WinMain()
.
First, Application::Run(System::Windows::Forms::Form^ mainForm)
is the command that runs your form. The code does not continue until the user has exited the form or Application::Exit()
is called.
Second, Application::EnableVisualStyles()
is the command that gives your form a Windows XP / <place w:st="on">Vista / 7 style. I recommend leaving this line of code out if you are using a rendering API (such as DirectX or OpenGL) with your form, as you might experience crashes while running your form.
Now your code should look like this:
#include "iostream"
#include "windows.h"
#include "Form1.h"
using namespace std;
using namespace TestC;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
Application::EnableVisualStyles();
Application::Run(gcnew Form1());
}
Now compile your program and run it, an empty form should appear onscreen. You can now play around with the forms designer, as it is pretty self explanatory.
Creating Events
After the initial hurdle, using .NET Forms in C++ becomes very easy. If you have created any controls on your form previously, you will notice that nothing happens when you click on them. We will fix this now, first we will create a button in the middle of a form that will cause the application to exit (the same effect obtained when clicking on the red x in the top right hand corner of the form).
To create an event, enter designer mode and in the properties window click on the icon that looks like a lightning bolt. You should now see a list of triggers. We will concentrate on the Click event (triggered when the button or control is clicked on by the user). Double click on the Click event and you should be redirected to the code. This is an event, treat it like you would a normal function, it will run whenever the event is triggered (in this case, when the user clicks on the button).
We want the application to exit and close, so add this code:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
Application::Exit();
}
This destroys the form and returns to the WinMain()
function.
More on Controls
Everything you create in the designer is a member of your form. A form is essentially a class with the parent System::Windows::Forms::Form
. Therefore, everything you created in designer mode can be accessed with this
. Each member is also a class in itself with several members that hold data relating to the control. For example: you can get the text contained within a text box like this:
String^ a = this->textBox1.Text;
NOTE: String^
is a common C# data type (string
in C#, String^
in C++).
Common Windows Dialogs
In many programs, you will see common windows dialogs, like the font dialog, the save dialog, or the load dialog, here is a list of all the dialogs in .NET (3.5):
ColorDialog
FolderBrowserDialog
FontDialog
OpenFileDialog
SaveFileDialog
PrintDialog
PrintPreviewDialog
Adding a Windows Dialog to your Form
Now, to add one of these dialogs to your form, simply drag them from the toolbox into your form and they should be listed at the bottom of the designer.
For this example, I am going to use a font dialog; add a multiline text box and a new button. Create a new event for when this button is clicked. Now pay close attention to this code:
private: System::Void button1_Click_1(System::Object^ sender, System::EventArgs^ e)
{
fontDialog1->ShowColor = true;
fontDialog1->Font = textBox1->Font;
fontDialog1->Color = textBox1->ForeColor;
if ( fontDialog1->ShowDialog() != ::DialogResult::Cancel )
{
textBox1->Font = fontDialog1->Font;
textBox1->ForeColor = fontDialog1->Color;
}
}
First, this code assigns the font and fore color of our text box to the font dialog, then it runs the dialog and only continues when the user exits the dialog. This code then checks whether or not the user ended the dialog by pressing cancel. If the user didn't press cancel, it then assigns the font and fore color to the text box.
Running Multiple Forms
Now, we will run multiple forms at once. Create a new form and remember to include it and use its namespace in your previous form's declarations.
#pragma once
#include "Form2.h"
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace TestC2;
Now create a new button in your old form. This button will have an event that will open the second form. Create a new Click event for the button and observe the following:
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e)
{
Form2^ F = gcnew Form2();
F->ShowDialog();
}
What we do here is simple, we create a new variable of type Form2^
( we must include the ^
because we are using gcnew
as opposed to new)
, then the form is displayed as a dialog, this pauses the previous form and makes it inactive.
If you want your new form to run alongside the old form as opposed to instead of it, use the function Show()
instead of ShowDialog()
.
Conclusion
In my opinion, the best way to learn .NET Forms is by experimentation, form here, now you know how to use .NET Forms in your programs. .NET Forms may appear intimidating at first glance, but it is far easier than it appears. If you are coming away from this tutorial a little confused, I recommend you learn a little C#, it is very useful when dealing with .NET Forms.
More on .NET Forms
If you want to know more about .NET Forms, check out my other article: DirectX SDK with .NET Forms at this link.
History
- 6th September, 2009: Initial post