Introduction to Characteristics of Windows Controls |
|
Fundamental Properties of a Control |
As mentioned already, in Microsoft Windows, to create a control, you can call either the CreateWindow() or the CreateWindowEx() function: |
|
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: //--------------------------------------------------------------------------- void __fastcall TExercise::ExerciseCreate(TObject *Sender) { CreateWindow("Button", "Submit", [SomeStyles], ); } //--------------------------------------------------------------------------- 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. Its syntax is: LONG_PTR SetWindowLongPtr( __in HWND hWnd, __in int nIndex, __in LONG_PTR dwNewLong ); 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. Its syntax is: ULONG_PTR GetClassLongPtr( __in HWND hWnd, __in int nIndex ); 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.
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. Here is an example: //---------------------------------------------------------------------------
void __fastcall TExercise::ExerciseCreate(TObject *Sender)
{
CreateWindow("Button", "Submit", WS_CHILD, );
}
//---------------------------------------------------------------------------
When designing an application, once you add it to a form, it becomes that form's child.
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. Here are examples: //--------------------------------------------------------------------------- void __fastcall TExercise::ExerciseCreate(TObject *Sender) { HWND hWndButton = CreateWindow("Button", "Submit", WS_CHILD, 10, 10, . . . ); } //--------------------------------------------------------------------------- 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 int Top = {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 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. Here is an example: //--------------------------------------------------------------------------- void __fastcall TExercise::ExerciseCreate(TObject *Sender) { HWND hWndButton = CreateWindow("Button", "Submit", WS_CHILD, 10, 10, 124, 25, . . .); } //--------------------------------------------------------------------------- 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 int Width = {read=FWidth,write=SetWidth}; In the same way, the height of a control is represented by the Height property of the TControl class: __property int Height = {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. Here is an example that changes the width of the form: //--------------------------------------------------------------------------- void __fastcall TExercise::ChangingFormWidth() { Width = 248; } //--------------------------------------------------------------------------- If the value you give to a property is not allowed, the program would throw an error.
There are two main categories of windows you will need to create for your application: parents and children:
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. Its syntax is: HWND SetParent( __in HWND hWndChild, __in HWND hWndNewParent ); 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. Its syntax is: HWND GetParent( __in HWND hWnd ); The hWnd argument is the handle of the control whose parent you want to find out.
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 Classes::TComponent * Owner = {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. This would appear as follows: TSomeControl *ctlShowMe = new TSomeControl(Mom);
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 Controls::TWinControl * Parent = {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. This would be done as follows: //---------------------------------------------------------------------------
void __fastcall TExercise::ExerciseCreate(TObject *Sender)
{
TSomeControl * ctlShowMe = new TSomeControl(Mom);
ctlShowMe->Parent = Mom;
}
//---------------------------------------------------------------------------
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. Here is an example: //---------------------------------------------------------------------------
class TExercise : public TForm
{
__published: // IDE-managed Components
private:
TSomeControl * ctlShowMe; // User declarations
public: // User declarations
__fastcall TExercise(TComponent* Owner);
};
//---------------------------------------------------------------------------
After declaring the control, you can sepecify its parent and owner in the constructor of the form as follows: //---------------------------------------------------------------------------
__fastcall TExercise::TExercise(TComponent* Owner)
: TForm(Owner)
{
ctlShowMe = new TSomeControl(Mom);
ctlShowMe->Parent = Mom;
}
//---------------------------------------------------------------------------
If you had declared the variable using an ancestor class that does not have a Parent property, you must cast the variable to the class of the control. Here is an example: TObject * ctlSubmit = new TButton(this); ((TButton *)ctlSubmit)->Parent = this; Because many programmers recommend not using C casting, you can use a C++ cast operator (static_cast, reinterpret_cast, or dynamic_cast). Here is an example: TObject * ctlSubmit = new TButton(this); (dynamic_cast<TButton *>(ctlSubmit))->Parent = this; 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. Here is an example: //--------------------------------------------------------------------------- void __fastcall TExercise::Configure(TObject *Sender) { TWinControl *Poppy = TSomeControl->Parent; if( Poppy == this ) ShowMessage("The form is your daddy"); } //--------------------------------------------------------------------------- Alternatively, to find out what object acts as a control’s parent, call the Win32 API’s GetParent() function. Its syntax is: HWND GetParent(HWND hWnd); The hWnd argument must be a handle to the control whose parent you want to find out. Here is an example: //--------------------------------------------------------------------------- void __fastcall TExercise::Configure(TObject *Sender) { HWND Poppy = GetParent(SomeControl->Handle); if( Poppy == this->Handle ) ShowMessage("The form is your daddy"); } //---------------------------------------------------------------------------
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:
From what we have learned so far, here is a complete control created by calling the CreateWindow() function: //---------------------------------------------------------------------------
void __fastcall TExercise::ExerciseCreate(TObject *Sender)
{
HWND hWndButton = CreateWindow("Button", "Submit",
WS_CHILD,
10, 10, 124, 25,
Handle,
NULL,
HInstance,
NULL);
}
//---------------------------------------------------------------------------
|
|
|||||||||||||||
|
|
||
Previous | Copyright © 2010-2016, FunctionX | Next |
|