Home

Introduction to Characteristics of Windows Controls

 

Fundamental Properties of a Control

 

Introduction

As mentioned already, in Microsoft Windows, to create a control, you can call either the CreateWindow() or the CreateWindowEx() function. In a VCL application, you can get a control from the Tool Palette, you can dynamically create a control, or you can use one of the above Win32 functions.

If for any reason you cannot or would not visually add a control at design time, you can create it programmatically. There are various techniques you can use. You can first decide what class will be used as the basis of your control.

The Control's Handle

A handle is a numeric value used internally by Microsoft Windows to identify a control or a class. Every control must have a handle. You have a choice of using it or not. The Win32 library defines a window as a handle to a window object, known as HWND. After the window has been created, the CreateWindow() or the CreateWindowEx() function returns an HWND variable. You can use this return value later to access the created window, for example to change some of its characteristics.

 

To access the handle to a control, when creating it, make sure you return its HWND value. Once you have the return value of a control, you can access that value any way you see fit in your program.

When creating a VCL application, you will mostly use the properties, methods, and events defined by that library. Because the VCL implements the Windows controls through a class called TWinControl, it makes sure it provides you with an HWND handle that allows you to directly access the properties or messages of the control as defined in the Win32 library. The handle to a Windows control is (simply) called Handle.

The Class Name of a Control

If you are using the Win32's CreateWindow() or CreateWindowEx() function, you can either use one of the existing names of controls or you are create a control with a custom name. The Win32 library provides already defined names of classes you can use to create a control. The standard controls use the following class names:

Class Name Description
STATIC A static control can be used to display text, a drawing, or a picture
EDIT As its name suggests, an edit control is used to display text to the user, to request text from the user, or both
RichEdit Like an edit box, a rich edit control displays text, requests it, or does both. Besides all the capabilities of the edit control, this control can display formatted text with characters or words that use different colors or weight. The paragraphs can also be individually aligned. The RichEdit class name is used to create a rich edit control using the features of Release 1.0 of its class
RICHEDIT_CLASS This control is used for the same reasons as the RichEdit class name except that it provides a few more text and paragraph formatting features based on Release 2.0
LISTBOX A list box is a control that displays items, such as text, arranged so each item, displays on its own line
COMBOBOX A combo box is a combination of an edit control and a list box. It holds a list of items so the current selection displays in the edit box part of the control
SCROLLBAR A scroll bar is a rectangular object equipped with a bar terminated by an arrow at each end. It is used to navigate left and right or up and down on a document
BUTTON A button is an object that the user clicks to initiate an action
MDICLIENT This class name is used to create a child window for an MDI application

Microsoft Windows added a few more class names for objects referred to as common controls. Fortunately, whether you want to use standard or common controls, the VCL provides friendlier implementations of all of them with even more Windows controls than the Win32 provides. The names of classes of controls are available in both the Tool Palette and the help file. To examine a class in the online help, first locate the package in which it is defined. Expand that node, then click the name of the class you want. Here is an example:

Classes

You can then use that name to dynamically create a control or to check its documentation.

To use one of the Win32 classes, pass its name as string to the lpszClassName argument of the CreateWindow() or the CreateWindowEx() functions.

If the control has been created already and you want to find its class name, the Win32 library provides the GetClassName() function. The hWnd argument is the handle of the control whose class name you want to find out. The lpClassName is the string that will be returned by this function. This means that you must first declare a string and pass it to this function. After the function has been called, the variable will carry the sought class name. The nMaxCount is the length of the lpClassName string.

Whether you are using the VCL or the Win32 libraries, although you can change the name of a control at runtime, refrain from doing it.

Control's Names

To create a control, the primary piece of information you must provide is its name. This allows you and the compiler to know what control you are referring to when the program is running. Specifying the name of a control may depend on the technique you decide to use to create the control.

In the CreateWindow() or CreateWindowEx() function, the control's name is primarily created as the lpWindowName argument. In the VCL, to let you get the name of a control, the TComponent class is equipped with a property named Name:

property Name: TComponentName read FName write SetName;

This Name property is inherited by all other classes that derive directly or indirectly from TComponent.

After adding a control to a form, it automatically receives a name. In the Object Inspector, the control's name displays in the Name field:

Name

A newly added control reflects the name of its icon from the Tool Palette and adds an incremental number. For example, if you click the TEdit icon in the Tool Palette and click the form, the control would be named Edit1. If you add a second TEdit control, it would be named Edit2. This causes the default names to be incremental. Since a program usually consists of many controls, it is usually a good idea to rename your controls and give them meaningful and friendlier names. The name should help you identify what the button is used for.

To change the name of a control, on the Object Inspector, click the word Name and type a valid Pascal.

Controls Text and Caption

