Training
Certifications
Books
Special Offers
Community




 
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.
 

More Information

About the Book
Table of Contents
Sample Chapter
Index
Related Series
Related Books
About the Author

Support: Book & CD

Rate this book
Barnes Noble Amazon Quantum Books

 


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 controls—such as buttons and list boxes—onto a form to build the GUI for your program. A simple form is shown in the following figure.

Click to view graphic
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 controls—such as color and text—and 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.

NameDescription
ApplicationProvides static methods to manage applications, including starting and stopping them, and getting information about them.
AxHostProvides a way to host ActiveX controls in Windows Forms applications.
BorderStyleAn 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.
ButtonRepresents a Windows button control.
ButtonStateAn enumeration that specifies the appearance of a button. Members include Inactive, Pushed, and Normal.
CheckBoxRepresents a Windows check box control.
ClipboardLets you place data onto and retrieve it from the system clipboard.
ColorDialogDisplays a standard dialog box to let the user pick a color.
ComboBoxRepresents a Windows combo box control.
CursorRepresents a cursor.
DataGridDisplays ADO.NET data in a scrollable grid.
DateTimePickerRepresents a Windows date-time picker control.
FormRepresents a window or a dialog box.
HScrollBarRepresents a Windows horizontal scroll bar control.
ImageListRepresents a collection of images typically used by toolbars.
LabelRepresents a Windows label control.
ListBoxRepresents a Windows list box control.
ListViewDisplays a list of items in one of four views.
MenuRepresents a menu.
MessageBoxDisplays a message box.
PanelA control that can contain other controls.
ProgressBarRepresents a Windows progress bar control.
RadioButtonRepresents a Windows radio button control.
SplitterProvides splitter functionality to a window.
StatusBarRepresents a Windows status bar control.
TextBoxRepresents a Windows edit control.
ToolBarRepresents 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.

  1. 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.
  2. Click to view graphic
    Click to view graphic

  3. Compile and run the code. A window will be displayed, as shown in the following figure.
  4. Click to view graphic
    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.

  5. Click the Close button—the one marked with an X on the far right of the title bar—to 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.

NameMethod or Property?Description
AcceptButtonPGets or sets a reference to the button control that corresponds to the user pressing Enter.
ActivateMActivates the window, bringing it to the front of the application's collection of windows.
ActiveFormPGets the currently active form for this application, meaning the one at the front of the application's collection of windows.
AutoScalePGets 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.
AutoScrollPGets or sets a value indicating whether the form displays scroll bars when controls fall outside the displayable area. The default is true.
CancelButtonPGets or sets a reference to the button control that corresponds to the user pressing Esc.
ClientSizePGets 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.)
CloseMCloses the form and frees any resources the form has used.
DesktopLocationPGets or sets the location of the form on the Windows desktop.
FormBorderStylePGets or sets the border style of the form. The default is FormBorderStyle::Sizeable.
HelpButtonPGets or sets a Boolean value indicating if the form is to display a Help button on the title bar. The default is false.
IconPGets or sets the icon associated with the form.
MaximizeBoxPGets or sets a Boolean value that indicates if the form is displaying a Maximize box on the title bar. The default is true.
MenuPGets or sets a reference to the menu that is displayed on this form.
MinimizeBoxPGets or sets a Boolean value that indicates if the form is displaying a Minimize box on the title bar. The default is true.
OwnedFormsPHolds the collection of child forms owned by this form, if any.
SetDesktopLocationMSets the location of the form on the desktop.
ShowDialogMShows the form as a modal dialog box.
ShowInTaskBarPGets or sets a Boolean value, which is true if the form is to be shown in the Windows taskbar. The default is true.
SizePGets or sets the form's size.
SizeGripStylePDetermines how (or even whether) the sizing grip is shown at the lower right of the form. The default is SizeGripStyle::Hide.
TopLevelPGets 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.
TopMostPGets 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.
WindowStatePGets or sets the form's window state, which determines how the form is displayed—minimized, 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.

  1. 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.
  2. 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
    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
    Click to view graphic

  3. 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.
  4. 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.
  5. Click to view graphic
    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 forms—think of displaying a dialog box—and 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.

  1. Continue with the same Windows Forms project that was used in the previous two exercises.
  2. 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.
  3. Click to view graphic
    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.

  4. 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.
  5. 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.

  6. 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).
  7. 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
    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.

  1. 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.
  2. Select the OK button, and bring up the Properties editor. Click on the Event button at the top of the Properties editor window—the button with a lightning bolt as a symbol—and 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.

  3. 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:
  4. 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.

  5. If you look in InitializeComponent, you can see how the button has been made aware of the handler.
  6. 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.

  7. Try building and testing the application. You should see a message box like the one shown in the following figure when you click OK.
  8. Click to view graphic
    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.

  9. 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 PropertyDescription
