|
|
 |

 |
|
Microsoft® Visual C++® .NET Step by Step--Version 2003
|
|
|
Author
|
|
Julian Templeman, Andy Olsen
|
|
|
Pages
|
608
|
|
Disk
|
1 Companion CD(s)
|
|
Level
|
Beg/Int
|
|
Published
|
03/26/2003
|
|
ISBN
|
9780735619074
|
|
Price
|
$39.99
To see this book's discounted price, select a reseller below.
|
|
|
|
|
 |
|
|
Chapter 16: Introducing Windows Forms
16 Introducing Windows Forms
In this chapter, you will learn how to:
- What Microsoft Windows Forms is
- What the System::Windows::Forms namespace contains
- How to create and use forms in applications
- How to handle events
- How to use the basic controls
- How to use menus
- How to execute and debug Windows Forms applications
Windows Forms is a powerful feature of the Microsoft Windows .NET Framework that provides a set of classes for building GUI applications. In contrast to most other GUI libraries, Windows Forms can be used from any .NET language, and you can now easily build mixed-language graphical applications.
Windows Forms is a large and complex subject, encapsulating the whole of writing GUI applications. The subject is worth a book in its own right, so the following two chapters can only scratch the surface to give you a taste of how Windows Forms operates and how you can use it to write GUI applications.
Windows Forms Applications
If you've ever programmed in Microsoft Visual Basic, the idea behind Windows Forms will be familiar to you. In fact, for the .NET Framework, Microsoft has taken the Visual Basic GUI programming model, complete with forms, controls, and properties, and generalized it so that it can be used from any .NET language.
A Windows Forms application consists of one or more windows called forms. These might be top-level windows, child windows, or dialog boxes, and an application might support many different forms. You place controlssuch as buttons and list boxesonto a form to build the GUI for your program. A simple form is shown in the following figure.

Click to view graphic
This form is a top-level window that is resizable and has a title bar; it also has Minimize, Maximize, and Close buttons on the right and a system menu button on the left. It contains a selection of common controls, including a button, radio buttons, a group box, and a combo box.
Windows Forms and Designers
Although you can write code to generate forms, you will normally use designers to create the user interface. Microsoft Visual Studio .NET supports graphical GUI construction using designers, which put a form on the screen and let you drag components from a Toolbox and drop them onto the form. A Properties editor lets you set the properties of forms and controlssuch as color and textand makes it easy to add event handlers. This way of developing forms will be familiar to anyone who has used Visual Basic in the past.
Forms are always constructed at run time by executing code, and designers simply take what you do on the screen and generate code underneath, which will create the user interface for you at run time. If you open a Visual Basic or C# project and look at the source code, you'll see a section labeled "Windows Form Designer generated code," which contains that code.
There was no designer for Microsoft Visual C++ included in the first release of Visual Studio .NET, so you had to create and populate forms yourself by writing code. Version 7.1 includes a C++ designer, so you can develop GUI applications in the same way that you would in Visual C# or Visual Basic .NET.
Windows Forms vs. MFC
Since its earliest days, Visual C++ has shipped with a library called MFC (Microsoft Foundation Classes). This library is used for writing C++ applications for Microsoft Windows, and it encapsulates mostly that part of the Windows API that deals with GUI programming, along with some other areas such as databases and networking.
MFC has become a standard for writing Windows applications in Visual C++. The latest version ships with Visual Studio .NET, and there's a lot of MFC code still around. It has nothing to do with .NET, however, and you probably won't want to use it for new Windows development in C++.
However, you still might need to use MFC when
- You have an MFC application, and you aren't updating it (or can't update it) to use Windows Forms.
- You've got to use some existing MFC components.
- You really like the MFC Document-View architecture, which isn't supported in the .NET Framework.
In the vast majority of cases, though, you'll want to use the .NET Framework. The object-oriented coverage of the Windows API is more complete, and it's better object-oriented code. Plus, mixed-language programming is easy with .NET.
A Word About ATL
While on the subject of C++ libraries for Windows programming, I'll also mention the other major Microsoft offering, the Active Template Library (ATL). ATL is a C++ library for writing the smallest, fastest COM objects possible. As such, it's a very specialized library, and few people will need to use it now that the .NET Framework has made COM less of a mainstream technology.
The System::Windows::Forms Namespace
The Windows Forms classes are provided in two namespaces: System::Windows::Forms and System::Windows::Forms::Design. The second of these contains classes for design-time use, which typically means customizing and extending the designers used in Visual Studio .NET. Because this namespace is more advanced than we have time or space for here, I won't mention this namespace again.
System::Windows::Forms is a very large namespace, containing more than 300 classes and enumerations. The following table shows some of the major members of this namespace, and you'll meet lots more during the rest of this chapter.
| Name | Description |
| Application | Provides static methods to manage applications, including starting and stopping them, and getting information about them. |
| AxHost | Provides a way to host ActiveX controls in Windows Forms applications. |
| BorderStyle | An enumeration that specifies the border style for controls. BorderStyle has three members: Fixed3D for three-dimensional borders, FixedSingle for simple line borders, and None for no border. |
| Button | Represents a Windows button control. |
| ButtonState | An enumeration that specifies the appearance of a button. Members include Inactive, Pushed, and Normal. |
| CheckBox | Represents a Windows check box control. |
| Clipboard | Lets you place data onto and retrieve it from the system clipboard. |
| ColorDialog | Displays a standard dialog box to let the user pick a color. |
| ComboBox | Represents a Windows combo box control. |
| Cursor | Represents a cursor. |
| DataGrid | Displays ADO.NET data in a scrollable grid. |
| DateTimePicker | Represents a Windows date-time picker control. |
| Form | Represents a window or a dialog box. |
| HScrollBar | Represents a Windows horizontal scroll bar control. |
| ImageList | Represents a collection of images typically used by toolbars. |
| Label | Represents a Windows label control. |
| ListBox | Represents a Windows list box control. |
| ListView | Displays a list of items in one of four views. |
| Menu | Represents a menu. |
| MessageBox | Displays a message box. |
| Panel | A control that can contain other controls. |
| ProgressBar | Represents a Windows progress bar control. |
| RadioButton | Represents a Windows radio button control. |
| Splitter | Provides splitter functionality to a window. |
| StatusBar | Represents a Windows status bar control. |
| TextBox | Represents a Windows edit control. |
| ToolBar | Represents a Windows toolbar control. |
Creating and Using Forms
Because Visual C++ .NET now has a GUI designer, you no longer have to construct GUI code by hand. This section will show you how to create and use forms using Visual Studio .NET 2003.
Creating a Simple Form
The following exercise shows you how to create and display a simple form.
- Start Visual Studio .NET, and open the New Project dialog box. Choose the .NET subfolder under the Visual C++ Projects entry, and create a new Windows Forms Application project named CppForm. Visual Studio .NET will display a form designer window like the one shown in the following figure.