Some controls are text-based. This means that they are meant to display or sometimes request text from the user. For such controls, this text is referred to as caption while it is simply called text for some other controls. This property is not available for all controls.

If you are using the Win32 approach, the text of a text-based control is passed as the lpWindowName argument of the CreateWindow() or the CreateWindowEx() functions. In the VCL, to support the caption, the TControl class is equipped with a property named Caption:

property Caption: TCaption read GetText write SetText;

The TControl class is also equipped with another property named Text:

property Text: TCaption read GetText write SetText;

As mentioned already, not all controls display text. Those that do inherit the appropriate property from TControl. If a control displays text, it then has a Text or a Caption property in the Object Inspector. Here is an example:

Name

After adding such a control to a form, its Caption or its Text field would hold the same text as its name. At design time, to change the text of the control, click either its Caption or its Text field and type the desired value. For most controls, there are no strict rules to follow for this text. Therefore, it is your responsibility to type the right value.

The text provided in a Caption or Text fields of a text-based control can only be set "as is" during design. If you want the text to change while the application is running, you can format it. For example, a control can display the current time or the name of the user who is logged in. These format attributes cannot be set at deign time.

To change the text of a text-based control at run time, either assign a simple string or provide a formatted string to either the Caption or the Text property. As we will see when studying messages and events, you can also change the text of a control using the SendMessage() function with the message set as WM_SETTEXT.

Introduction to Styles and Properties of a Window

When it comes to Microsoft Windows controls, a style is a characteristic that defines how the object looks and behaves with regards to the other objects of the same application or objects of the other applications on the same computer. The styles are varied from one control to another although they share some of the characteristics common to most Windows controls.

The Win32 library defines a certain number of styles that were released with Microsoft Windows 95. Additional styles were created later and were named extended styles. If you programmatically create a window using either the CreateWindow() or the CreateWindowEx() function, specify its style(s) as the dwStyle argument.

As mentioned already, in the Win32, you can specify a style when creating it using CreateWindow() or CreateWindowEx(). If the control has been created already and you want to change its style, you can call the SetWindowLongPtr() function.

The hWnd argument represents the handle of the control whose style you want to change.

The nIndex argument is the byt value that represents the type of change you want to make. For a control, it can be GWL_STYLE to indicate that you want to change a style, or GWL_EXSTYLE to indicate that you want to change an extended style.

The dwNewLong represents the new style you want to apply.

If a control exists already, to find out the style(s) it is currently using, you can call the GetWindowLongPtr() function.

The arguments are the same first two of the SetWindowLongPtr() function.

In the VCL, the styles are defined as properties of the TControl (for all visual and non-visual controls) and the TWinControl (for visual controls) classes. To specify or change the property of a control, if the property is read-write, you can access it from its class and assign the desired value. To get the value of a property, get its write accessor.

A Control as a Child

All of the controls you will create need to be hosted by another control. During design, once you position a control on a form, it (the control) automatically gets the status of child.

If you are creating a control using the CreateWindow() or the CreateWindowEx() function, to specify that the control is a child, add the WS_CHILD flag to the dwStyle argument. When designing an application, once you add it to a form, it becomes that form's child.

The Location of a Control

The controls added to a form are confined to the area of the body offered by that window. After adding it to a window, the control is positioned in the body of the form using a Cartesian coordinate system whose origin is located on the top-left corner of the parent window. The horizontal measurements move from the origin to the right. The vertical measurements move from the origin to the bottom.

If you are using the CreateWindow() or the CreateWindowEx() functions, to set the left distance, pass the desired value as the X argument. On the other hand, to specify the top distance, pass the desired value for the Y argument.

In the VCL, the distance from the control's left border to the parent's left border is represented by the Left property of the TControl class:

__property int Left = {read=FLeft,write=SetLeft};

The distance from the control's top border to the parent's top border is called the Top property of the TControl class:

property Top: Integer read FTop write SetTop;

The Left and Top values are known as the control's location. This can be illustrated as follows:

When you click a control on the Tool Palette and click its parent window, the Left and Top values are set where the mouse landed. To change the location of a control, as we saw already, you can click and drag it to the new desired location. Alternatively, you can type the desired value in either the Left or the Top fields on the Object Inspector. At design time, if you drag a control to move it, Embarcadero RAD Studio updates the values of its location. If you save the project, the compiler would also save the locations of all objects, including the form, so that the next time you run the application, the compiler would remember to display the form where it was last positioned at design time.

To programmatically move a control, which is equivalent to changing the values of the Left or the Top properties at run time, assign the desired respective values. If you set a negative value for the Left field, the left border of the control would be hidden. In the same way, a negative Top value would hide the top border of the control. Make sure you use valid integer values; otherwise you would receive an error when you compile the project.

The Size of a Control

The width of a control is the distance from its left to its right borders. The height of a control is the distance from its top to its bottom borders.