AutoSizeDetermines whether the label automatically resizes itself to fit the text.
BackColor (inherited from Control) Represents the background color of the label.
BorderStyleGets or sets the style of the label border: three-dimensional, single, or none.
FlatStyleDetermines 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.
ImageGets or sets the image associated with the label.
ImageAlignRepresents the alignment of the image on the label. The default is centered.
ImageIndexThe index of the image to be used from the associated ImageList.
ImageListThe ImageList to be used as a source of images for this label.
PreferredHeightGets the height necessary to display one line of text.
PreferredWidthGets the width necessary to display the current text.
RenderTransparentDetermines whether the container's background will be displayed as the background to the label.
TabStopDetermines whether the user can tab to this control.
TextRepresents the text of the label.
TextAlignGets or sets the text alignment. The default is left aligned.
UseMnemonicDetermines 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.

  1. Continue using the CppForm project. Open the Toolbox, and drag a Label onto the form. You can leave the control name as label1.
  2. 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.
  3. 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.

  4. 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.
  5. Set the Location of the Label to be 20,20.
  6. 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.
  7. 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.
  8. Click to view graphic
    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 PropertyDescription
DialogResultRepresents 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.

PropertyDescription
AutoCheckDetermines whether the appearance of the control automatically changes when the user clicks it (as opposed to being set from code).
CheckAlignRepresents the alignment of the check box. The default is MiddleLeft.
CheckedRepresents 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.

  1. 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.
  2. 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.
  3. Add another two radio buttons to the group box, positioning them below the first. Set their Text properties to C# and C++, respectively.
  4. 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.
  5. Click to view graphic
    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.

PropertyDescription
ColumnWidthGets or sets the width of columns in a multicolumn list box.
HorizontalScrollbarGets or sets a value indicating whether the control displays a horizontal scroll bar.
IntegralHeightSet to true if the ListBox should resize itself so that it doesn't show partial items.
ItemsRepresents the collection of items held in the list box.
MultiColumnSet to true if the list box supports multiple columns. The default is false.
PreferredHeightGets 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.
ScrollAlwaysVisibleIf set to true, the vertical scroll bar will always be visible.
SelectedIndicesFor multiselection list boxes, represents a collection of the indexes of all the items currently selected in the list box.
SelectedItemGets or sets the currently selected object in the list box.
SelectedItemsFor multiselection list boxes, represents a collection of all the items currently selected in the list box.
SelectionModeRepresents the selection mode of the list. (SelectionMode is discussed in the following text.)
SortedSet to true if the items in the list box are to be sorted. The default is false.
TextRepresents 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.
TopIndexThe 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:

  1. SelectionMode::None, meaning that the user cannot select any items.
  2. SelectionMode::One, meaning that the user can select one item at a time. This is the default value.
  3. SelectionMode::MultiSimple, meaning that the user can select more than one item at a time.
  4. 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.

MethodDescription
BeginUpdate, EndUpdateBeginUpdate prevents the list box from redrawing until EndUpdate is called. This improves the performance when adding several items.
ClearSelectedDeselects all the items in a list box.
FindString, FindStringExactFinds the first item in the list box that starts with a given string or that exactly matches a given string.
GetSelectedReturns true if the item with the specified index is selected.
SetSelectedSets 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.