Click to view graphic
- Compile and run the code. A window will be displayed, as shown in the following figure.

Click to view graphic
You can see how the form has all the attributes of a window: it has a title bar with a caption and a system menu button on the left; it has Minimize, Maximize, and Close buttons; and you can resize it. The size and caption are set by properties in the C++ code. Right-click the form displayed in the designer, and choose View Code from the context menu. This will display the code for Form1.h. If you examine the code in the InitializeComponent function, you'll see where the Size and Text properties are set. You'll see later in the chapter how to use the Properties editor to change these properties.
- Click the Close buttonthe one marked with an X on the far right of the title barto close the window. This terminates message processing, and closes the window.
Using Form Properties
Now that you've mastered the basics of displaying a form, let's move on to see how you can affect the way the form looks and behaves. When you examine the code in Form1.h, you'll see that the form is represented by a class that inherits from System::Windows::Forms::Form. You use this class as the base class whenever you want to create a form.
The Form class has a large number of properties and methods, the most important of which are summarized in the following table.
| Name | Method or Property? | Description |
| AcceptButton | P | Gets or sets a reference to the button control that corresponds to the user pressing Enter. |
| Activate | M | Activates the window, bringing it to the front of the application's collection of windows. |
| ActiveForm | P | Gets the currently active form for this application, meaning the one at the front of the application's collection of windows. |
| AutoScale | P | Gets or sets a Boolean value indicating whether the form adjusts its size to fit the height of the font used on the form and scales its controls accordingly. The default is true. |
| AutoScroll | P | Gets or sets a value indicating whether the form displays scroll bars when controls fall outside the displayable area. The default is true. |
| CancelButton | P | Gets or sets a reference to the button control that corresponds to the user pressing Esc. |
| ClientSize | P | Gets or sets the size of the client area of the form. (The client area is the portion of the form that excludes the title bar and borders.) |
| Close | M | Closes the form and frees any resources the form has used. |
| DesktopLocation | P | Gets or sets the location of the form on the Windows desktop. |
| FormBorderStyle | P | Gets or sets the border style of the form. The default is FormBorderStyle::Sizeable. |
| HelpButton | P | Gets or sets a Boolean value indicating if the form is to display a Help button on the title bar. The default is false. |
| Icon | P | Gets or sets the icon associated with the form. |
| MaximizeBox | P | Gets or sets a Boolean value that indicates if the form is displaying a Maximize box on the title bar. The default is true. |
| Menu | P | Gets or sets a reference to the menu that is displayed on this form. |
| MinimizeBox | P | Gets or sets a Boolean value that indicates if the form is displaying a Minimize box on the title bar. The default is true. |
| OwnedForms | P | Holds the collection of child forms owned by this form, if any. |
| SetDesktopLocation | M | Sets the location of the form on the desktop. |
| ShowDialog | M | Shows the form as a modal dialog box. |
| ShowInTaskBar | P | Gets or sets a Boolean value, which is true if the form is to be shown in the Windows taskbar. The default is true. |
| Size | P | Gets or sets the form's size. |
| SizeGripStyle | P | Determines how (or even whether) the sizing grip is shown at the lower right of the form. The default is SizeGripStyle::Hide. |
| TopLevel | P | Gets or sets a Boolean value, which is true if the form is a top-level window, meaning that it has no parent other than the Windows desktop. The default is true. |
| TopMost | P | Gets or sets a Boolean value, which is true if the form is a topmost window, meaning it is always displayed on top of other windows, even when it doesn't have the focus. The default is false. |
| WindowState | P | Gets or sets the form's window state, which determines how the form is displayedminimized, maximized, or normal. The default is FormWindowState::Normal. |
The Form class also has a very large number of methods and properties that it inherits from its base classes, which are shown here:
Object MarshalByRefObject Component Control ScrollableControl ContainerControl Form
Notice especially the Component class, which forms the basis for all components that can be used with forms, and Control, which provides the base class for all visual components. All the base classes between them provide Form with approximately 110 properties, 180 methods, and 70 events! There are far too many to list here, so I suggest that you consult the .NET Framework documentation for more details. When I use inherited properties in the exercises or examples in this chapter, I'll tell you which base class they come from.
Although you can interact with the form's properties in code, the designer provides a Properties editor that gives you graphical access to all the most frequently used properties.
The following exercise will show you how to use the Properties editor to edit the properties of a form so that you can make it appear where and how you want.
- Continue with the previous application, making sure that the design window is displayed. If the design window is not open, click the Form1.h file in Solution Explorer. You'll see that the form header file has a different icon from the other header and source files because it is the file that contains the definition of the form, and it's the file that is used by the designer.
Right-click the form, and choose Properties from the context menu. The Properties editor will be displayed. Select the Text property, and change its value to give a suitable caption to the form, as shown in the following figure.