If you are creating the control using the CreateWindow() or the CreateWindowEx() functions, specify the value for the distance from the left border of the parent window to the left border of the control as the nWidth argument. In the same way, pass the desired value for the distance from the top border of the parent to the top border of the control as the nHeight argument. If you specify negative values for the left and top distances, either the left or the top borders, respectively, will be hidden.

In the VCL, the distance from the left border to the right border of a control is represented by the Width property of the TControl class:

property Width: Integer read FWidth write SetWidth;

In the same way, the height of a control is represented by the Height property of the TControl class:

property Height: Integer read FHeight write SetHeight;

 The size of a control can be illustrated as follows:

If you click a control's button on the Tool Palette and click its parent window, the control assumes some default dimensions in the body of the parent. As we saw in the previous lesson, to change the dimensions of a control, you can drag one of its borders or corners. Alternatively, on the Object Inspector, you can type the desired values in either or both the Height and the Width fields.

If the control has already been created, you can resize it at run time. To change the dimensions programmatically, simply assign the desired value to the Height and/or Width property of your choice. If the value you give to a property is not allowed, the program would throw an error.

If you are creating a graphical application for a touch screen, you should use as much space for each control as possible. This means that you should use a with and a height larger than the values used for a regular program.

The Parent of a Control

There are two main categories of windows you will need to create for your application: parents and children:

  • Owner and Parent: a window is referred to as a parent when there are, or there can be, other windows that depend on it. The Standard toolbar of the RAD Studio is an example of a parent window. It is equipped with buttons and acts as their parent. When a parent is created, it "gives life" to other windows that can depend on it. When a parent is destroyed, it also destroys its children.
    An owner is a control that "owns" another control. The owner must be a parent type. An owner "carries", "holds", or hosts the controls that it owns. When an owner is created, made active, or made visible, it gives existence and visibility to its controls. When an owner gets hidden, it also hides its controls. If an owner moves, it moves with its controls. The controls keep their positions and dimensions inside the owner
  • Child: A window is referred to as child when its existence and its visibility depend on another window called its parent or owner. All of the Windows controls you will use in your applications are child controls and they must be parented or owned by another control

A child window can be a parent of another control. For example, the Standard toolbar of the RAD Studio is the parent of the buttons on it. If you close or hide the toolbar, its children disappear. At the same time, the toolbar is a child of the application's frame. If you close the application, the toolbar disappears, along with its own children. In this example, the toolbar is a child of the frame but is a parent to its buttons.

If you create a control using either the CreateWindow() or the CreateWndowEx() function, to specify its parenth, pass the parent's handle as the hWndParent argument. If the control has been created already, to specify or change its parent at run time, you can call the SetParent() function.

The hWndChild argument is the handle of the control whose parent you want to change. The hWndNewParent argument must be the handle of the new parent. To find out what object acts as the parent of a control, you can call the GetParent() function. The hWnd argument is the handle of the control whose parent you want to find out.

The Owner of a Control

In the VCL, the parent of a control is also referred to as the owner. To support it, the TComponent class is equipped with the Owner property:

property Owner: TComponent read FOwner;

If you decide to dynamically create a control, you must specify its owner. The owner will be responsible for hosting or carrying the child control. The name of the owner is passed to the constructor of the control. After specifying the owner, you must also specify the parent of the control. The parent is responsible for destroying the child control when it (the parent) is destroyed. To support this, the TControl class is equipped with a property named Parent:

property Parent: TWinControl read FParent write SetParent;

All classes of visual controls inherit this property. Therefore, to specify the parent of a control, access its Parent property and assign it the name of the parent. Normally, the name of the parent is the same as the owner.

If you declare and completely create a control in an event or a method, the control would be available only in that member function and cannot be accessed outside. To make such a control available to other events or controls owned by the same parent, you should declare it in the header file of its parent. After declaring the variable, you can sepecify its parent and owner in the constructor of the form.

If the control has already been created and you want to know "who" its parent is, you can assign its Parent property to a TWinControl variable.

Alternatively, to find out what object acts as a control's parent, call the Win32 API's GetParent() function. The hWnd argument must be a handle to the control whose parent you want to find out.

The Additional Parameters of a Control

We have reviewed the fundamental pieces of information necessary to create a simple or normal control by calling either the CreateWindow() or the CreateWidowEx() function:

  • We will come back to the menus in another lesson. Otherwise, if you don't have a menu, you can pass the hMenu, argument as NULL
  • In Lesson 2, we introduced the instance of an application. If you (and you should) have an instance of an application, pass it as the hInstance argument
  • The lpParam argument is a pointer to the CREATESTRUCT structure, which is a structure that holds additional information about a control. If you don't have it, you can pass this argument as NULL
 
 
 
 

Previous Copyright © 2010 FunctionX, Inc. Next