Over all, it is not strictly necessary to know Win32 thoroughly to write programs; but it is highly valuable to know some or most of the intricacies of its implementations. Since Win32 “tells” Microsoft Windows what to do, it is important to know how Windows functions.
In order to create a Win32 application in Borland C++ Builder, you would call the New Items dialog box. From the General property page, click the Console Application icon and click OK. From the Console Wizard
dialog box, click the C++ radio button
and make sure the Console Application check box is unchecked. When writing a Win32 application, Borland C++ Builder displays a syntax of the
WinMain() function.
Practical Learning: Starting a Win32 Application |
|
- If you did not do so already, start Borland C++ Builder. From the main menu, click File
-> New -> Other (or File -> New)
- From the New Items dialog box, click the Console Wizard icon and click OK.
- In the Console Wizard dialog, make sure the C++ radio button is selected. On the right side,
leave all check boxes empty (or unchecked):
- Click OK
The WinMain() Function Definition |
|
Just like every C++ application starts from a function called main(), every Win23 application starts with a function called
WinMain(). The syntax of the WinMain() function is:
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow);
|
The first argument, hInstance, represents the current instance of the running application.
The second argument, hPrevInstance, represents a previous instance of the application. In our applications, this parameter will always be ignored or set to NULL.
The third argument, lpCmdLine, is a 32-bit long pointer to a null-terminated string that represents the
attribute(s) of the command line when running the application.
The last argument, nCmdShow, is an integer that directs how the window should appear.
It is a constant integer that can have one of the following values:
Value |
Description |
SW_HIDE |
Used to hide the window. If another window was running
when this one got hidden, that one becomes active. If there were many
windows running, the operating system follows a coordinate system that
allows it to choose the window that was immediately behind the one that
has been hidden. |
SW_MAXIMIZE |
Used to maximize the window. Consequently, the window
fills the whole screen. If other windows were running, they become
hidden. |
SW_MINIMIZE |
Used to minimize the window. If another window was
running, that one becomes active. If there were many windows running,
the operating system follows a coordinate system that allows it to
choose the window that was immediately behind the one that was just
minimized. |
SW_RESTORE |
Restores the window. If the window was maximized, which
means it was covering the whole screen, it uses a dimension and position
that it had prior to this action. |
SW_SHOW |
Activates the window and displays it in its current size
and position. |
SW_SHOWMAXIMIZED |
Activates the window and displays it as a maximized
window. |
SW_SHOWMINIMIZED |
Activates the window and displays it as a minimized
window. |
SW_SHOWMINNOACTIVE |
Displays the window as a minimized window.
This value is similar to SW_SHOWMINIMIZED, except the window is not
activated.
|
SW_SHOWNA |
Displays the window in its current size and position.
This value is similar to SW_SHOW, except the window is not activated.
|
SW_SHOWNOACTIVATE |
Displays a window in its most recent size and position.
This value is similar to SW_SHOWNORMAL, except the window is not
activated.
|
SW_SHOWNORMAL |
Activates and displays a window. If the window is
minimized or maximized, the system restores it to its original size and
position. An application should specify this flag when displaying the
window for the first time. |
The first thing you do when creating a Win32 application is to create a window. A window, or the main window, is created using the
WNDCLASS or the WNDCLASSEX structures. Although still available and used, the
WNDCLASS structure was mainly used with previous versions of Microsoft Windows. Since everything in
WNDCLASS is also available in WNDCLASSEX and more, we will use the
latter for our application.
The WNDCLASS and the WNDCLASSEX structures are defined as follows:
struct WNDCLASS
{ |
struct WNDCLASSEX
{ |
|
|
|
UINT cbSize; |
UINT style; |
|
UINT style; |
WNDPROC lpfnWndProc; |
|
WNDPROC lpfnWndProc; |
int cbClsExtra; |
|
int cbClsExtra; |
int cbWndExtra; |
|
int cbWndExtra; |
HINSTANCE hInstance; |
|
HINSTANCE hInstance; |
HICON hIcon; |
|
HICON hIcon; |
HCURSOR hCursor; |
|
HCURSOR hCursor; |
HBRUSH hbrBackground; |
|
HBRUSH hbrBackground; |
LPCTSTR lpszMenuName; |
|
LPCTSTR lpszMenuName; |
LPCTSTR lpszClassName; |
|
LPCTSTR lpszClassName; |
|
|
HICON hIconSm; |
}; |
}; |
|
In order to use one of these structures, you must first declare it. The name of the variable could be any you like but you should make it easy for the name to reflect the structure you are using. This could be done as follows:
WNDCLASS WndClass;
or
WNDCLASSEX WndClsEx;
The cbSize (Class-Byte Size) member variable of the WNDCLASSEX structure represents the byte size of the object. To find its value, you will use the
sizeof operator like this:
WndClsEx.cbSize = sizeof(WndClsEx);
|
Both structures use a set of constant integers that specify the attributes of the window
style. The attributes are defined as follows:
#define CS_VREDRAW 0x0001
#define CS_HREDRAW 0x0002
#define CS_DBLCLKS 0x0008
#define CS_OWNDC 0x0020
#define CS_CLASSDC 0x0040
#define CS_PARENTDC 0x0080
#define CS_NOCLOSE 0x0200
#define CS_SAVEBITS 0x0800
#define CS_BYTEALIGNCLIENT 0x1000
#define CS_BYTEALIGNWINDOW 0x2000
#define CS_GLOBALCLASS 0x4000
|
When using these attributes, one of them may be enough for your application. You can use one attribute as follows:
WndClass.style = CS_VREDERAW;
|
If you would like to use more than one attribute, you can combine them using the bitwise OR (|) operator. Here is example:
WndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
|
The lpfnWndProc (Long-Pointer-To-A-Function-Window-Procedure) member defines the window procedure. It is provided from an external function that we will review later.
The cbClsExtra (Class-Byte-Class-Extra) and the cbWndExtra (Class-Byte-Window-Extra) members specify the number of extra bytes to provide to the object.
Both members receive a value of 0 for regular programs.
The hInstance (Handle-Instance) represents the instance of the current window.
The hIcon (Handle-Icon) variable represents an icon for the current application. If you do not have an icon or you do not want to specify an icon, set this value to NULL. In that case the application would use the default icon. Otherwise, you can use the
LoadIcon() function to include an icon.
The hCursor (Handle-Cursor) member is used to specify a cursor for the application. You mostly use the
LoadCursor() function to specify a cursor for the application.
The hbrBackground (Handle-Brush-Background) member is used to set a color for the background of the window.
If you decide to display a menu, you can set its identifier using the lpszMenuName
(Long-Pointer-To-A-String-As-The-Menu's-Name). If you do not have a menu, set this variable to NULL.
Every window must have a name in your application. This allows you and the application to refer to that window. The name of the window is a null-terminated string set with the
lpszClassName (Long-Pointer-To-A-String-As-The-Class'-Name) member.
The WNDCLASSEX structure allows you to specify a small icon for the application. This icon is used when the application is displaying in Windows Explorer using the list, details, or small icons views. This is handled by the
hIconSm (Handle-Icon-Small) member variable.
Practical Learning: Filling Out a Window |
|
- To fill out a window structure, change the content of the file as follows:
//---------------------------------------------------------------------------
#include <windows.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
// The variable that will define the window
WNDCLASSEX WndClsEx;
// The window's name
static char szAppName[] = "FirstClass";
// Filling out the structure that builds the window
WndClsEx.cbSize = sizeof(WndClsEx);
WndClsEx.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
WndClsEx.lpfnWndProc = WindowProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hInstance = hInstance;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = szAppName;
WndClsEx.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
return 0;
}
//---------------------------------------------------------------------------
|
After building a window, you must let the operating system
know that you have built a window and intend to use it. Letting the operating
system be aware of the window is referred to as registering it. To register a
window, you can use either the RegisterClass() or the RegisterClassEx()
functions. Their respective syntaxes are:
ATOM RegisterClass(CONST WNDCLASS *lpWndClass );
and
ATOM RegisterClassEx(CONST WNDCLASSEX *lpwcx );
This function takes one argument which is the name of the window you had just
built using either WNDCLASS or WNDCLASSEX structures. The argument is passed as
a pointer.
Practical
Learning: Registering a Window |
|
- Register the previous object as follows:
//---------------------------------------------------------------------------
#include <windows.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
// The variable that will define the window
WNDCLASSEX WndClsEx;
// The window's name
static char szAppName[] = "FirstClass";
// Filling out the structure that builds the window
WndClsEx.cbSize = sizeof(WndClsEx);
WndClsEx.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
WndClsEx.lpfnWndProc = WindowProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hInstance = hInstance;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = szAppName;
WndClsEx.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
RegisterClassEx(&WndClsEx);
return 0;
}
//---------------------------------------------------------------------------
|
The use of the WNDCLASS or the WNDCLASSEX structures allow you to
"build" a window. In other words, you lay the foundation of a window
as a structural object. To create the actual window, you use either the CreateWindow() or the
CreateWindowEx() functions and fill it out.
The CreateWindow() function is declared as follows:
HWND CreateWindow( |
|
LPCTSTR
lpClassName, |
// registered class name |
LPCTSTR
lpWindowName, |
// window name |
DWORD dwStyle, |
// window style |
int x, |
// horizontal position of window |
int y, |
// vertical position of window |
int nWidth, |
// window width |
int nHeight, |
// window height |
HWND hWndParent, |
// handle to parent or owner window |
HMENU hMenu, |
// menu handle or child identifier |
HINSTANCE
hInstance, |
// handle to application instance |
LPVOID lpParam |
// window-creation data); |
) |
|
The CreateWindowEx() function has the following arguments:
HWND CreateWindowEx( |
|
DWORD dwExStyle, |
// extended window style |
LPCTSTR lpClassName, |
// registered class name |
LPCTSTR
lpWindowName, |
// window name |
DWORD dwStyle, |
// window style |
int X, |
// horizontal position of window |
int Y, |
// vertical position of window |
int Width, |
// window width |
int Height, |
// window height |
HWND hWndParent, |
// handle to parent or owner window |
HMENU hMenu, |
// menu handle or child identifier |
HINSTANCE
hInstance, |
// handle to application instance |
LPVOID lpParam |
// window-creation data); |
) |
|
For this tutorial, we will use the CreateWindowEx()
version. This function takes quite a few arguments:
The dwExStyle (Window-Extended-Style) argument
specifies the style that would control the window.
The lpClassName (Long-Pointer-to-the-Class'-Name) is
a pointer to a null-terminated string that specifies or represents the name of
the class as the lpszClassName member that was passed to the WNDCLASS or
the WNDCLASSEX structures..
The lpWindowName (Long-Pointer-to-the-Window's-Name)
is a string that would display as the caption of the window. If you do not want
a caption, you can set this argument to NULL or type two double-quotes (that
would represent an empty string).
|
Not providing or specifying the lpWindowName
as NULL does not delete the title bar. In that case, the window would simply not
have a caption. |
The dwStyle (Window-Style) is an unsigned integer
that specifies how to display the window or what style should be used.
The X (X-axis-coordinate) represents the horizontal distance of the
top-left corner of the window from the top left corner of the monitor when the
window appears (See the following picture). If you do not know or cannot make up your mind on the value of
X, you can give it a value of CW_USEDEFAULT
(Class-Window-Use-The-Default-Value). If you set the X argument to
CW_USEDEFAULT, the operating system would use a default value. The CW_USEDEFAULT
value can be selected randomly.
The Y (Y-axis coordinate) represents the vertical distance of the
top-left corner of the window from the top-left corner of the monitor when the
window appears. If you do not know or cannot make up your mind on the value of
Y, you can give it a value of CW_USEDEFAULT. If you set the Y argument to
CW_USEDEFAULT, the operating system would use a default value. The CW_USEDEFAULT
value can be selected randomly.
Both the X and Y arguments represent the Location of the
window:
The Width argument specifies the horizontal
measurement of the window. If you do not know or cannot make up your mind on the
width of the window, you can give it a value of CW_USEDEFAULT. If you set
the Width argument to CW_USEDEFAULT, the operating system would use a
default width.
The Height argument specifies the vertical
measurement of the window. If you do not know or cannot make up your mind on the
height of the window, you can give it a value of CW_USEDEFAULT. If you
set the Height argument to CW_USEDEFAULT, the operating system would use
a default height.
The Width and the Height represents the Size of the window:
The hWndParent (Handle-to-the-Window's-Parent) argument can be used if the window you
are creating will be "owned" by another window. Such a second window would be
considered the parent of the window you are creating. In that case, use the hWndParent
argument to specify the parent of the window you are creating.
The hMenu (Handle-to-a-Menu) specifies the menu to be used with the
current window. If you do not have a menu, pass this argument as NULL.
The hInstance (Handle-Instance) argument is the instance of the current
window, the same that was specified in the window structure.
The lpParam (Long-Pointer-to-a-Parameter) is a long
pointer to a value passed to another class, in case your application is made of
various objects, such as various windows.
Practical Learning: Creating a Window |
|
- Change the content of the file as follows:
//---------------------------------------------------------------------------
#include <windows.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
// The variable that will define the window
WNDCLASSEX WndClsEx;
// The window's name
static char szAppName[] = "FirstClass";
MSG Msg;
// Filling out the structure that builds the window
WndClsEx.cbSize = sizeof(WndClsEx);
WndClsEx.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
WndClsEx.lpfnWndProc = WindowProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hInstance = hInstance;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = szAppName;
WndClsEx.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
RegisterClassEx(&WndClsEx);
CreateWindowEx( WS_EX_OVERLAPPEDWINDOW,
szAppName,
"Basic Win32 Application",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0,
0,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
// return 0;
}
//---------------------------------------------------------------------------
|
Windows Processing of Object's Requests |
|
Every time you create an object in your program, like the
window we have created using the WNDCLASSEX structure, such an object needs to find
a way to communicate with the operating system. It is not the job of the
WinMain() function to let the operating system know what an object wants to do.
As it happens, Microsoft Windows is a message-oriented operating system. Each
object of your program sends messages to Microsoft Windows. Whenever the
operating system receives one of those messages, it must analyze and process it.
To send its messages to the operating system, an object,
such as a window, must send four pieces of information to the operating system.
To send these pieces of information as one request (instead of sending four
disparate requests), the object must put them in a function that would carry
them as arguments. The name of the function is not important but there are rules
the object (actually it is your responsibility) must follow. The function that
carries the message of the object must
- be a callback type. A function is considered as "callback" when
its name can be assigned as a value, that is, without arguments, as if the
name of the function were a regular value (a "normal" C++ function
cannot be assigned to a variable as a value); to make a function call back,
you can declare and define it using the CALLBACK keyword or you can declare and define it using the WINAPI keyword (CALLBACK
and WINAPI are interchangeable)
- return LRESULT as its value
As stated already, the name of the function is not important
but the name of the function must be exactly assigned to the lpfnWndProc
member of the object you are creating. The syntax used for the function is:
LRESULT CALLBACK MyMessages(HWND hWnd, UINT
uMsg, WPARAM wParam, LPARAM lParam);
or
LRESULT WINAPI MyMessages(HWND hWnd, UINT
uMsg, WPARAM wParam, LPARAM lParam);
By tradition or pure habit, most programmers define and
declare this function using words or suffixes like Wind, Wnd, Proc, and
Procedure. Therefore, it is usual to create this function with a name like
WndProc or WindowProc. The syntax of the function
can be written as follows:
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM
wParam, LPARAM lParam);
The hWnd (Handle-Window) argument is a handle to the
object or window that is sending the message(s).
The uMsg (Message) is an unsigned integer that
represents the message that is being sent. Most or all messages are represented
by a map of integral values of the Win32 library.
The wParam (Parameter, the w does not necessarily
mean window) is an additional piece of information that can accompany the uMsg
argument. The value of wParam depends on the type of message that is
being sent. It would mean different things to the operating system if the
message sent has to do with an action on the keyboard (for example if the
message was sent because the user pressed a key on the keyboard) or an action on
the mouse (for example if the message was sent because the user pressed the
right button on the mouse).
The lParam (Parameter, the l does not necessarily
mean window or long integer) is an additional piece of information that can be
sent with the uMsg argument.
Practical Learning: Processing Window Messages |
|
- Just on top of the WinMain() function, add the implementation of the following function (and here is the complete file):
//---------------------------------------------------------------------------
#include <windows.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg,
WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
break;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
//---------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
// The variable that will define the window
WNDCLASSEX WndClsEx;
// The window's name
static char szAppName[] = "FirstClass";
MSG Msg;
// Filling out the structure that builds the window
WndClsEx.cbSize = sizeof(WndClsEx);
WndClsEx.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
WndClsEx.lpfnWndProc = WindowProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hInstance = hInstance;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = szAppName;
WndClsEx.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
RegisterClassEx(&WndClsEx);
CreateWindowEx( WS_EX_OVERLAPPEDWINDOW,
szAppName,
"Basic Win32 Application",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
// return 0;
}
//---------------------------------------------------------------------------
|
- To test your program, press F9
- After viewing the window, return to Bcb.
C++ Builder Application Fundamentals |
|
To make application development easy, that is, to provide Rapid Application
Development (RAD), Borland simpliefied the above steps.
C++ Builder uses the same WinMain() function to create an application. Instead of defining a window class structure and creating a window using the
CreateWindow() function, you can simply add a form and use the TApplication::CreateForm() function to start the application by displaying a form.
Practical Learning: Creating a Basic Application |
|
- To create a new Win32 application, from the main menu, click File -> New
-> Other…
- From the New Items dialog, double-click the Console Wizard icon.
- Since Bcb remembers the last selection made on the Console Wizard dialog, click OK.
- To add a form to the application, on the main menu, click File -> New
-> Form.
- Press F12 to access the Code Editor window.
- Click the Unit1.cpp tab and change the content of the file as follows:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma argsused
WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
Application->Initialize();
Application->CreateForm(__classid(TForm2), &Form2);
Application->Run();
return 0;
}
//---------------------------------------------------------------------------
|
- If the form was created with a unit name other than Unit2, change the name accordingly.
To test the application, press F9.
When creating applications using Borland C++ Builder, you will essentially be choosing objects that are necessary for your application. The objects are provided in a pool, ranging from very simple to
fairly complicated. To manage all these objects, Borland created a library called the Visual Component Library
(VCL) based on the Pascal language but fully adhering to the C++ language.
The VCL is a set of functions, classes, variables, and libraries that provide the application developer to choose which objects are appropriate to respond to a particular
scenario.
The Visual Component Library is organized like a tree (upside-down) with objects inheriting from
earlier ones:
A class called TObject is the ancestor or the parent of all classes used in the
VCL. This class provides the starting point for the other objects. When you will be implementing an object in your application, you can use either the Help files or the poster that ships with C++ Builder to trace the ancestry of the object: but this is not always important.
There are three categories of objects you will be using when creating your programs: the VCL objects, your own objects, and Win32 objects. A program can include one category.
Many of the programs we will be writing essentially consist of VCL objects. A program can also combine data types and objects of any of the three categories.
Here are examples of two objects that implement two geometric figures, namely a trapezoid and a parallelogram:
//---------------------------------------------------------------------------
#include <iostream.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
//---------------------------------------------------------------------------
class TParallelogram
{
public:
__fastcall TParallelogram(double B = 0.00, double H = 0.00)
: Base(B), Height(H) {}
__fastcall TParallelogram(const TParallelogram& P)
: Base(P.Base), Height(P.Height) {}
virtual __fastcall ~TParallelogram() {}
double __fastcall getBase() const { return Base; }
double __fastcall getHeight() const { return Height; }
double __fastcall Area() const { return Base * Height; }
private:
double Base;
double Height;
};
//---------------------------------------------------------------------------
struct TTrapezoid
{
public:
__fastcall TTrapezoid(double B = 0.00, double b = 0.00, double H = 0.00)
: Base(B), base(b), Height(H) {}
__fastcall TTrapezoid(const TTrapezoid& t)
: Base(t.Base), base(t.base), Height(t.Height) {}
virtual __fastcall ~TTrapezoid() {}
void __fastcall setDimensions(double B, double b, double H)
{ Base = B; base = b; Height = H; }
void __fastcall setBase(const double B) { Base = B; }
void __fastcall setbase(const double b) { base = b; }
void __fastcall setHeight(const double H) { Height = H; }
double __fastcall getBase() const { return Base; }
double __fastcall getbase() const { return base; }
double __fastcall getHeight() const { return Height; }
double __fastcall Area() const { return Height * (Base + base) / 2; }
private:
double Base;
double base;
double Height;
};
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TParallelogram Para(6.95, 10.65);
cout << "Characteristics of the Parallelogram";
cout << "\nBase: " << Para.getBase();
cout << "\nHeight: " << Para.getHeight();
cout << "\nArea: " << Para.Area();
cout << "\n\n";
TTrapezoid Trapper(16.25, 20.28, 12.44);
cout << "Characteristics of the Trapezoid";
cout << "\nLower Base: " << Trapper.getBase();
cout << "\nUpper Base: " << Trapper.getbase();
cout << "\nHeight: " << Trapper.getHeight();
cout << "\nArea: " << Trapper.Area();
cout << "\n\n";
cout << "Press any key to continue...";
getchar();
return 0;
}
//---------------------------------------------------------------------------
|
This would produce:
Characteristics of the Parallelogram
Base: 6.95
Height: 10.65
Area: 74.0175
Characteristics of the Trapezoid
Lower Base: 16.25
Upper Base: 20.28
Height: 12.44
Area: 227.217
Press any key to continue...
|
TObject is the ancestor of all objects and classes you will be using when
writing your applications using the VCL. Like any library, the VCL has some
implementations and syntaxes that are particular to it. There are some details
you should be aware of about objects that are part of the VCL. One of those
details involves deriving an object from TObject.
To inherit an object from the TObject class:
- you must use the vcl.h header file in your application
- follow the normal rules applied to C++ inheritance. For example, to create a TBook object based on
TObject, you could write: class TBook : public TObject
- to access a class that is derived from TObject, you must dynamically declare an instance of the class.
Based on these rules, the above classes can be made children of the TObject as follows:
//---------------------------------------------------------------------------
#include <iostream.h>
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
//---------------------------------------------------------------------------
class TParallelogram : public TObject
{
public:
__fastcall TParallelogram(double B = 0.00, double H = 0.00)
: Base(B), Height(H) {}
__fastcall TParallelogram(const TParallelogram& P)
: Base(P.Base), Height(P.Height) {}
virtual __fastcall ~TParallelogram() {}
double __fastcall getBase() const { return Base; }
double __fastcall getHeight() const { return Height; }
double __fastcall Area() const { return Base * Height; }
private:
double Base;
double Height;
};
//---------------------------------------------------------------------------
struct TTrapezoid : TObject
{
public:
__fastcall TTrapezoid(double B = 0.00, double b = 0.00, double H = 0.00)
: Base(B), base(b), Height(H) {}
__fastcall TTrapezoid(const TTrapezoid& t)
: Base(t.Base), base(t.base), Height(t.Height) {}
virtual __fastcall ~TTrapezoid() {}
void __fastcall setDimensions(double B, double b, double H)
{ Base = B; base = b; Height = H; }
void __fastcall setBase(const double B) { Base = B; }
void __fastcall setbase(const double b) { base = b; }
void __fastcall setHeight(const double H) { Height = H; }
double __fastcall getBase() const { return Base; }
double __fastcall getbase() const { return base; }
double __fastcall getHeight() const { return Height; }
double __fastcall Area() const { return Height * (Base + base) / 2; }
private:
double Base;
double base;
double Height;
};
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TParallelogram *Para = new TParallelogram(6.95, 10.65);
cout << "Characteristics of the Parallelogram";
cout << "\nBase: " << Para->getBase();
cout << "\nHeight: " << Para->getHeight();
cout << "\nArea: " << Para->Area();
cout << "\n\n";
TTrapezoid *Trapper = new TTrapezoid(16.25, 20.28, 12.44);
cout << "Characteristics of the Trapezoid";
cout << "\nLower Base: " << Trapper->getBase();
cout << "\nUpper Base: " << Trapper->getbase();
cout << "\nHeight: " << Trapper->getHeight();
cout << "\nArea: " << Trapper->Area();
cout << "\n\n";
cout << "Press any key to continue...";
getchar();
return 0;
}
//---------------------------------------------------------------------------
|
Following the hierarchy of VCL objects, most of the objects we will use in this
book will be derived from a class of the VCL. Your object does not have to use any of the features of VCL or any of the access techniques of C++ Builder.
|
|