Click to view graphic
The Text property is inherited from Control, and it's being used here to set the text associated with the control. Many controls have some notion of an associated piece of text. In the case of an edit control, it's the text in the control; in the case of a button, it's the legend on the button. In the case of a form, it's the title displayed on the title bar of the form.
If you rebuild and run the code, you'll see that the form now displays a caption.

Click to view graphic
- The form border is represented by the FormBorderStyle property, which takes its value from the FormBorderStyle enumeration. The default border style is FormBorderStyle::Sizeable, which provides a simple border whose outline you can drag to change the size of the form. Use the Properties editor to change the border style to Fixed3D.
- Compile and run the code, and you'll see that the border style has changed and you can no longer resize the window, as shown in the following figure.

Click to view graphic
Experiment with other Form properties to change the look and feel of the form.
Form Relationships
Any form can create other formsthink of displaying a dialog boxand by default, forms will be independent of one another so that you can minimize them and close them separately. There will be a parent/child relationship between the forms, but apart from that relationship, they are independent. Top-level forms, which are usually used for an application's main window, either do not have a parent form or have the desktop as a parent.
It's also possible for one top-level form to be the owner of another top-level form, in which case there is a relationship between the two forms such that:
- The owned form is minimized, maximized, and hidden along with its owner.
- The owned form is closed when the owner form is closed.
- The owned form never displays behind the owner form.
Think of the Find And Replace dialog box in Microsoft Word. This window appears when you want to find something in the document, and it hovers over the Word window until you close it. If you minimize Word, the dialog box is minimized, and it disappears when you close Word.
Placing Controls on the Form
Now that you know how to create forms and set their properties, let's examine how to add controls to a form. The following exercise will walk you through adding two buttons to the form, and the same procedure can be applied to many other controls.
- Continue with the same Windows Forms project that was used in the previous two exercises.
- Make sure that the designer window is open, and open the Toolbox. If the Toolbox is not already visible, you can open it by using the Toolbox item on the View menu or by pressing Ctrl+Alt+X. If the Windows Forms tab is not open on the Toolbox, select it. Selecting this tab will display all the controls that can be used with Windows Forms.

Click to view graphic
Click the Button entry in the Toolbox, and drag it onto the form. When you release the mouse button, you will see a button appear on the form.
- Select the button, and use the Properties editor to set its Name to btn1, its Text to OK, its Size to 70,25, and its Location to 130,225. The coordinates for Location are in pixels, relative to the upper-left corner of the form containing the button. If you examine the code in Form1.h and look at the InitializeComponent function, you will see that code has been added to create and set up the button. The designer changes the code in the InitializeComponent function as you edit the form, so you should be very careful about editing InitializeComponent yourself.
Notice how the button has been added to the Controls property of the form. Every container (such as a form) has a Controls property that contains references to all the controls currently hosted by the form. By adding a control to the collection, the form will display it and will treat it as an owned window.
- Add a second button to the form, and name it btn2. Make it display Cancel for the text, and make the size the same, but change the Location so that this one displays at (210,225).
Compile and run the code, and you should see two buttons displayed on the form, as shown in the following figure.

