Introduction to Controls Containers


Parent Controls


The Windowís Desktop

When you start the computer, the first object the operating system creates is the desktop window. This is a wide rectangular area that covers the entire monitor screen. Based on the settings of the Control Panel, the operating system uses either a color or a picture (a bitmap) to fill the window. Once the desktop is ready, other objects or controls can be placed on it.


To provide some information about the desktop, the VCL is equipped with the TScreen class. This allows you to get such details as the screen dimensions (its width and height), the form that is displaying on the screen, the type of keyboard being used, etc. To make the screen information available to you any time, every application declares a TScreen global variable so you do not have to declare your own.

Alternatively, to get access to the desktop, you can call the GetDesktopWindow() function. Its syntax is:

HWND GetDesktopWindow(VOID);

This function simply returns a handle to the desktop window. This handle can give some information about the desktop such as its size, etc.


Because GetDesktopWindow() is just a function, it only produces a handle to the desktop. If you want to perform other processing on the desktop, you should use the TScreen class members or you can use some of the Win32 library functions such as SystemParametersInfo().

Applicationís Containers

A control is referred to as container if it can host other controls. While the desktop is the biggest container of the computer, to develop your applications, you will use your own controls that can act as parent to other controls. The VCL provides various objects that can play this role. The list includes the form, the frame, the group box, the panel, the scroll box, the control bar, the tab control, the page control, the status bar, the toolbar, the cool bar, the page scroller, the tabbed notebook, etc. The list is impressive and these parent controls are usually used for different purposes. In fact, the only real characteristic they share is their ability to host other controls.

Except for the form (and consequently the dialog box), most, if not all, of the other containers must be hosted by a form. Therefore, after starting a project or once you get a form, you can place a control container on it (the form). Once placed on a form, these parent windows can host their own controls. Therefore, to use a container, you can either position your control on the form, in which case the form would act as the parent, or you can first select one of the containers, place it on a form, and then add other controls to it.

The Parentís Location

As seen with child controls, except for the desktop window, every visual object either on the screen or in your application must be located. The location of an object depends on its parent and some other considerations.

The main object or frame of an application, which is usually the first form of a project, when it appears on the screen, is located with regards to the screen. Such a form is located on a Cartesian coordinate system whose origin is on the top-left corner of the screen. The horizontal axis moves from the left border to the right. The vertical axis moves from the top border down.

The distance from the left border of the screen to the form is the Left measurement. The distance from the top border of the screen to the top border of the form is its Top measurement.

This can be illustrated as follows:

The above illustration shows a form positioned on a monitor. The desktop acts as the parent window of the form. In the same way, if you place a control on a container, the control is located with regards to its parent, not based on the screen. As seen previously, in such a case, the origin of the coordinate system is located on the top-left corner of the parent window. The distance from the left border of the parent window to the left border of the control is the controlís Left property. The distance from the top border of the parent window to the top border of the control is the controlís Top property. Here is an example in which a child control positioned inside a another control that acts as its parent (that container itself is a child to the form):


In the same way, an object positioned on a parent can be seen only if its dimensions are confined to the body of the parent.

Control Alignment and Constraint


The Client Area

To manage the display of visible windows, each parent provides a section called the client area. For the desktop screen, the client area is the whole screen. For a form, the client area is the body of the form without the title bar. Most other containers provide their whole body as the client area:


The desktop window provides a rectangular area that it can use to display the computerís applications. This area is also used to host other objects. Although an objectís borders can span beyond the borders of the desktop, only the area of an object covered by the desktop can be seen. Here is an example of a window whose right side cannot be seen:


The client area is a rectangle primarily used for its location and dimensions. To get the values of the shape that compose the client area, you have various options and considerations. For example, to get the area that represents the desktop, which would let you know how much real estate is available for your application, you can call the TScreen::DesktopRect member variable. Here is an example:

void __fastcall TForm1::FormCreate(TObject *Sender)
	TRect Recto = Screen->DesktopRect;

	Caption = "Width: " + IntToStr(Recto.Width()) +
		  " Height: " + IntToStr(Recto.Height());
Client Area

The TScreen class also provides such aspects as the location and width of the desktop in the forms of DesktopLeft, DesktopTop, DesktopWidth, and DesktopHeight.

The DesktopRect and the DesktopHeight provide the height of the desktop including the task bar. If you want to know the actual area that is made available on the desktop, which does not include the taskbar, use the TScreen::WorkAreaRect or the TScreen::WorkAreaHeight respectively. Otherwise, you can also get the left, the top, and width measures using the WorkAreaLeft, the WorkAreaTop, and the WorkAreaWidth respectively. In reality, the WorkArea_ measures can be more useful if your application takes advantage of more than one monitor. In this case the WorkArea_ measures provide information about the desktop of the primary monitor.

Besides the TScreen class, you can use the GetDesktopWindow() function to get a handle to the desktop and find the dimensions of that window. Here is an example that displays the screen resolution:

void __fastcall TForm1::FormCreate(TObject *Sender)
	TRect recto;
	HWND hWndDesktop = GetDesktopWindow();
	GetWindowRect(hWndDesktop, &recto);

	Caption = "Width: " + IntToStr(recto.Width()) +
		  " Height: " + IntToStr(recto.Height());

It is important to know where the origin of a control is located. During control design, we saw that, when a container is selected and you double-click a visual control on the Tool Palette, the new control would be added to the container. On the other hand, if you have a container that is positioned on the form but the container, or any specific container, is not selected, if you double-click a control on the Tool Palette, the control would be added to the form even though the new control may be positioned on a container. In this case, the form would become the parent of the new control. Therefore, in order to do anything related to the location and/or dimensions of a control, you must know the coordinate of the origin used as the basis for its location and dimensions.

