( draft . . .)
| ABC Tutorials |
(Event-driven programming)
This program displays the plot for a cubic polynomial: C0 + C1 x + C2 x2 + C3 x3.
Subjects covered:
Start C++Builder. An empty form is created by default. Select File
Save
Project As, and in C++Builder Project directory create the directory SciProg as well as the subdirectory
CubicPolinomial. Save Unit1 as fPolynomial and Project1 as Polynomial.
C++Builder generates the following C++ files: Polynomial.cpp, fPolynomial.h and fPolynomial.cpp. C++Builder also generates several files with IDE settings and resources (see "C++Builder generated files" in C++Builder Help).
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("fPolynomial.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
Normally you do not work with the program file directly. It is automatically updated by C++Builder.
//---------------------------------------------------------------------------
#ifndef fPolynomialH
#define fPolynomialH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:// IDE-managed Components
private:// User declarations
public:// User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
In this header only one class, TForm1, is defined. It is derived from TForm declared in the Forms.hpp and introduces no new functionality. C++Builder inserts the necessary #include directives during the visual desine. You may need include your C++ files manually.
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "fPolynomial.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
The source file implements the constructor, which currently only calls the base class constructor. It also refers to the resources necessary for the form creation ( see the C++Builder Help for details).
The variable Form1 of the type TForm1* is also declared. It could be renamed in the Object Inspector.
This is a fully-functional program (although it does nothing useful) and you
can run it (click
or press F9).
Note: right-clicking on fPolynomial tab and selecting Open
Source/Header file toggles *.h
*.cpp .
Stop the program, click on the fPolynomial tab:
and press F12 to toggle code
design.
Drop Panel on the form and make it large enough for the following components. In the Object Inspector set
its Name to PanelBottom, Caption
empty string. Drop 8 Labels on the Panel, accept their default names and set the captions to
'X min', 'X max', 'C min', 'C max', 'C 0', 'C 1', 'C 2', 'C 3'.
Drop 4 ScrollBars and name them 'ScrollBarC0', 'ScrollBarC1', 'ScrollBarC2', 'ScrollBarC3'. Drop 4 Edits and name them 'EditXmin', 'EditXmax', 'EditCmin', 'EditCmax'. Arrange all components according to the picture.
Change the Anchors properties of the scrollbars to [akLeft,akRight]. This make the scrollbars to resize automatically with resizing the form. Tip: by Shift-clicking select them all and change the properties at once. Set Align property to alBottom.
Drop another Panel on the form, assign Name to PanelTop. Set Align property to alClient.
Drop the PaintBox component on PanelTop and set its Align property to alClient.
Take a look at the class TForm1 now. Note, that C++Builder updates the TForm1 class declaration.
Try to run the program.
Add the following declarations to the private section of TForm1:
private:// User declarations
double c0, c1, c2, c3, Cmin, Cmax;
double Xmin, Xmax, Ymin, Ymax;
double p3(double x);
void SetParameters();
Add the following code into fPolynomial.cpp:
// Cubic polynomial
double TForm1::p3(double x)
{
return c0+x*(c1+x*(c2+x*c3));
}
// Reads parameters from Edits and Scrollbars,
// Calculates Y-limits
void TForm1::SetParameters()
{
int n = 50;
double x;
Xmin = StrToFloat(EditXmin->Text);
Xmax = StrToFloat(EditXmax->Text);
Cmin = StrToFloat(EditCmin->Text);
Cmax = StrToFloat(EditCmax->Text);
c0 = Cmin + (Cmax-Cmin)*ScrollBarC0->Position/ScrollBarC0->Max; // Min = 0
c1 = Cmin + (Cmax-Cmin)*ScrollBarC1->Position/ScrollBarC1->Max; // Min = 0
c2 = Cmin + (Cmax-Cmin)*ScrollBarC2->Position/ScrollBarC2->Max; // Min = 0
c3 = Cmin + (Cmax-Cmin)*ScrollBarC3->Position/ScrollBarC3->Max; // Min = 0
Ymin = 1.0e+9;
Ymax =-1.0e+9;
for (int i = 0; i <= n; i++)
{
x = Xmin+(Xmax-Xmin)*i/n;
Ymin = min(Ymin, p3(x));
Ymax = max(Ymax, p3(x));
}
Ymax = Ymax + 0.1;
Ymin = Ymin - 0.1;
}
Select Form1 from the drop-down box in the Object Inspector and flip to the Events tab. Select OnCreate and double-click on the white field to the right. It creates the procedure FormCreate in the implementation section. Add the call to SetParameters:
void __fastcall TForm1::FormCreate(TObject *Sender)
{
SetParameters();
}
Select PaintBox1 and select its OnPaint event. Create PaintBox1Paintprocedure by double clicking to the white field. Type the following code:
void __fastcall TForm1::PaintBox1Paint(TObject *Sender)
{
int n = 50;
int mX, mY, ix, iy, OldWidth;
double x, y;
SetParameters();
mX = PaintBox1->ClientWidth;
mY = PaintBox1->ClientHeight;
PaintBox1->Canvas->Brush->Color = clWhite; // makes white backgrownd
PaintBox1->Canvas->FillRect(PaintBox1->ClientRect); // fill PaintBox with Brush->Color
// zero line
ix = 0;
y = 0.0;
iy = int(mY*(Ymax-y)/(Ymax-Ymin)+0.5);
PaintBox1->Canvas->MoveTo(ix, iy);
PaintBox1->Canvas->Pen->Color = clRed;
PaintBox1->Canvas->LineTo(mX, iy);
PaintBox1->Canvas->Pen->Color = clBlack;
// polynomial plot
ix = 0;
y = p3(Xmin);
iy = int(mY*(Ymax-y)/(Ymax-Ymin)+0.5);
PaintBox1->Canvas->MoveTo(ix, iy);
OldWidth = PaintBox1->Canvas->Pen->Width;
PaintBox1->Canvas->Pen->Width = 2;
for (int i = 1; i <= n; i++)
{
x = Xmin+(Xmax-Xmin)*i/n;
y = p3(x);
ix = int(i*mX/n+0.5);
iy = int(mY*(Ymax-y)/(Ymax-Ymin)+0.5);
PaintBox1->Canvas->LineTo(ix, iy);
};
PaintBox1->Canvas->Pen->Width = OldWidth;
}
The last event handler processes the scrollbars' movement. Select e.g. ScrollBarC0 and its OnChange event. Create the ScrollBarC0Change procedure:
void __fastcall TForm1::ScrollBarC0Change(TObject *Sender)
{
PaintBox1Paint(Sender);
}
Select the same procedure for the rest of the scrollbars:
Run the program:
The project code for C++Builder can be downloaded here.
(in preparation)
| Scientific programming |
©Nikolai V. Shokhirev, 2004-2005