Click to view graphic
Handling Events
It isn't much use placing buttons on a form unless you can make them do something, so let's take a look at how to handle the events that are fired by controls. The .NET event mechanism was covered in Chapter 14, so you might review that material now if you want to refresh your memory.
To handle an event, you need to create an event handler function and attach it to the event source. In Chapter 14, you saw how to do this with custom event source and receiver classes, and now I'll show you how to do it with standard event sources in the form of controls.
The following exercise, which follows on from the last one, shows you how to add event handlers for the buttons on the form.
- Continue with the project from the previous exercise. The form currently contains two buttons, and you're going to add handlers for the Click events that are raised when the buttons are clicked.
Select the OK button, and bring up the Properties editor. Click on the Event button at the top of the Properties editor windowthe button with a lightning bolt as a symboland the editor will show the events associated with the button. Find the Click event in the left-hand column, and double-click in the blank space to the right of it. The name btn1_Click will be inserted into the space, and a function with the same name will be added to the code.
- This function is called when the button is clicked, and just to prove that the handler is called, add a line to display a message box, as shown here:
private: System::Void btn1_Click(System::Object * sender, System::EventArgs * e) { MessageBox::Show(S"It worked!", S"Message..."); }
The MessageBox class is part of the Forms namespace, and its one Show method is used to display a standard Windows message box. Show has a dozen overloads that take different combinations of arguments, and the one I'm using specifies only the message and title. This message box will display without an icon and with a single OK button.
- If you look in InitializeComponent, you can see how the button has been made aware of the handler.
this->btn1->Click += new System::EventHandler(this, btn1_Click);
From the discussion of events in Chapter 14, you'll recall that event handlers are connected with event sources by delegates. There are several different event handlers associated with controls (we'll meet some of them later in the chapter), but the delegate used for controls that don't pass back any data is called EventHandler, and this event delegate passes back a plain EventArgs object.
So, to connect an event handler to the button object, a new EventHandler is created, which is passed a pointer to the object that is going to handle the event and the address of the event-handling function within the object. In this case, the event is being handled within the form object, so the this pointer is passed for the first argument and the address of the btn1_Click function as the second.
The event handler is registered with the source by using the += operator to link the handler to the button's Click event.
- Try building and testing the application. You should see a message box like the one shown in the following figure when you click OK.

Click to view graphic
Note that the message box is modal: you can't return to the application until you've sent the message box away by clicking OK.
- Try adding a similar handler for the Cancel button.
Using Controls
Now that you've seen the basics of adding controls to forms and handling events, let's look at some of the controls that are available for you to use in Windows Forms applications. This section will look at the most fundamental controls, and Chapter 17 will deal with other controls in more detail. All these controls inherit from the Component and Control classes, which gives them a very large number of methods and properties in common.
Label
A label is a control that is used to provide descriptive text on a form. Users don't normally interact with label controls, and these controls don't usually receive the input focus, so it's unusual for programs to handle events originating from labels.
Using labels mainly consists of creating them and then setting their properties. The following table shows the most commonly used properties of the Label class.
| Label Property | Description |
| AutoSize | Determines whether the label automatically resizes itself to fit the text. |
| BackColor (inherited from Control) | Represents the background color of the label. |
| BorderStyle | Gets or sets the style of the label border: three-dimensional, single, or none. |
| FlatStyle | Determines whether the label has a flat appearance. |
| Font (inherited from Control) | Represents the font for the control. |
| ForeColor (inherited from Control) | Represents the foreground color of the label. |
| Image | Gets or sets the image associated with the label. |
| ImageAlign | Represents the alignment of the image on the label. The default is centered. |
| ImageIndex | The index of the image to be used from the associated ImageList. |
| ImageList | The ImageList to be used as a source of images for this label. |
| PreferredHeight | Gets the height necessary to display one line of text. |
| PreferredWidth | Gets the width necessary to display the current text. |
| RenderTransparent | Determines whether the container's background will be displayed as the background to the label. |
| TabStop | Determines whether the user can tab to this control. |
| Text | Represents the text of the label. |
| TextAlign | Gets or sets the text alignment. The default is left aligned. |
| UseMnemonic | Determines whether ampersand (&) characters in the text should be interpreted as access keys. |
There are a couple of items in the table worth explaining in more detail.
Labels do participate in the tab order on forms but don't usually receive the focus. If you want to give the focus to a label for some reason, set the TabStop property to true. In addition, ampersand (&) characters normally aren't interpreted as access keys as they are in menus, where the presence of an ampersand underlines the following character rather than displays the ampersand. If you want ampersands to be interpreted as access keys, set the UseMnemonic property to true.
Labels can display an image as well as (or instead of) text, and the Image property represents the image currently associated with the label. You can also use images stored in ImageList controls, via the ImageList and ImageIndex properties.
The following exercise shows you how to add a label to a form and how to manipulate the label's properties.
- Continue using the CppForm project. Open the Toolbox, and drag a Label onto the form. You can leave the control name as label1.
- Set the Text of the label to Acme Consulting, Inc., and set its AutoSize property to true. If you have carried straight on from the previous exercise, you will need to press the Properties button at the top of the Properties editor so that it displays properties instead of events.
Make sure that there are three spaces before the word Acme; you are going to display an image at the left of the label, and you need to leave space so that it doesn't overlap with the start of the text. Setting the AutoSize property to true means that the label will resize itself to contain whatever text is assigned to it.
- Now set up the font details for the label. Check that the ForeColor property is set to ControlText, which defaults to black. Then find the Font property, and click the plus sign (+) to the left to expand the Font property items. Use the drop-down list to set the Name to Verdana, set Italic to true, and set the Size to 16.
- Set the Location of the Label to be 20,20.
- Now add an image to the label. Find the Image property in the Properties editor, and use the Browse button to find a suitable bitmap for display. I've provided a small bitmap of a floppy disk, called Floppy.bmp, which you can find in the CppForm project directory. When you have selected the image, set the ImageAlign property to MiddleLeft, which specifies middle alignment vertically and left alignment horizontally. When you click the down-arrow button to the right of the ImageAlign value, you will be given a graphical way to choose the alignment.
- Build and run the program, and you'll see a label containing text and an image being displayed at the top of the form, as shown in the following figure.