Because only a parent can host some controls, it holds an origin and makes it available to its children. To get the origin of a container, call the TControl::ClientOrigin property.

To get the location and dimensions of any window that serves as parent, you can call the TControl::ClientRect property. A control hosted by a container can be displayed only inside its parent. If the controlís left or top measures are negative, its left or top borders respectively would be hidden under the left or top sides of the parent. If the dimensions of the child control span beyond the dimensions of the parent window, the controlís right or bottom border will be hidden. We will see that some controls cannot allow their child or children to expand the client area and some other controls can display scroll bars so the hidden parts can be navigated to.

The ClientRect property mainly provides only the width and the height of a client area since the left and the top measures are set to 0 each as the origin (0, 0) is the base. Alternatively, you can get the width of a control using the TControl::ClientWidth and you can get the height of the control using the TControl::ClientHeight properties.

Controlís Alignment in the Client Area

Besides the Top, the Left, and the Position properties, you can also control the position of a control in the client area of its container using the Align property. This property and its values have the following effects:

By default, the Align property is set to alNone. In this case, the control can assume any position with regard to its host control

Control Alignment
Control Alignment

When the Align property is set to alLeft, the control will be fixed to the left border of its host.

A control whose Align property is set to alTop can serve as a toolbar or a floatable window on the top section of its host.

Control Alignment
Control Alignment

If the control has the Align property set to alRight, the control would be anchored to the right border of its container.

A control can be used as a status bar that always displays on the bottom section of the form. In this case, its Align property would be set to alBottom.

Control Alignment
Control Alignment

If a controlís Align property is set to alClient, it would occupy the client area of the container. If another control on the same container already has one of the previous alignments, except alNone, the control whose Align property is set to alClient would occupy only the remaining unoccupied area.

In case of a (regular) form, the Align property controls how the form is positioned with respect to the monitor's screen. When it comes to a form, the Align property should be used only if you have a good reason. For example, to maximize a form at startup, you can set its Align property to alClient, which you can also accomplish using the WindowSate property. The default value of the Align property is alNone, which means the appearance of the form is left to other properties. We will explore the Align property when we get to the controls but remember that it is also available to the form.

The Client Areaís Constraints

The user of your application will have the ability to resize the form when using your application. If the form is not a classic dialog box, by default, the user can resize it to any dimensions allowed by the screen resolution; the minimum is to have the system buttons and just a tiny part of the caption.

You can set the minimum height, the maximum height, the minimum width, and the maximum width allowed on the control if the control gets resized. This property is controlled by the Constraints property. The Constraints property is a TSizeConstraints class, which is inherited from the TPersistent class. Although it is a class, you should never declare it. The control that uses a Constraints property will create and initialize an instance of the class. The MinWidth, MinHeight, MaxWidth, and MaxHeight values are integers you can set using the keyboard. To set the constraints of a control that has this property, click the + button of the Constraints field in the Object Inspector, click the field desired and type an integer value. To programmatically control the constraints of a control, call the TSizeConstraints::Property and type the desired value. In the following example, when the user tries to resize the Form1 form, the minimum and maximum dimensions of the form are already set and would not change:

void __fastcall TForm1::FormResize(TObject *Sender)
	Form1->Constraints->MinHeight = 300;
	Form1->Constraints->MinWidth = 500;
	Form1->Constraints->MaxHeight = 400;
	Form1->Constraints->MaxWidth = 565;

Control Anchoring

If you position a (visual) control on a form, if the control is positioned on the top left section of the form, when the user resizes the form, the controlís position would appear static, it would not move. This could be a concern if the control is positioned on the right, the bottom or the lower right section of the form. When the user resizes the form, the controlís position would not be updated. Sometimes you will want the control to have the same location and/or distance with regard to the bottom, the right, and/or the lower right corner of the form. This ability is controlled by the Anchors property.

The anchoring of a control to its parent or host container is controlled using a set property derived from the TAnchors enumerator. By default, when you add a control to a form, it is "glued" to the top left corner of its container. Since this property is a Set, you can set the controlís position with regards to its containerís right and bottom borders. The possible values of the Anchors property are:

Value The controlís location will not change
akTop With regards to its parentís top border
akLeft With regards to its parentís left border
akRight With regards to its parentís right border
akBottom With regards to its parentís bottom border

Child Controls and DragíníDrop Operations

One of the most useful actions performed on a control consists of involving it in drag and drop operations. Some controls can serve as the source or the destination on such an operation. Drag and drop operations are performed using specific properties of child controls associated with their parents.

The DockSite property uses a Boolean value to indicate that the control can serve as the host for a dragínídrop operation. The DragKind property specifies how the control participates in the dragínídrop operation. If the control serves as a docking host, you should set its DragKind property to dkDock. By contrast, if the control will itself be used when dragging, set its DragKind property to dkDrag.

If a control is ďdraggableĒ, you can use the DragMode property to specify how the dragging operation on the control would be initiated. If you want the dragging operation to be possible when the user clicks the control, set its DragMode property to dmAutomatic. Otherwise, some controls, depending on the result you are trying to achieve, should be available for dragging only depending on an intermediary action. In such a case, you can write your program so that the dragging operation on a control would be available only after the application or another event or control has called the TControl::BeginDrag() method. In this case, you can set the DragMode property to dmManual.


Previous Copyright © 2010-2016, FunctionX Home