Pro Visual C++-CLI And The .NET 2.0 Platform (2006) [eng]-1
.pdf428 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
(cli::safe_cast<System::ComponentModel::ISupportInitialize^> (this->eProvider))->BeginInit();
this->SuspendLayout();
//
// tbPword
//
this->tbPword->Location = System::Drawing::Point(103, 83); this->tbPword->Name = L"tbPword"; this->tbPword->PasswordChar = '*';
this->tbPword->Size = System::Drawing::Size(100, 20); this->tbPword->TabIndex = 9; this->tbPword->Validating +=
gcnew System::ComponentModel::CancelEventHandler(this, &Form1::textbox_Validating);
//
//lbPword
this->lbPword->AutoSize = true;
this->lbPword->Location = System::Drawing::Point(34, 83); this->lbPword->Name = L"lbPword";
this->lbPword->Size = System::Drawing::Size(53, 13); this->lbPword->TabIndex = 8;
this->lbPword->Text = L"&Password";
//bnLogin
//
this->bnLogin->Location = System::Drawing::Point(75, 131); this->bnLogin->Name = L"bnLogin";
this->bnLogin->Size = System::Drawing::Size(75, 23); this->bnLogin->TabIndex = 7;
this->bnLogin->Text = L"&Login"; this->bnLogin->Click +=
gcnew System::EventHandler(this, &Form1::login_Click);
//
// tbName
//
this->tbName->Location = System::Drawing::Point(103, 31); this->tbName->Name = L"tbName";
this->tbName->Size = System::Drawing::Size(100, 20); this->tbName->TabIndex = 6;
this->tbName->Validating +=
gcnew System::ComponentModel::CancelEventHandler(this, &Form1::textbox_Validating);
//
// lbName
//
this->lbName->AutoSize = true;
this->lbName->Location = System::Drawing::Point(34, 31); this->lbName->Name = L"lbName";
this->lbName->Size = System::Drawing::Size(35, 13); this->lbName->TabIndex = 5;
this->lbName->Text = L"&Name";
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 |
429 |
//
//eProvider
this->eProvider->ContainerControl = this;
//Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(237, 185); this->Controls->Add(this->tbPword); this->Controls->Add(this->lbPword); this->Controls->Add(this->bnLogin); this->Controls->Add(this->tbName); this->Controls->Add(this->lbName);
this->Name = L"Form1"; this->Text = L"System Login";
(cli::safe_cast<System::ComponentModel::ISupportInitialize^> (this->eProvider))->EndInit();
this->ResumeLayout(false); this->PerformLayout();
}
#pragma endregion
private:
System::Void textbox_Validating(System::Object^ sender, System::ComponentModel::CancelEventArgs^ e)
{
try
{
TextBox ^tb = (TextBox^)(sender);
if (tb->Text->Equals(""))
eProvider->SetError(tb, "**Error** Missing Entry!"); else
eProvider->SetError(tb, "");
}
catch (Exception^)
{
// Not TextBox
}
}
System::Void login_Click(System::Object^ sender, System::EventArgs^ e)
{
if (tbName->Text->Equals(""))
eProvider->SetError(tbName, "**Error** Missing Entry!");
else
eProvider->SetError(tbName, "");
430 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
if (tbPword->Text->Equals(""))
{
// Place the icon left side of control eProvider->SetIconAlignment(tbPword,
ErrorIconAlignment::MiddleLeft); eProvider->SetError(tbPword, "**Error** Missing Entry!");
}
else
eProvider->SetError(tbPword, "");
}
};
}
Figure 10-12 shows what ErrorProviderEx.exe looks like when you execute it.
Figure 10-12. The ErrorProvider control
NotifyIcon
If you’ve tried to add an icon to the notification area in your past life, you know that it wasn’t a simple task. Well, with the .NET Framework, it is. All it takes is a drag and drop of the NotifyIcon control from the Toolbox view to the Design view.
The NotifyIcon control also provides four properties that you’ll probably change:
•Icon is an Icon object that represents the icon to display on the notification area. The default is null, which causes no icon to be displayed. (Why someone would do this, I’m not sure.)
•Text is a String that represents the ToolTip text to be displayed when the mouse pauses over the icon in the notification area. The default is null, which causes no text to be displayed.
•ContextMenu is a ContentMenu object that represents a pop-up menu displayed when the icon is right-clicked. The default is null, which causes no menu to be displayed. (I cover ContentMenus earlier in this chapter.)
•Visible is a Boolean that represents whether the icon is displayed in the notification area. The default is true, which displays the icon.
Listing 10-11 shows the NotifyIcon control in action. To give the example some life, I added two buttons. The first toggles the icon in the notification area, and the second toggles the program display in the taskbar. When you write your own program, you may want to display either in the notification area or in the taskbar, but not in both. I also added a context menu so that you can exit the application if you happen to minimize the application while the taskbar icon is turned off.
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 |
431 |
Listing 10-11. The NotifyIcon Control
namespace |
NotifyIconEx |
{ |
|
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::Button^ bnTaskBar; System::Windows::Forms::Button^ bnNotify; System::Windows::Forms::NotifyIcon^ notifyIcon; System::Windows::Forms::ContextMenuStrip^ menuExit; System::Windows::Forms::ToolStripMenuItem^ miExit; System::ComponentModel::IContainer^ components;
#pragma region Windows Form Designer generated code
void InitializeComponent(void)
{
this->components = (gcnew System::ComponentModel::Container()); System::ComponentModel::ComponentResourceManager^ resources =
(gcnew System::ComponentModel::ComponentResourceManager(Form1::typeid)); this->bnTaskBar = (gcnew System::Windows::Forms::Button()); this->bnNotify = (gcnew System::Windows::Forms::Button()); this->notifyIcon =
(gcnew System::Windows::Forms::NotifyIcon(this->components)); this->menuExit =
(gcnew System::Windows::Forms::ContextMenuStrip(this->components)); this->miExit = (gcnew System::Windows::Forms::ToolStripMenuItem()); this->menuExit->SuspendLayout();
this->SuspendLayout();
432 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
//
//bnTaskBar
this->bnTaskBar->Location = System::Drawing::Point(28, 59); this->bnTaskBar->Name = L"bnTaskBar";
this->bnTaskBar->Size = System::Drawing::Size(131, 23); this->bnTaskBar->TabIndex = 3;
this->bnTaskBar->Text = L"Toggle TaskBar Icon"; this->bnTaskBar->Click +=
gcnew System::EventHandler(this, &Form1::bnTaskBar_Click);
//bnNotify
//
this->bnNotify->Location = System::Drawing::Point(28, 12); this->bnNotify->Name = L"bnNotify";
this->bnNotify->Size = System::Drawing::Size(131, 23); this->bnNotify->TabIndex = 2;
this->bnNotify->Text = L"Toggle Notify Icon"; this->bnNotify->Click +=
gcnew System::EventHandler(this, &Form1::bnNotify_Click);
//
//notifyIcon
this->notifyIcon->ContextMenuStrip = this->menuExit; this->notifyIcon->Icon = (cli::safe_cast<System::Drawing::Icon^>
(resources->GetObject(L"notifyIcon.Icon"))); this->notifyIcon->Text = L"Notify Icon Example";
this->notifyIcon->Visible = true;
//menuExit
//
this->menuExit->Items->AddRange(
gcnew cli::array< System::Windows::Forms::ToolStripItem^>(1) {this->miExit});
this->menuExit->Name = L"miExit"; this->menuExit->RightToLeft =
System::Windows::Forms::RightToLeft::No; this->menuExit->Size = System::Drawing::Size(153, 48);
//
//miExit
this->miExit->Name = L"miExit";
this->miExit->Size = System::Drawing::Size(152, 22); this->miExit->Text = L"E&xit";
this->miExit->Click +=
gcnew System::EventHandler(this, &Form1::miExit_Click);
//Form1
//
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 |
435 |
3.Select the Windows Form (.NET) icon from the Templates panel and give the dialog box a name. I used MyDialog.
4.Click Open. This will provide you with an empty form in the Design view.
5.Build the form exactly as you do the main form.
You can now work with this form in exactly the same way as you do with the application’s main form, except for a couple of minor things.
The first minor difference is that if you want to pass information to the dialog box or get information back from the dialog box, you need to add properties to your form to get and set the information:
public:
property String^ PassedValue1; // Trival
// or
Property String^ PassedValue2
{
void set(String^ value)
{
tbPassedValue->Text = value;
}
String^ get()
{
return tbPassedValue->Text;
}
}
Another method of doing this would be to change the constructor to send data to the dialog box, but I prefer properties. Plus, if you use the constructor to pass data to the dialog box, you still need to create properties or methods to send data back, so why not bite the bullet and use properties in both cases? This method is clean and safe (because you can verify the validity of the passed data) and it’s easy to use.
The second change that you can make, which is totally optional, is to change the style of the dialog box to look more like a dialog box and less like a form:
this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedToolWindow;
// Or this->FormBorderStyle =
System::Windows::Forms::FormBorderStyle::SizableToolWindow;
The third difference is that you want to have any buttons that close your dialog box return a DialogResult. The .NET Framework class library provides a number of possible DialogResults (see Table 10-2).
Table 10-2. DialogResults
Type |
Description |
Abort |
Returns the value Abort. Usually you will have a button labeled Abort to |
|
handle this. |
Cancel |
Returns the value Cancel. This is the value returned when the Esc key is pressed (if |
|
enabled) or the close dialog box button is clicked. Also, you will have a button on |
|
the form labeled Cancel. |
436 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
Table 10-2. DialogResults (Continued)
Type |
Description |
Ignore |
Returns the value Ignore. Usually you will have a button labeled Ignore to |
|
handle this. |
No |
Returns the value No. Usually you will have a button labeled No to handle this. |
None |
Returns nothing. You will use this with a modal dialog box, which is discussed later |
|
in this section. |
OK |
Returns the value OK. This is the value returned when the Enter key is pressed (if |
|
enabled). Also, you will have a button on the form labeled OK. |
Retry |
Returns the value Retry. Usually you will have a button labeled Retry to |
|
handle this. |
Yes |
Returns the value Yes. Usually you will have a button labeled Yes to handle this. |
|
|
To return a DialogResult value to the calling form, you need to assign to the button that will end the dialog the desired DialogResult value:
bnOK->DialogResult = DialogResult::OK;
When the button is clicked, it will automatically return the DialogResult it was set to (DialogResult::OK is set in the preceding code). By the way, you can still handle the Click event, if you need to, for the button. (You can even change its DialogResult in the handler if you really want to. For example, you could turn DialogResult::OK into DialogResult::Cancel if no text is entered in the dialog box.)
The final change you are probably going to want to make is to assign default buttons to respond to the Accept and Cancel conditions. You do this by assigning a button to the form’s AcceptButton and CancelButton properties:
AcceptButton = bnOK;
CancelButton = bnCancel;
Once you have performed the preceding additional steps, you have a complete custom dialog box. Listing 10-12 shows the code of a custom dialog box that takes in some text, places it in a text box, allows it to be updated, and then returns the updated text to the calling form. The dialog box also allows the user to abort or cancel the dialog box.
Listing 10-12. The MyDialog.h File
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 |
437 |
namespace CustomDialog
{
public ref class MyDialog : public System::Windows::Forms::Form
{
public:
MyDialog(void)
{
InitializeComponent();
}
protected:
~MyDialog()
{
if (components)
{
delete components;
}
}
public:
property String^ PassedValue // PassedValue property
{
void set(String ^value)
{
tbPassedValue->Text = value;
}
String ^get()
{
return tbPassedValue->Text;
}
}
private:
System::Windows::Forms::Button^ bnCancel; System::Windows::Forms::Button^ bnAbort; System::Windows::Forms::Button^ bnOK; System::Windows::Forms::TextBox^ tbPassedValue; System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
void InitializeComponent(void)
{
this->bnCancel = (gcnew System::Windows::Forms::Button()); this->bnAbort = (gcnew System::Windows::Forms::Button()); this->bnOK = (gcnew System::Windows::Forms::Button()); this->tbPassedValue = (gcnew System::Windows::Forms::TextBox()); this->SuspendLayout();