Click to view graphic
Button
You've already met the Button class earlier in the chapter, and you've seen how to add buttons to forms. A Button represents a Windows button on a form and, next to Label, it's probably the simplest of the commonly used Windows controls.
The most frequently used properties of the Button class are listed in the following table.
| Button Property | Description |
| DialogResult | Represents the value that is returned to the parent form when the button is clicked. |
| Flattyle (inherited from ButtonBase) | Determines whether the button is drawn with a flat style. |
| Image (inherited from ButtonBase) | Gets or sets the image displayed on the button. |
| ImageAlign (inherited from ButtonBase) | Gets or sets the image alignment. The default value is MiddleCenter. |
| IsDefault (inherited from ButtonBase) | Determines whether the button is the form's default button. |
| TextAlign (inherited from ButtonBase) | Gets or sets the alignment of the text on the button. |
A button on a form can be designated the default button, in which case it is displayed with a darker border than other buttons on the form. If the user presses Enter, it's taken to be equivalent to clicking the default button.
Forms that are used as dialog boxes use buttons to close the dialog box and return a value to the caller. The DialogResult property can be used to assign a result code (such as OK or Cancel) to the form, and clicking a button that has a DialogResult set will close the parent form without you having to hook up any event handlers.
CheckBox and RadioButton
If you look at the .NET Framework documentation, you'll find that Button, CheckBox, and RadioButton all have the same base class, ButtonBase. This shared base class is because all three classes are different types of button, each sharing the same on/off functionality but contributing their own special characteristics.
| Property | Description |
| AutoCheck | Determines whether the appearance of the control automatically changes when the user clicks it (as opposed to being set from code). |
| CheckAlign | Represents the alignment of the check box. The default is MiddleLeft. |
| Checked | Represents the check state of the control, with true representing checked. |
| CheckState (CheckBox only) | Represents the state of the checkbox: checked, unchecked, or indeterminate (appears dimmed). |
| Image (inherited from ButtonBase) | Gets or sets the image displayed on the button. |
| ImageAlign (inherited from ButtonBase) | Gets or sets the image alignment. The default value is MiddleCenter. |
| ThreeState (CheckBox only) | If true, the check box can display three states: checked, unchecked, or indeterminate. |
CheckBox and RadioButton can both fire events when the Appearance and Checked properties change, and CheckBox also fires an event if the CheckState changes.
Using Radio Buttons as a Group
It's common to use radio buttons to let users select one of a set of options. To do so, you provide a set of radio buttons inside a group box control; the group box not only encloses the buttons visually, but also makes them act as a group, ensuring that when any one is selected, the others are deselected.
The following exercise shows you how to set up a group box containing radio buttons on a form.
- Continue with the CppForm project. Open the Toolbox, and drag a GroupBox onto the form. Use the Property Editor to change its Text to read Language, its Size to 200,104, and its Location to 24,64.
- Drag a RadioButton onto the form, and drop it inside the group box. You will see that the group box clips the radio button so that no part of the button shows outside the border of the group box. Position the radio button toward the top of the group box, and set its Text to Visual Basic.
- Add another two radio buttons to the group box, positioning them below the first. Set their Text properties to C# and C++, respectively.
- Build and test the application. You should see the radio buttons displaying inside the group box, and you should find that when you select one button, all the others are unchecked. By default, none of the buttons are checked when the application starts. To start with one of the buttons checked, use the Properties editor to set its Checked property to true.