PropertyDescription
DropDownStyleRepresents the style of the combo box.
DropDownWidthRepresents the width in pixels of the drop-down box.
DroppedDownSet to true if the list portion is currently displayed.
IntegralHeightSet to true if the combo box should resize itself so that it doesn't show partial items.
ItemsRepresents the collection of items held in the combo box.
MaxDropDownItemsRepresents the maximum number of items in the drop-down list. The value must be between 1 and 100.
MaxLengthRepresents the maximum length of the text in the text box.
SelectedItemGets or sets the currently selected item.
SelectedTextRepresents the currently selected text in the text box portion of the combo box control.
SelectionStart, SelectionLengthGets or sets the start position and length of the selected text in the text box portion of the combo box control.
SortedDetermines whether the list in the combo box is sorted.
TextGets 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.

MethodDescription
BeginUpdate, EndUpdateBeginUpdate prevents the combo box from redrawing until EndUpdate is called. This improves the performance when adding several items.
FindString, FindStringExactFinds the first item in the combo box that starts with a given string or that exactly matches a given string.
SelectSelects a range of text in the text box portion of the combo box.
SelectAllSelects 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.

  1. Open the CppForm project if it isn't already open.
  2. Drag a ComboBox from the Toolbox onto the form, and change its name to combo1.
  3. 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.
  4. 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 values—Beginner, Intermediate, and Advanced—one per line, and press OK to dismiss the editor when you're done.
  5. 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:
  6. combo1->SelectedIndex = 0;

  7. 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 editor—the 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:
  8. 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.

  9. 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.
  10. Click to view graphic
    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.

PropertyDescription
AcceptsTabIf 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.
AutoSizeIf true, the control automatically resizes itself to fit its text. The default is true.
BackColor, ForeColorRepresents the background and foreground colors.
BorderStyleRepresents the border style. The default is Fixed3D.
CanUndoSet to true if the last operation can be undone.
HideSelectionIf true, selected text in the control is dimmed when the focus passes to another control.
LinesGets or sets the collection of lines in a text box as an array of Strings.
MaxLengthRepresents 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.
ModifiedGets or sets a Boolean value representing whether the control's content has been modified.
MultilineIf true, the control is a multiline text box.
PreferredHeightGets the preferred height in pixels for the current font. This enables you to size the text box so that it displays text correctly.
ReadOnlyGets or sets the read-only status of the control.
SelectedTextRepresents the currently selected text.
SelectionLengthGets or sets the length of the selection.
SelectionStartGets or sets the start of the selection.
TextGets or sets the text displayed in the control.
TextLengthGets the length of the text in the control.
WordWrapIf true, multiline text boxes will word-wrap as necessary. If false, they will scroll horizontally until a newline character is reached.

MethodDescription
AppendTextAppends text to the control
ClearClears the text in the control
ClearUndoClears the most recent operation from the control's undo buffer
CopyCopies the selected text to the clipboard
CutCuts the selected text to the clipboard
PasteReplaces the current selection with the contents of the clipboard
ScrollToCaretScrolls the control so that the caret is visible
SelectSelects text in the control
SelectAllSelects all the text in the control
UndoUndoes 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.

PropertyDescription
AcceptsReturnIf 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.
CharacterCasingDetermines 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.
PasswordCharIf set to a value other than 0, masks the characters with the specified value as they are typed. The default is 0.
ScrollBarsDetermines whether a multiline text box displays with scroll bars. The default is no scroll bars.
TextAlignRepresents 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.

  1. 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.
  2. Drag a TextBox from the Toolbox onto the form.
  3. 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.
  4. 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.
  5. Fill in the event handler function like this:
  6. 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.)

  7. 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.
  8. Click to view graphic
    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.

  1. Continue working with the same project you've been using throughout this chapter.
  2. 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.
  3. Click to view graphic
    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
    Click to view graphic

  4. 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.
  5. 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.
  6. 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:
  7. 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();
    }

  8. 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.
  9. Click to view graphic
    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
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
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 menus—small 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.

  1. Continue working with the same project you've been using throughout this chapter.
  2. Drag a ContextMenu from the Toolbox onto the form. It will display at the bottom of the form, next to the MainMenu.
  3. 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.
  4. Assign the context menu to the ContextMenu property of the form, using the Properties editor.
  5. Build and run the code. You'll find that you can display the context menu by right-clicking the form.
  6. Click to view graphic
    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

ToDo 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
Top of Page