Pro Visual C++-CLI And The .NET 2.0 Platform (2006) [eng]-1
.pdf438 C H A P T E R 1 0 ■ A D V A N C E D W I N D O W S F O R M S A P P L I C A T I O N S
//
//bnCancel
this->bnCancel->DialogResult = System::Windows::Forms::DialogResult::Cancel;
this->bnCancel->Location = System::Drawing::Point(205, 60); this->bnCancel->Name = L"bnCancel";
this->bnCancel->Size = System::Drawing::Size(75, 23); this->bnCancel->TabIndex = 7;
this->bnCancel->Text = L"Cancel";
//bnAbort
//
this->bnAbort->DialogResult = System::Windows::Forms::DialogResult::Abort;
this->bnAbort->Location = System::Drawing::Point(110, 60); this->bnAbort->Name = L"bnAbort";
this->bnAbort->Size = System::Drawing::Size(75, 23); this->bnAbort->TabIndex = 6;
this->bnAbort->Text = L"Abort";
//
//bnOK
this->bnOK->DialogResult = System::Windows::Forms::DialogResult::OK; this->bnOK->Location = System::Drawing::Point(13, 60);
this->bnOK->Name = L"bnOK";
this->bnOK->Size = System::Drawing::Size(75, 23); this->bnOK->TabIndex = 5;
this->bnOK->Text = L"OK";
//tbPassedValue
//
this->tbPassedValue->Location = System::Drawing::Point(13, 20); this->tbPassedValue->Name = L"tbPassedValue"; this->tbPassedValue->Size = System::Drawing::Size(267, 20); this->tbPassedValue->TabIndex = 4;
//
// myDialog
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(292, 102); this->Controls->Add(this->bnCancel); this->Controls->Add(this->bnAbort); this->Controls->Add(this->bnOK); this->Controls->Add(this->tbPassedValue);
this->Name = L"myDialog"; this->Text = L"My Custom Dialog"; this->ResumeLayout(false); this->PerformLayout();
}
#pragma endregion };
}
C H A P T E R 1 0 ■ A D V A N C E D W I N D O W S F O R M S A P P L I C A T I O N S |
439 |
Figure 10-15 shows what the preceding example looks like when you execute it.
Figure 10-15. A custom dialog box
Now let’s take a look at the code to implement a custom dialog box (see Listing 10-13). The example calls the dialog box by clicking anywhere in the form.
Listing 10-13. Implementing a Custom Dialog Box
#include "MyDialog.h"
namespace |
CustomDialog |
{ |
|
using |
namespace System; |
using |
namespace System::ComponentModel; |
using |
namespace System::Collections; |
using |
namespace System::Windows::Forms; |
using |
namespace System::Data; |
using |
namespace System::Drawing; |
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
}
protected:
~Form1()
{
if (components)
{
delete components;
}
}
private:
System::Windows::Forms::Label^ lbRetString; System::Windows::Forms::Label^ lbRetVal; System::ComponentModel::Container ^components;
440 C H A P T E R 1 0 ■ A D V A N C E D W I N D O W S F O R M S A P P L I C A T I O N S
#pragma region Windows Form Designer generated code
void InitializeComponent(void)
{
this->lbRetString = (gcnew System::Windows::Forms::Label()); this->lbRetVal = (gcnew System::Windows::Forms::Label()); this->SuspendLayout();
//
//lbRetString
this->lbRetString->Location = System::Drawing::Point(34, 119); this->lbRetString->Name = L"lbRetString";
this->lbRetString->Size = System::Drawing::Size(225, 19); this->lbRetString->TabIndex = 3;
//lbRetVal
//
this->lbRetVal->Location = System::Drawing::Point(34, 77); this->lbRetVal->Name = L"lbRetVal";
this->lbRetVal->Size = System::Drawing::Size(225, 19); this->lbRetVal->TabIndex = 2;
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(292, 273); this->Controls->Add(this->lbRetString); this->Controls->Add(this->lbRetVal);
this->Name = L"Form1";
this->Text = L"Click Form to get dialog"; this->Click +=
gcnew System::EventHandler(this, &Form1::Form1_Click); this->ResumeLayout(false);
}
#pragma endregion
private:
System::Void Form1_Click(System::Object^ sender, System::EventArgs^ e)
{
MyDialog ^mydialog = gcnew MyDialog(); mydialog->PassedValue = "This has been passed from Form1";
if (mydialog->ShowDialog() == System::Windows::Forms::DialogResult::OK) lbRetVal->Text = "OK";
else if (mydialog->DialogResult == System::Windows::Forms::DialogResult::Abort) lbRetVal->Text = "Abort";
else
lbRetVal->Text = "Cancel";
C H A P T E R 1 0 ■ A D V A N C E D W I N D O W S F O R M S A P P L I C A T I O N S |
441 |
lbRetString->Text = mydialog->PassedValue;
}
};
}
Figure 10-16 shows what the preceding example looks like when you execute it.
Figure 10-16. Calling a custom dialog box
Not much of a change, is there? First, you include the include file for the definition of the MyDialog class using the standard include statement:
#include "MyDialog.h"
You need to do this because C++/CLI requires (like standard C++) that classes be defined before you use them. Next, you create an instance of the dialog box:
MyDialog ^mydialog = gcnew MyDialog();
Optionally, you can pass all the data you want to the dialog box:
mydialog->PassedValue = "This has been passed from Form1";
Then you call the dialog box in one of two ways:
•ShowDialog()
•Show()
The first mode, ShowDialog(), is modal. In this mode, you wait for the dialog box to finish before you continue processing. Normally, you would check the DialogResult upon exit, as you do in the example, but that is not necessary:
if (mydialog->ShowDialog() == System::Windows::Forms::DialogResult::OK) lbRetVal->Text = "OK";
else if (mydialog->DialogResult == System::Windows::Forms::DialogResult::Abort) lbRetVal->Text = "Abort";
else
lbRetVal->Text = "Cancel";
The second mode, Show(), is modeless. In this mode, the dialog box opens and then returns control immediately back to its caller. You now have two threads of execution running. (I cover threads in Chapter 16.) I usually use modeless dialog boxes for displaying information and not retrieving information. A classic example is the about box:
442 C H A P T E R 1 0 ■ A D V A N C E D W I N D O W S F O R M S A P P L I C A T I O N S
AboutBox->Show();
This is not to say that you can’t use a modeless dialog box to retrieve information, but you just need to be aware that the code that opens the dialog box is still executing, and it will not be waiting for a result from the dialog box. If this confuses you, you might want to consult Chapter 16 on how to code for two (or more) threads of execution.
The final thing you might do (again, this is optional) is grab the changed data out of the dialog box:
lbRetString->Text = mydialog->PassedValue;
By the way, I have been using Strings to pass data back and forth between the dialog box and the main application. This is not a restriction, though—you can use any data type you want.
Common .NET Framework–Provided Dialog Boxes
When you’ve worked with Windows for any length of time, you soon come to recognize some common dialog boxes that many applications use. The .NET Framework class library provides you easy access to using these same Windows dialog boxes in your programs. Table 10-3 shows a list of the available common dialog boxes.
Table 10-3. The Common Dialog Boxes
Dialog Box |
Description |
ColorDialog |
A dialog box to select a color |
FolderBrowserDialog |
A dialog box that allows the user to choose a folder |
FontDialog |
A dialog box to select a font |
OpenFileDialog |
A common Open File dialog box |
PageSetupDialog |
A dialog box that manipulates page settings, such as margins |
PrintDialog |
A dialog box to select a printer and the portion of the document |
|
you want to print |
SaveFileDialog |
A common File Save dialog box |
|
|
You call the common dialog boxes in the same way you do the custom dialog box you just built. Listing 10-14 shows just how simple it is to call the ColorDialog. Calling all the other custom dialog boxes is done the same way.
Listing 10-14. Calling a Common ColorDialog
namespace |
ColorDialogEx |
{ |
|
using |
namespace System; |
using |
namespace System::ComponentModel; |
using |
namespace System::Collections; |
using |
namespace System::Windows::Forms; |
using |
namespace System::Data; |
using |
namespace System::Drawing; |
C H A P T E R 1 0 ■ A D V A N C E D W I N D O W S F O R M S A P P L I C A T I O N S |
443 |
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
}
protected:
~Form1()
{
if (components)
{
delete components;
}
}
private:
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
void InitializeComponent(void)
{
this->SuspendLayout();
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(292, 273);
this->Name = L"Form1";
this->Text = L"Common Color Dialog - Click Form"; this->Click +=
gcnew System::EventHandler(this, &Form1::Form1_Click); this->ResumeLayout(false);
}
#pragma endregion
private:
System::Void Form1_Click(System::Object^ sender, System::EventArgs^ e)
{
ColorDialog^ colordialog = gcnew ColorDialog();
if (colordialog->ShowDialog() == System::Windows::Forms::DialogResult::OK)
{
BackColor = colordialog->Color;
}
}
};
}
444 C H A P T E R 1 0 ■ A D V A N C E D W I N D O W S F O R M S A P P L I C A T I O N S
There is nothing new or special here. First, check to make sure that the dialog box exited with the DialogResult of OK, and then set the color of the object you want changed with the value in the
Color property of the ColorDialog.
Figure 10-17 shows what the example looks like when you execute it.
Figure 10-17. Calling a common ColorDialog
Summary
In this chapter, you’ve encountered many of the more powerful controls available to the Win Forms developer. You started off with a couple of views and then moved on to container controls. Next, you looked at the strip controls ToolStrip, StatusStrip, and MenuStrip. Then, to finish off the coverage of controls, you took a look at some of the more fun controls available. After your whirlwind tour of controls, you ended Windows Form development with examining dialog boxes.
You should now be able to build a commercial-grade GUI interface that will impress all of your peers.
In the next chapter, you’ll continue to examine the GUI interface provided by the .NET Framework class library, but this time you’ll look at working with things such as fonts and prebuilt images, and drawing your own images from scratch.
446 |
C H A P T E R 1 1 ■ G R A P H I C S U S I N G G D I + |
A Quick Look at the GDI+ Namespaces
You can find the core functionality of GDI+ in the .NET Framework class library namespaces listed in Table 11-1.
Table 11-1. GDI+ Core Namespaces
Namespace |
Description |
System::Drawing |
This namespace is the core of GDI+. It consists of numerous |
|
classes to handle basic 2D rendering. It is also the location of |
|
the Graphics class from which all GDI+ functionality springs. |
System::Drawing::Drawing2D |
This namespace extends the 2D rendering capabilities of |
|
GDI+ by providing more advanced 2D rendering and vector |
|
graphics. |
System::Drawing::Imaging |
This namespace provides classes that allow direct manipula- |
|
tion of graphical images. |
System::Drawing::Printing |
This namespace provides classes that allow printing to a |
|
printer. It also provides classes to interact with the printer. |
System::Drawing::Text |
This namespace provides advanced font and font family |
|
functionality. |
|
|
Primarily, most of the functionality that you’ll be working with is found in the classes and structures in the System::Drawing namespace (see Table 11-2).
Table 11-2. Key System::Drawing Namespace Classes and Structures
Class/Structure |
Description |
Bitmap |
A class that represents and provides limited manipulation capabili- |
|
ties for an image file with formats such as .bmp, .gif, and .jpg |
Brush |
A class used to specify the color and pattern to fill the interior of a |
|
shape such as a rectangle, ellipsis, or polygon |
Brushes |
A class made up of several static properties of predefined brushes |
Color |
A structure that represents a color |
Font |
A class that represents a font |
FontFamily |
A class that defines a group of fonts with the same basic design |
Graphics |
The core class of GDI+ that represents a drawing surface where you |
|
will place your text, shapes, and images |
Icon |
A class that represents a Windows icon |
Image |
An abstract base class used in all image type classes such as bitmaps |
|
and icons |
Pen |
A class used to specify the color, thickness, and pattern used to |
|
outline shapes |
Pens |
A class made up of several static properties of predefined pens |
C H A P T E R 1 1 ■ G R A P H I C S U S I N G G D I + |
447 |
Table 11-2. Key System::Drawing Namespace Classes and Structures
Class/Structure |
Description |
Point, PointF |
A structure that represents an x, y coordinate as either a pair of |
|
Int32s or Singles |
Rectangle, RectangleF |
A structure that represents the size and location of a rectangle using |
|
either Int32 or Single values |
Region |
A sealed class that describes a geometric shape using rectangles |
Size, SizeF |
A structure that represents a size as either a pair of Int32s or Singles |
SolidBrushes |
A class that defines a Brush that fills a shape with a solid color |
StringFormat |
A sealed class that specifies the layout information such as align- |
|
ment, formatting, and line spacing for a set of text |
SystemBrushes |
A class made up of several static properties of SolidBrushes using |
|
system colors |
SystemColors |
A class made up of several static properties of system colors |
SystemFonts |
A class made up of several static properties of system fonts |
SystemIcons |
A class made up of several static properties of Windows system icons |
SystemPens |
A class made up of several static properties of Pens using system colors |
TextureBrush |
A class that represents a Brush that uses an image to fill a shape interior |
|
|
All of the functionality of GDI+ is located within the System.Drawing.dll assembly. Thus, you need to reference it at the top of your source code with the following #using statement:
#using <System.Drawing.dll>
■Note If you are using Visual Studio 2005 to do your Win Forms development, System.Drawing.dll is automatically added as a reference.
“Hello World!” GDI+ Style
Why break a trend I’ve set in the book? Here’s “Hello World!” again (see Listing 11-1). This time it’s using GDI+ to render the “Hello World” text.
Listing 11-1. “Hello World!” GDI+ Style
namespace |
HelloGDI |
{ |
|
using |
namespace System; |
using |
namespace System::ComponentModel; |
using |
namespace System::Collections; |
using |
namespace System::Windows::Forms; |
using |
namespace System::Data; |
using |
namespace System::Drawing; |