Click to view graphic
ListBox and ComboBox
List boxes and combo boxes are common features of Windows applications, each representing a scrollable list of items. The ComboBox class differs from the ListBox class in that ComboBox is able to display an item in a TextControl above the list. These two classes have many features in common because they both derive from the ListControl class, which provides some common functionality.
The table below shows commonly used properties of the ListBox class.
| Property | Description |
| ColumnWidth | Gets or sets the width of columns in a multicolumn list box. |
| HorizontalScrollbar | Gets or sets a value indicating whether the control displays a horizontal scroll bar. |
| IntegralHeight | Set to true if the ListBox should resize itself so that it doesn't show partial items. |
| Items | Represents the collection of items held in the list box. |
| MultiColumn | Set to true if the list box supports multiple columns. The default is false. |
| PreferredHeight | Gets the combined height of all items in the list box. You can use this to resize the list box so that all items display without vertical scroll bars. |
| ScrollAlwaysVisible | If set to true, the vertical scroll bar will always be visible. |
| SelectedIndices | For multiselection list boxes, represents a collection of the indexes of all the items currently selected in the list box. |
| SelectedItem | Gets or sets the currently selected object in the list box. |
| SelectedItems | For multiselection list boxes, represents a collection of all the items currently selected in the list box. |
| SelectionMode | Represents the selection mode of the list. (SelectionMode is discussed in the following text.) |
| Sorted | Set to true if the items in the list box are to be sorted. The default is false. |
| Text | Represents the text of the currently selected item in the list box. If you set this property to a string, the control searches for the first item that matches the string and selects it. |
| TopIndex | The index of the top item visible in the control. |
The SelectionMode property represents the way users can select items from the list and can take one of the following values from the SelectionMode enumeration:
- SelectionMode::None, meaning that the user cannot select any items.
- SelectionMode::One, meaning that the user can select one item at a time. This is the default value.
- SelectionMode::MultiSimple, meaning that the user can select more than one item at a time.
- SelectionMode::MultiExtended, meaning that the user can use the Shift, Ctrl, and arrow keys to make selections.
ListBox also supports a number of methods, the most commonly used of which are summarized in the table below.
| Method | Description |
| BeginUpdate, EndUpdate | BeginUpdate prevents the list box from redrawing until EndUpdate is called. This improves the performance when adding several items. |
| ClearSelected | Deselects all the items in a list box. |
| FindString, FindStringExact | Finds the first item in the list box that starts with a given string or that exactly matches a given string. |
| GetSelected | Returns true if the item with the specified index is selected. |
| SetSelected | Sets or clears the selection for an item in the list box. |
The main event fired by the ListBox class is the SelectedIndexChanged event, which is fired when a user selects a new item in the list.
The ComboBox class has a similar set of methods and properties, as outlined in the two tables below.
| Property | Description |
| DropDownStyle | Represents the style of the combo box. |
| DropDownWidth | Represents the width in pixels of the drop-down box. |
| DroppedDown | Set to true if the list portion is currently displayed. |
| IntegralHeight | Set to true if the combo box should resize itself so that it doesn't show partial items. |
| Items | Represents the collection of items held in the combo box. |
| MaxDropDownItems | Represents the maximum number of items in the drop-down list. The value must be between 1 and 100. |
| MaxLength | Represents the maximum length of the text in the text box. |
| SelectedItem | Gets or sets the currently selected item. |
| SelectedText | Represents the currently selected text in the text box portion of the combo box control. |
| SelectionStart, SelectionLength | Gets or sets the start position and length of the selected text in the text box portion of the combo box control. |
| Sorted | Determines whether the list in the combo box is sorted. |
| Text | Gets or sets the text in the text box portion of the combo box control. |
A combo box can have one of the following three styles:
- ComboBoxStyle::DropDown, where the text box can be edited and the user must click the arrow to display the list. This is the default style.
- ComboBoxStyle::DropDownList, which is the same as DropDown, with the exception that the text box can't be edited.
- ComboBoxStyle::Simple, where the text box can be edited and the list is always visible.
| Method | Description |
| BeginUpdate, EndUpdate | BeginUpdate prevents the combo box from redrawing until EndUpdate is called. This improves the performance when adding several items. |
| FindString, FindStringExact | Finds the first item in the combo box that starts with a given string or that exactly matches a given string. |
| Select | Selects a range of text in the text box portion of the combo box. |
| SelectAll | Selects all the text in the text box portion of the combo box. |
As with ListBox, the main event fired by the ComboBox class is the SelectedIndexChanged event, which is fired when a user selects a new item in the list.
The exercise that follows will show you how to set up a combo box and respond to the events it fires, and you'll find that list boxes work in very much the same way.
- Open the CppForm project if it isn't already open.
- Drag a ComboBox from the Toolbox onto the form, and change its name to combo1.
- Set the DropDownStyle to DropDownList, which means that the user has to click the button to the right of the text box to display the list, and that the text in the text box can't be edited. The Text property is blanked out automatically.
- To add some strings to the combo box using the Properties editor, first find the Items property. Click the browse button to the right of the (Collection) string, which will display the String Collection Editor. Type in three valuesBeginner, Intermediate, and Advancedone per line, and press OK to dismiss the editor when you're done.
- To display the first string in the combo box when the application starts, you need to set the SelectedIndex property. This cannot be done using the Properties editor, so add the following line of code to the Form1 constructor in Form1.h, immediately after the call to InitializeComponent:
combo1->SelectedIndex = 0;
- The SelectedIndexChanged event will be fired whenever the user selects a new item in the drop-down list. Use the Properties editor to display the events for the combo box by pressing the Event button at the top of the editorthe one marked with a lightning symbol. Find the SelectedIndexChanged event, and double-click in the blank right-hand column. A handler function will be added to the form class. Edit the handler code as shown here:
private: System::Void combo1_SelectedIndexChanged( System::Object * sender, System::EventArgs * e) { if (sender == combo1) { String* ps = String::Concat(S"New index is ", __box(combo1->SelectedIndex)->ToString()); MessageBox::Show(ps, S"Index Change"); } }
The function checks that the sender was combo1, and if so, it builds a String containing the index of the new selection. The String is built using the static Concat function from the String class, and to convert the SelectedIndex value from an integer to a String, it is first boxed so that ToString can be called on the resulting object. The final string is displayed in a message box so that you can be sure the selection has happened.
- Build and run the project, and you'll see a combo box on the form that displays three items. You should also get a message box displayed whenever you select a new item.

Click to view graphic
TextBox
The System::Windows::Forms namespace has two edit control classes, both of which are derived from TextBoxBase. I'll look at TextBox in this section, and you'll find the more advanced RichTextBox class covered in Chapter 17.
A TextBox is a Windows edit control that provides a number of methods and properties to manipulate the text inside the control. TextBox actually inherits most of its methods and properties from TextBoxBase, and the following two tables list some of the most commonly used inherited members.
| Property | Description |
| AcceptsTab | If true, the Tab key will enter a tab character into the control instead of moving to the next control in the tab order. The default is false. |
| AutoSize | If true, the control automatically resizes itself to fit its text. The default is true. |
| BackColor, ForeColor | Represents the background and foreground colors. |
| BorderStyle | Represents the border style. The default is Fixed3D. |
| CanUndo | Set to true if the last operation can be undone. |
| HideSelection | If true, selected text in the control is dimmed when the focus passes to another control. |
| Lines | Gets or sets the collection of lines in a text box as an array of Strings. |
| MaxLength | Represents the maximum number of characters that can be typed into a control. The default value is 0, which means that the length is limited only by the available memory. |
| Modified | Gets or sets a Boolean value representing whether the control's content has been modified. |
| Multiline | If true, the control is a multiline text box. |
| PreferredHeight | Gets the preferred height in pixels for the current font. This enables you to size the text box so that it displays text correctly. |
| ReadOnly | Gets or sets the read-only status of the control. |
| SelectedText | Represents the currently selected text. |
| SelectionLength | Gets or sets the length of the selection. |
| SelectionStart | Gets or sets the start of the selection. |
| Text | Gets or sets the text displayed in the control. |
| TextLength | Gets the length of the text in the control. |
| WordWrap | If true, multiline text boxes will word-wrap as necessary. If false, they will scroll horizontally until a newline character is reached. |
| Method | Description |
| AppendText | Appends text to the control |
| Clear | Clears the text in the control |
| ClearUndo | Clears the most recent operation from the control's undo buffer |
| Copy | Copies the selected text to the clipboard |
| Cut | Cuts the selected text to the clipboard |
| Paste | Replaces the current selection with the contents of the clipboard |
| ScrollToCaret | Scrolls the control so that the caret is visible |
| Select | Selects text in the control |
| SelectAll | Selects all the text in the control |
| Undo | Undoes the last clipboard or text change operation |
Text boxes can be single-line or multiline, which is controlled by the Multiline property. Multiline text controls will use newline characters to break lines, whereas single-line controls will display newline characters as control characters (which usually display as a short vertical bar). The Lines property holds an array of Strings that is used to represent the lines in a multiline edit control.
Text controls maintain an undo buffer, so it's possible to undo changes. Because it's possible to clear the undo buffer, you should check the CanUndo property before trying to undo operations.
The TextBox class adds several properties to the ones it inherits from TextBoxBase, as shown in the following table.
| Property | Description |
| AcceptsReturn | If true, the Enter key will create a new line in a multiline text box instead of activating the default button for the form. The default is true. |
| CharacterCasing | Determines whether the control modifies the case of characters as they are entered. The values can be CharacterCasing::Normal (the default), CharacterCasing::Upper, or CharacterCasing::Lower. |
| PasswordChar | If set to a value other than 0, masks the characters with the specified value as they are typed. The default is 0. |
| ScrollBars | Determines whether a multiline text box displays with scroll bars. The default is no scroll bars. |
| TextAlign | Represents the text alignment. The default is HorizontalAlignment::Left. |
This exercise shows you how to add an edit control to the form and manipulate the text it contains.
- Open the CppForm project, if it isn't already open. The form was created with the default size of 300 by 300 pixels. To create more space to display a text box, set the form's Size property to 456,400 to give enough space to display the text box next to the group box. Select both the OK and Cancel buttons, and drag them to the lower-right corner of the form. Reposition combo1 by setting its Location property to 256,72.
- Drag a TextBox from the Toolbox onto the form.
- Position the text box just to the right of the group box and below the combo box, and use the Properties editor to set its Size to 100,150. Set the Multiline property to true so that it can display more than one line of text.
- Let's arrange for the text in the text box to be filled in automatically when the user clicks the radio buttons. To do so, you need to add a handler for the radio buttons. Select all three radio button objects, and then open the Properties editor. Click the Event button to display the events, and double-click in the blank space next to the Click event. One event handler will be added that will apply to all three radio buttons.
- Fill in the event handler function like this:
private: System::Void radioButton2_Click(System::Object * sender, System::EventArgs * e) { if (sender == radioButton1) textBox1->Text = "You have selected the Visual Basic option."; else if (sender == radioButton2) textBox1->Text = "You have selected the C# option."; else if (sender == radioButton3) textBox1->Text = "You have selected the C++ option.\r\n\r\n" "Here is another line"; }
The handler checks which of the radio buttons has originated the event and puts some appropriate text into the text box. The third radio button puts two lines of text into the text box, separated by a blank line. (The \r\n sequence acts as a line break.)
- Build and run the program. You should now be able to click the radio buttons on the form and see text displayed in the text box.

Click to view graphic
Using Menus
Menus are a well-known feature of most GUI programs, and the Forms namespace contains a complete set of classes for building and working with menus.
Menus in Windows Forms applications are represented by two main classes: MainMenu represents the menu bar that sits at the top of a form, while MenuItem represents all the items that make up the menus attached to a MainMenu. A MainMenu has a collection of MenuItems, and to model the hierarchical nature of menus, MenuItems themselves can have collections of other MenuItems.
In use, menu items bear some similarity to buttons: they are both distinguished by their text, and both fire a Click event when they are selected. It probably won't surprise you to learn that you set up handlers for menu items in exactly the same way as you do for buttons.
The following exercise will show you how to add a simple menu to the application's main form.
- Continue working with the same project you've been using throughout this chapter.
- Drag a MainMenu from the Toolbox, and drop it onto the form. You will see that an icon is displayed in a special area at the bottom of the designer screen.

Click to view graphic
Controls that have no visible presence on the form display in a separate area at the bottom of the designer. Only controls that can be seen at run time display on the form.
You will see a menu-like feature has been added to the top of the form, with a rectangle toward the left that contains the text Type Here. Click in that rectangle, and type &File to add a menu item.

Click to view graphic
- Once you've typed the entry, you will see that two more Type Here boxes appear. The one to the right is to add more items to the menu bar, while the one below is to add more items to the File menu. Add &About... and E&xit items to the File menu.
- Select the About menu item, and bring up the Properties editor. Change the name of the About menu item to aboutMenuItem. Change the name of the Exit menu item to exitMenuItem.
- You provide menu items so that the user can select them and execute code. Double-click the About menu item to add a handler, and add the following code to the function:
private: System::Void aboutMenuItem_Click(System::Object * sender, System::EventArgs * e) { MessageBox::Show(S"The About menu item", S"Menu"); }
Add a second handler for the Exit menu item, but this time use it to exit from the application.
private: System::Void exitMenuItem_Click(System::Object * sender, System::EventArgs * e) { // Exit from the application Application::Exit(); }
- Build and run the program. You should see that the form now has a menu bar at the top, and you should be able to select the menu items.

Click to view graphic
More About Menus
Now that you've mastered the basics of adding menu support to programs, I'll briefly mention some of the other features of the menu classes.
First, you can create hierarchical menus. Each menu item has a Type Here box to its right, and you can use this box to start a new hierarchical menu.

Click to view graphic
To add a separator bar to a menu, select the menu item above which you want the separator. Right-click the item, and select Insert Separator from the context menu.

Click to view graphic
The Checked and Enabled properties can be used to display a check mark next to a menu item and to dim menu items that aren't currently active. Simply set the requisite property to true or false in the Properties editor, as required. Note that the Properties editor gives you a way to set the initial values of properties. You can always change them later programmatically.
Displaying a Context Menu
Most GUI applications nowadays use context menussmall menus that pop up when you right-click over a window and that are used to provide menu items specific to that part of the GUI. You can easily add a context menu to a form by creating a ContextMenu object, adding menu items to it, and then assigning it to the form's ContextMenu property.
The following exercise shows you how to add a context menu to a form.
- Continue working with the same project you've been using throughout this chapter.
- Drag a ContextMenu from the Toolbox onto the form. It will display at the bottom of the form, next to the MainMenu.
- Add some items to the ContextMenu in the same way that you did for the main menu. You will see that the menu items display at the top of the form, as if you were editing a main menu.
- Assign the context menu to the ContextMenu property of the form, using the Properties editor.
- Build and run the code. You'll find that you can display the context menu by right-clicking the form.

Click to view graphic
You use handlers with items on context menus in exactly the same way as with main menus.
Chapter 16 Quick Reference
| To | Do this |
| Create a form. | Derive a class from System::Windows::Forms::Form. |
| Add controls to a form. | Drag controls from the Toolbox, and drop them onto the form. |
| Handle events. | Use the Properties editor to add an event handler. |
| Add a menu to a form. | Drag a MainMenu item onto the form, and add menu items using the graphical menu editor. |
| Add a context menu. | Drag a ContextMenu onto the form, in exactly the same way that you'd add a MainMenu. |
Last Updated: March 12, 2003
|