Учебные демонстрационные программы на C++ в Borland C++ Builder 6

Бесплатный доступ

Приведено несколько demo-программ на алгоритмическом языке С++ в объектноориентированной среде компилятора Borland С++ Builder 6, показывающие некоторые "современные" требования к программным продуктам и реализуемым возможностям. Это, во-первых, создание формы на экране дисплея для визуализации задачи, размещение на ней объектов-компонент, предлагающих интерактивное выполнение необходимых действий, а также возможности графики, сервисных функций для работы с файлами (поиск, чтение, запись) и запуск приложений.

Объектно-ориентированные языки программирования

Короткий адрес: https://sciup.org/147245411

IDR: 147245411   |   DOI: 10.17072/1993-0550-2018-4-60-73

Текст научной статьи Учебные демонстрационные программы на C++ в Borland C++ Builder 6

В основе предлагаемых программ использованы некоторые demo-модули компилятора CBuilder 6, которые переработаны и дополнены для более полного представления начинающим программистам о возможностях применения различных компонент языка С++.

Рассмотрено применение следующих объектов и событий, это –

– графические компоненты ( PaintBox, Image, Chart ); при построении графика на объекте типа Image средствами Canvas приводятся формулы, связывающие истинные координаты графика с графическими координатами экрана дисплея;

– компоненты выбора цвета ( ColorGrid, ColorBox ); событие OnChange в объекте типа ColorGrid или событие OnСlick в объекте ColorBox отслеживают и выполняют оперативное изменение выбранного цвета;

– группа быстрых кнопок SpeedButton для выбора инструмента последующего графического рисования с помощью курсора, управляемого "мышью": PencilButton – для рисования тонких линий; FillButton – для закрашивания области, ограниченной тонкими линиями;

EraseButton – для стирания рисунка; CircleButton и SquareButton – для рисования тонких линий (окружность или эллипс и квадрат или прямоугольник); SolidClrButton и SolidSqButton – для рисования сплошных "закрашенных" геометрических тел (круг/ эллипс, квадрат/ прямоугольник); для оперативного отслеживания движения "мыши" предусмотрена обработка событий OnMouseDown, OnMouseMove, OnMouseUp , в которой определяются графические координаты "мыши";

– компонент Shape для отображения на форме различных геометрических фигур;

– компонент панель заголовков ( HeaderControl ) с помощью выполнения события OnSectionTrack настраивает размеры других объектов (например, Shape ) под размеры разделов панели заголовков;

– компонент текстовой области Memo для ввода и хранения, например, справочной информации;

– невизуальный компонент Timer и событие OnTimer моделируют процессы, связанные с реальным временем (например, вращение нарисованных фигур);

– компонент главное меню (объект MainMenu ) с помощью события OnClick запускает на выполнение выбранный элемент из MainMenu, это может быть некоторая функция или самостоятельный exe-модуль.

Предусмотрено копирование графических объектов в буфер ( Clipboard Windows ) для сохранения в Word-документе.

В приложениях часто нужно предусмотреть поиск файлов без online-выхода из выполняемого модуля в среду операционной системы. А так как предлагаемых функций в алгоритмических языках (в C++ это FindFirst, FindNext, FileSearch ) недостаточно, то предложены демонстрационная программа, функции поиска файлов и запуска на выполнение найденного exe-модуля. Предлагаемые функции могут быть полезны начинающим программистам.

Все demo-программы работают в интерактивном режиме, для изменения параметров, выбора цвета, инструментов, конкретных действий используются объекты-компоненты – LabelEdit , панель группы переключателей RadioGroup , кнопки Button , панель страниц-вкладок PageControl и др. На панели типа StatusBar или в заголовке всех программ приведена справочная информация – на какой вкладке компилятора находятся необходимые объекты.

1. Модуль Canvas _new3.exe (проект Canvas_new.bpr , рис. 1, 2) демонстрирует построение графических фигур на объекте типа PaintBox (вкладка System) с помощью графического средства – Canvas (холст). Это прямоугольная поверхность, на которой выполняется рисование функцией-обработчиком события OnPaint. Для размещения на рисунке различных фигур нужно определить центр рисунка и структурный массив их направляющих косинусов . Реализовано построение и режим вращения 12 графических фигур. Выбор и активация нужного рисунка ( int num ) выполняется в интерактивном режиме с помощью объекта типа ComboBox (вкладка Standard), а режим вращения ( int koef ) – на объекте типа RadioGroup . Графические фигуры 1–11 состоят из окружностей и отрезков,

соединяющих все базовые точки на этих окружностях, а 12-я демонстрирует движение " колеса " по большой круговой орбите (число базовых точек 16).

Для фигур 1–11 предусмотрено интерактивное определение числа базовых точек ( int PointCount ) на окружностях и рисующего цвета ( TColor col ) на объекте типа ColorGrid (вкладка Samples).

Предусмотрено сохранение активного рисунка в буфере Windows.

На рис. 1 приведен вид формы demo-модуля со всеми объектами и активным рисунком 12, а на рис. 2 – сохраненные копии рисунков 1 и 7.

Рис. 1. Копия формы demo-модуля (num=12)

Рис. 2. Копии рисунков (num=1, num=7)

При выборе рисунка (объект Com-boBox1 , событие OnClick ) управление передается на кнопку " Построить " (функция But-ton3Click ), определяются направляющие косинусы соответствующих фигур рисунка и его полная перерисовка. Приведем фрагмент функции.

void __fastcall TFormMain::Button3Click(TObject *Sender)

{ int i,nn,angle;

nn=ComboBox1->ItemIndex+1;

switch (nn)

{ case 1 :

for (i = 0, angle = 45; i < 4; i++, angle += 90)

{ P8[i].X = cos(angle*M_PI/180.0); P8[i].Y = sin(angle*M_PI/180.0 ); } break;

//……………………………………………………………………..

case 11:

for (i = 0, angle =0; i < 4; i++, angle += 90)

{ P8[i].X = cos(angle*M_PI/180.0); P8[i].Y = sin(angle*M_PI/180.0); } for (i = 0, angle =45; i < 4; i++, angle += 90)

{ P11[i].X = cos(angle*M_PI/180.0); P11[i].Y = sin(angle*M_PI/180.0); } break;

} col = ColorGrid1->ForegroundColor;

i=interval; interval=StrToIntDef(Led_time->Text,i);

if(nn==12)

{nc=0; nred=0; Rotation=0; MaxPoints=16; Led_max->Text=IntToStr(MaxPoints);} if(nn==13) {nc=0; Rotation=0;}

Led_time->Text=IntToStr(interval); Timer1->Enabled=false;

Timer1->Interval=interval; Timer1->Enabled=true;

PointCount=MaxPoints; RotatePoints(); FormPaint(Sender);}

Для реализации эффекта вращения активного рисунка введен невизуальный объект – TTimer *Timer1 , его основное свойство Timer1–>Interval содержит интервал времени между генерацией события OnTimer , т.е. ско-

рость вращения активного рисунка. Приведем функцию Led_timeClick , определяющую в интерактивном режиме скорость вращения (в мс) и последующую работу модуля под управлением таймера.

void __fastcall TFormMain::Led_timeClick(TObject *Sender)

{ int i; i=interval;

interval=StrToIntDef(Led_time->Text,i);

if (interval<250) interval=max(i,250);

Led_time->Text=IntToStr(interval);

Timer1->Enabled=false;

Timer1->Interval=interval; Timer1->Enabled=true;

RotatePoints(); FormPaint(Sender); }

Если входные параметры (номер рисун- ределяет событие OnTimer и соответствую-ка, режим, цвет) не меняются, то работу мо- щая функция-обработчик Timer1Timer. дуля под управлением таймера автономно оп- void __fastcall TFormMain::Timer1Timer(TObject *Sender)

{ RotatePoints(); if (RadioGroup1->ItemIndex==0) return; Invalidate(); }

Для полной перерисовки рисунка здесь использован метод Invalidate, который позволяет избежать мерцания изображения. Кроме

того, для правильной перерисовки на главной форме нужно предусмотреть событие OnRe-size и его функцию-обработчик FormResize.

void __fastcall TFormMain::FormResize(TObject *Sender) { Invalidate(); }

Каждый шаг работы таймера и всех случаев интерактивного изменения входных параметров ( num – номер рисунка, PointCount – число базовых точек, col – выбранный цвет, koef – направление вращения) заканчивается обращением к двум функциям, это

RotatePoints() и функция-обработчик FormPaint (Sender) для события OnPaint.

Для их выполнения введены геометрические параметры и структурные массивы для вычисления направляющих косинусов центров окружностей и их базовых точек на очередном шаге вращения:

  • а)    угол поворота за 1 шаг вращения ( 2*pi/32 для графических фигур 1–11 и 2pi/8 для фигуры 12);

  • б)    центральный угол ( float StepAngle ) между базовыми точками, т.е. угловое расстояние между точками;

  • в)    угол (float Rotation) , накапливается с учетом направления вращения на каждом следующем шаге возникновения события OnTimer;

  • г)    struct TRPoint { float X, Y; };

TRPoint Points[200], P8[10], P11[10], P12[10] ;

  • – для направляющих косинусов.

Углы StepAngle и Rotation нужны для определения на каждом шаге вращения но- вых координат базовых точек.

Функция RotatePoints() – корректирует угол Rotation , вычисляет относительно центра вращения (центр рисунка) направляющие косинусы в массиве Points для определения координат базовых точек окружностей, а для фигуры 12 вычисляет в массиве P12 направляющие косинусы мини-кругов относительно центра "колеса" и очередной точки касания. Мини-круги при движении "колеса" двигаются по хордам большой окружности.

Для определения центров окружностей на каждом рисунке в P8 и P11 вычисляются их направляющие косинусы.

void __fastcall TFormMain::RotatePoints()

{ float angle,angl2;

num=ComboBox1->ItemIndex+1; if ( num==12) PointCount=16;

StepAngle = M_2PI /PointCount; // angular distance between points switch (RadioGroup1->ItemIndex) // режим направления вращения

{ case 0 : koef=0; break; case 1 : koef=1; break; case 2 : koef=-1; break;

// не вращать

// вправо

} // влево // end switch if (num==12) Rotation += koef*M_PI / 8;    // угол поворота рисунка по OnTimer if (num<12) Rotation += koef*M_PI / 32;     // Increment the angle of rotation of figure if ((Rotation > StepAngle)&(num<12)) Rotation -= StepAngle; angl2=Rotation;

for (int i = 0, angle = Rotation; i < PointCount; i++, angle += StepAngle)

{ Points[i].X = cos(angle);            // These values will be multiplied by the

Points[i].Y = sin(angle);             // current radius at display time.

{ if (i>0) angl2=angl2+2*StepAngle;

P12[i].X=cos(angl2); P12[i].Y=sin(angl2); }

}

}

// end

Функция FormPaint(TObject *Sender) – Оператор switch(num) управляет выбором обработчик события OnPaint, выполняет ри- рисунка. Приведем фрагмент функции сование активного рисунка на объекте Paint- FormPaint для двух фигур ( num =1 и 12). Box1 с учетом его реальных размеров.

void __fastcall TFormMain::FormPaint(TObject *Sender)

{ int centerX = PaintBox1->Width / 2; int centerY = PaintBox1->Height / 2; int radius = std::min(centerY, centerX); PaintBox1->Color=clWhite;

// координаты центра вращения

// радиус большой окружности

// цвет фона

PaintBox1->Canvas->Rectangle(0, 0, radius*2, radius*2); // рамка num=ComboBox1->ItemIndex+1;       // номер рисунка switch (num)

{ case 1: goto one;

//...................................................

case 12: goto twelve;

default: num=1; ComboBox1->ItemIndex=num-1; goto end;

}

// 1 big circle+4 small..................................................

one: r1=radius*(3.0-sqrt(8.0)); dr=(radius-r1)*sqrt(2.0);

for (i = 0; i < 4; i++) { x0=radius + floor(P8[i].X * dr);

y0=radius + floor(P8[i].Y * dr);

y1=y0-r1; y2=y0+r1; x1=x0-r1; x2=x0+r1;

PaintBox1->Canvas->Ellipse(x1, y1, x2, y2);

for (int i1 = 0; i1 < PointCount; i1++) { for (j = i1 + 1; j < PointCount; j++)

{ PaintBox1-> Canvas->MoveTo(x0 + floor(Points[i1].X * r1), y0 + floor(Points[i1].Y * r1));

PaintBox1-> Canvas->LineTo(x0 + floor(Points[j].X * r1), y0 + floor(Points[j].Y * r1));

} } //j,i

}

//------------------------------ big circle

PaintBox1->Canvas->Ellipse(0, 0, radius*2, radius*2);

for (i = 0; i < PointCount; i++) { for (j = i + 1; j < PointCount; j++) {

PaintBox1-> Canvas->MoveTo(radius + floor(Points[i].X * radius), radius + floor(Points[i]. Y * radius));

PaintBox1-> Canvas->LineTo(radius + floor(Points[j].X * radius), radius + floor(Points[j]. Y * radius));

} } goto end;

twelve: PaintBox1->Canvas->Pen->Color = clBlack;

PaintBox1->Canvas->Ellipse(0, 0, radius*2, radius*2); npt=PointCount;

for (i = 0; i < npt; i++)                                 //------- big circle

{ PaintBox1->Canvas->MoveTo(radius + floor(Points[i].X * radius), radius + floor(Points[i].Y * radius));

PaintBox1->Canvas->LineTo(radius,radius); }

// ---- центр колеса, касающегося большого круга xc0=radius+floor(P12[0].X * radius)/2;

yc0=radius+floor(P12[0].Y * radius)/2;

PaintBox1->Canvas->Ellipse(xc0-2, yc0-2, xc0+2, yc0+2);

rad_1=radius/2;

// ------координаты центров мини-кругов колеса xc1=xc0+floor(P12[0].X * rad_1*0.9);

yc1=yc0+floor(P12[0].Y * rad_1*0.9);

if((0==nred)) PaintBox1->Canvas->Pen->Color = clRed;

else PaintBox1->Canvas->Pen->Color = clBlack;

for ( k = 10; k >0; k--)

{PaintBox1->Canvas->Ellipse(xc1-k, yc1-k, xc1+k, yc1+k);}

// ------ остальные 7 мини-кругов колеса.

PaintBox1->Canvas->Pen->Color = clBlack;

for (i = 1; i < npt/2; i++)

{ if((i==nred)) PaintBox1->Canvas->Pen->Color = clRed;

else PaintBox1->Canvas->Pen->Color = clBlack;

xc1=xc0+floor(P12[i].X * rad_1*0.9); //nn yc1=yc0+floor(P12[i].Y * rad_1*0.9);

for (k = 10; k >0; k--)

{PaintBox1->Canvas->Ellipse(xc1-k, yc1-k, xc1+k, yc1+k);}

}

PaintBox1->Canvas->Pen->Color = clBlack;

if(koef>0) {nc=nc+1; if (nc==8) nc=0;nred=nred-1; if(nred<0)nred=7; } if(koef<0) {nc=nc-1; if (nc<0) nc=7; nred=nred+1; if(nred==8)nred=0;} StatusBar1->SimpleText=IntToStr(nc)+"+"+IntToStr(nred);

goto end ;

// ...................................

end: PaintBox1->Canvas->Pen->Color = col;

PaintBox1->Canvas->TextOut(0,5,"¹"+IntToStr(num));

Application->ProcessMessages(); }

Выбор цвета для фигур 1–11 выполняет функция CColorGrid1Change (приведем фрагмент)

void __fastcall TFormMain::CColorGrid1Change(TObject *Sender).

{ //.

//. }

TColor col = ColorGrid1->ForegroundColor ;

//рисующий цвет

PaintBox1->Canvas->Pen->Color = col;

..

Сохранение рисунка из PaintBox1 в ClipBoard Windows выполняет функция Button2Click .

void __fastcall TFormMain::Button2Click(TObject *Sender)

{ int x0,y0,d_x,d_y;

Graphics::TBitmap* Bitmap=new Graphics::TBitmap;

//левый верхний угол

// P=PaintBox1->ClientToScreen(P);

x0 = P.x; y0 = P.y; d_x=PaintBox1->Width; d_y=PaintBox1->Height;

Bitmap->Width =d_x; Bitmap->Height=d_y;

BitBlt(Bitmap->Canvas->Handle,0,0,d_x,d_y,GetDC(0),x0,y0,SRCCOPY);

Clipboard()->Assign(Bitmap);

StatusBar1->SimpleText="Копирование рисунка в ClipBoard";

delete Bitmap; }

2. Модуль Doodle_new.exe ( проект Doodle_new.bpr , рис. 3) демонстрирует процесс графического рисования на экране движением "мыши" на объекте типа Image. Выбор "инструмента" (линии, примитивы) выполняют быстрые кнопки SpeedButton (вкладка Additional), расположенные на форме demo-модуля в объекте PageControl на вкладке " Tool " (рис. 3, справа).

Реализованы быстрые кнопки-"инстру-менты": PencilButton – рисование тонких линий; FillButton – закрашивание области, ограниченной тонкими линиями; EraseButton – стирание рисунка; CircleButton и SquareButton – рисование тонкими линиями фигур-примитивов (круг/эллипс, квадрат/прямо-угольник); SolidClrButton и SolidSqButton – рисование сплошных закрашенных геометрических тел (круг/ эллипс, квадрат/ прямоугольник). Выбор быстрой кнопки на вкладке " Tool " (событие OnClick ) – с помощью курсора, управляемого "мышью", а для оператив-

ного отслеживания ее движения (т.е. процесса рисования) предусмотрены события OnMouseDown, OnMouseMove, OnMouseUp и их обработчики , которые определяют графические координаты "мыши".

Цвет рисования определяется на вкладке " Color " на форме demo-модуля. Для создания этой вкладки использован объект типа ColorGrid (вкладка Samples).

Рис. 3. Копия формы demo-модуля Doodle_new

Чтобы увидеть особенности реализации нужно установить соответствие – события и их функции-обработчики :

  • а)    OnCreate, OnActivate, OnClose для всей формы – функции FormCreate, FormActivate, FormClose для создания базовых средств рисования, активации размеров формы, закрытия формы;

  • б)    OnChange для объекта ColorGrid1 на вкладке Color формы demo-модуля – функция ColorGrid1Change (см. п. 1), выбирает рисующий цвет;

  • в)    OnClick быстрых кнопок FillButton, PencilButton, EraseButton на вкладке Tool формы – функции FillButtonClick, PencilButtonClick, EraseButtonClick для активации выбранного простейшего рисующего "примитива";

  • г)    OnClick быстрых кнопок CircleButton, SquareButton, SolidClrButton, Solid-SqButton – функция ShapeButtonClick для активации рисующих фигур (круг, эллипс, квадрат, прямоугольник и др.);

  • д)    OnMouseDown, OnMouseMove, OnMouseUp для объекта Image1 – функции Image1MouseDown, Image1MouseMove, Im-age1MouseUp для отслеживания движения курсора-мыши и рисования линий стандартными графическими функциями MoveTo, Li-neTo в С++, фигур с помощью функции DrawShape , созданной в проекте demo-модуля.

Сохранение рисунка в буфере Windows выполняет кнопка " CopyToClipBoard " (функция Button1Click). Приведем некоторые функции.

void __fastcall TDoodleForm::FormCreate(TObject *Sender)

{

HINSTANCE HInst;

HInst = reinterpret_cast(HInstance);

Screen->Cursors[crFill] = LoadCursor(HInst, "FILL");

Screen->Cursors[crPlus] = LoadCursor(HInst, "PLUS");

Screen->Cursors[crDraw] = LoadCursor(HInst, "DRAW");

Screen->Cursors[crErase] = LoadCursor(HInst, "ERASE");

Cursor = TCursor(crDraw);

DoodleForm->Caption="Additional>Image(Canvas),Shape; Samples>ColorGrid";

}

//--------------------------------------------------------------------------- void __fastcall TDoodleForm::FormActivate(TObject *Sender)

{ if (DoodleForm->Visible) return;

DoodleForm->Top = DoodleForm->Top + (DoodleForm->Height / 6);

DoodleForm->Left = DoodleForm->Left - ((DoodleForm->Width / 5)); DoodleForm->Show();}

//--------------------------------------------------------------------------- void __fastcall TDoodleForm::PencilButtonClick(TObject *Sender)

{ DoodleForm->Cursor = TCursor(crDraw); }

//--------------------------------------------------------------------------- void __fastcall TDoodleForm::ShapeButtonClick(TObject *Sender)

{ DoodleForm->Cursor = TCursor(crPlus); }

//--------------------------------------------------------------------------- void __fastcall TDoodleForm::Image1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)

{ // Only the left mouse button is of interest if (Button != mbLeft) return;

if ((DoodleForm->FillButton->Down) || (DoodleForm->PencilButton->Down)) return;

if (DoodleForm->EraseButton->Down)

{ Image1->Canvas->Pen->Width = 1; return; }

DrawShape(X, Y); delete TmpImage;}

//--------------------------------------------------------------------------- void __fastcall TDoodleForm::DrawShape(int X, int Y)

{ TRect bounds; // for graphics functions which require a rect

Image1->Picture = TmpImage->Picture;

Image1->Canvas->Brush->Color = DoodleForm->FGShape->Brush->Color;

Image1->Canvas->Pen->Color = DoodleForm->FGShape->Brush->Color;

if (X < InitialX)

// Draw the circle or square using the corresponding function.

if (DoodleForm->CircleButton->Down)

Image1->Canvas->Arc(InitialX, InitialY, X, Y, X, Y, X, Y);

else if (DoodleForm->SolidCirButton->Down)

Image1->Canvas->Ellipse(InitialX, InitialY, X, Y);

else if (DoodleForm->SquareButton->Down) Image1->Canvas->FrameRect(bounds);

else if (DoodleForm->SolidSqButton->Down) Image1->Canvas->FillRect(bounds);

}

//------------------------------------------------------------------------------- void __fastcall TDoodleForm::Button1Click(TObject *Sender)

{ Clipboard()->Assign(DoodleForm->Image1->Picture->Bitmap); }

Рис. 4. Копия формы demo-модуля Function

Связь истинных координат (X,Y) графика с графическими координатами (PX,PY) объекта типа Image имеет вид:

X=a*PX+b; PY=c*Y+d .

Параметры связи a, b, c, d определяются из очевидных условий

Xmin=a*0+b; Xmax=a*Width+b;

0=c*Ymax+d; Height=c*Ymin+d.

В demo-примерах принято:

Xmin=0; Xmax=4pi; Ymax=1; Ymin=-1, m – интерактивный масштабный коэффициент.

Рассмотрим некоторые функции-кнопки demo-модуля.

Функция Button1Click ( Button1 -> Caption = " Рисовать " ) реализует рисование выбранного графика с учетом обрезания, если он выходит за выбранный диапазон.

void __fastcall TForm1::Button1Click(TObject *Sender)

{ float X, Y,ymin0,ymax0;        // Переменные функции int PX, PY,kk;                     // Координаты пикселов

Form1->Button4Click(0); kk=0;    // Очистить область графика

Image1->Canvas->MoveTo(0, Image1->Height/2); // ось ОХ Image1->Canvas->LineTo(Image1->Width, Image1->Height/2);

Image1->Canvas->MoveTo(0, 0);                  //ось ОY

Image1->Canvas->LineTo(0,Image1->Height);

Image1->Canvas->MoveTo(0, Image1->Height/2); Xmin=0;Ymin=100; Xmax=0; Ymax=0;

for (PX=0; PX<=Image1->Width; PX++)

{ X=PX*4*PI/Image1->Width;

switch (n) //номер функции

{ case 1: Y=m*sin(X); break;

//...................................................

case 5: Y=m*(cos(X)+sin(X)); break;

default: break;

}

PY=Image1->Height-(Y+1)*Image1->Height/2;

if (PY<0) { PY=0; ymax0=1.0; kk=1;} if (PY>Image1->Height )

{ PY=Image1->Height-1; ymin0=2.0/Image1->Height-1; kk=1;}

Image1->Canvas->LineTo(PX, PY);

Xmin=std::min(Xmin,X);Xmax=std::max(Xmax,X);

Ymin=std::min(Ymin,Y);Ymax=std::max(Ymax,Y); }

//.........................................

}

Функция-кнопка Button4Click выполняет очистку области рисования, т.е. Image1 :

void __fastcall TForm1::Button4Click(TObject *Sender)

{ Image1->Canvas->FillRect(Rect (0,0,Image1->Width, Image1->Height));}

Остальные кнопки – это изменение m- параметра, выбор функции и построение графика прямым переключением на кнопку " Рисовать " одним оператором Form1-

>Button1Click(0);

Функция Button6Click копирует график из объекта Image1 в буфер ClipBoard Windows

void __fastcall TForm1::Button6Click(TObject *Sender){ Clipboard()->Assign(Form1->Image1->Picture->Bitmap); }

  • 4.    Модуль My_Prim.exe (проект My_prim.bpr, рис. 5) демонстрирует часто применяемые объекты и их возможности, это PageControl (вкладка Win32) c набором вложенных страниц-вкладок; компонент текстовая область Memo (вкладка Standard) – для информации о модуле и предлагаемых действиях; объекты типа LabelEdit (вкладка Additional) для интерактивного ввода параметров; стандартный графический объект Chart-диаграммы (вкладка Additional) для эффективного и удобного построения графиков; невизуальные компоненты SaveDialog и OpenDialog (вкладка Dialogs) для стандартного online-выбора файла при выполнении операций чтения-записи массивов данных; набор объектов Button для выполнения предусмотренных действий.

  • 5.    Модуль Header_new.exe (проект Header_new.bpr) демонстрирует применение объекта панель заголовков типа HeaderControl (вкладка Win32) и объектов типа Shape ( вкладка Additional). На рис. 6 приведена копия формы demo-модуля.

Рис. 5. Копия формы demo-модуля My_prim

Реализованы некоторые технические возможности стандартных средств Chart -диаграмм [1–4], например, оперативное определение координат точки, выбранной курсором "мыши" на графике (событие OnClickSeries ), программное оперативное изменение цвета графика или его части.

Сохранение Chart-диаграммы в буфере ция-обработчик Chart1Click. Windows (событие OnClick) выполняет функ- void __fastcall TForm1::Chart1Click(TObject *Sender) { OpenClipboard;

switch ( PageControl1->TabIndex )

{ case 0: Chart1->CopyToClipboardBitmap(); break; } CloseClipboard; }

Размеры рисуемых фигур подгоняются в demo-модуле под размеры разделов заголовков панели HeaderControl или определяются в интерактивном режиме (события OnSectionTrack и OnChange ). Для этого введены массивы int H[3],W[3].

Движение "мыши" по панели заголовка порождает событие OnSectionTrack, которое вызывает функцию

HeaderControl1SectionTrack для корректировки ширины полей как панели заголовка, так и объектов типа Shape, полей массива W[3] и соответствующих объектов

типа LabelEdit (Led_W0,Led_W1,Led_W2).         Рис. 6. Копия формы модуля Header new

void __fastcall TFormMain::HeaderControl1SectionTrack( THeaderControl *HeaderControl, THeaderSection *Section, int Width, TSectionTrackState State)

{ Section->Width = Width;

Shape1->Width = HeaderControl1->Sections->Items[0]->Width;

Shape2->Width = HeaderControl1->Sections->Items[1]->Width;

Shape2->Left = HeaderControl1->Sections->Items[1]->Left;

Shape3->Width = HeaderControl1->Sections->Items[2]->Width;

Shape3->Left = HeaderControl1->Sections->Items[2]->Left;

W[0]=Shape1->Width; W[1]=Shape2->Width; W[2]=Shape3->Width;

Led_W0->Text=IntToStr(W[0]); Led_W1->Text=IntToStr(W[1]);

Led_W2->Text=IntToStr(W[2]); }

Любое интерактивное изменение ширины графических объектов типа Shape (показанной на форме в объектах Led_W0, Led_W1, Led_W2 ) приводит к выполнению

функции Led_W0Change, т.е. к перерисовке Shape -объектов и перенастройке панели заголовков.

void __fastcall TFormMain::Led_W0Change(TObject *Sender)

{ W[0]=StrToInt(Led_W0->Text); W[1]=StrToInt(Led_W1->Text);

W[2]=StrToInt(Led_W2->Text);

Shape1->Width=W[0];

HeaderControl1->Sections->Items[0]->Width=Shape1->Width;

Shape2->Width=W[1]; Shape2->Left=Shape1->Left+W[0];

HeaderControl1->Sections->Items[1]->Width=Shape2->Width;

Shape3->Width=W[2]; Shape3->Left=Shape2->Left+W[1];

HeaderControl1->Sections->Items[2]->Width=Shape3->Width; }

Изменение высоты всех фигур (напри- цией Led_H0Change и приводит к перерисов-мер, Shape1 ) контролируется функцией- ке Shape -объектов.

обработчиком события OnChange, т.е. функ- void __fastcall TFormMain::Led_H0Change(TObject *Sender) { H[0]=StrToInt(Led_H0->Text); Shape1->Height=H[0];

}

Цвет фигур определяется с помощью объектов типа ColorBox (вкладка Additional).

Приведем функцию, определяющую

цвет, например, для фигуры Shape1 и соответствующую корректировку на панели заголовков.

void __fastcall TFormMain::ColorBox1Click(TObject *Sender) { Shape1->Brush->Color=ColorBox1->Selected;

HeaderControl1->Sections->Items[0]->Text=

ColorBox1->Items->Strings[ColorBox1->ItemIndex];

}

Предусмотрено копирование в буфер (функция-кнопка Button1Click ). Возможны варианты.

void __fastcall TFormMain::Button1Click(TObject *Sender)

{ Graphics::TBitmap* Bitmap = new Graphics::TBitmap;

//левый верхний угол -1й вариант

P= Panel1->ClientToScreen(P); x0 = P.x; y0 = P.y;

// 2-й вариант

// x0=Left+Panel1->Left; y0=Top+Panel1->Top;

//3-й вариант

// x0=Left+HeaderControl1->Left; y0=Top+HeaderControl1->Height;

dx=Panel1->Width-Panel1->BevelWidth;

dy=Panel1->Height-Panel1->BevelWidth;

Bitmap->Width =dx; Bitmap->Height=dy;

BitBlt(Bitmap->Canvas->Handle,0,0,dx,dy,GetDC(0),x0,y0,SRCCOPY);

Clipboard()->Assign(Bitmap);

}

Рис. 7 . Копия формы demo-модуля поиска файла

Приведем главную рекурсивную функцию ListFiles_n для поиска файлов и несколько вспомогательных функций, которые могут быть полезны начинающим программистам.

Входные параметры функции List-Files_n:

AnsiString path – строка-директория начального поиска,

AnsiString filename – искомый файл, TStrings* List – для результатов поиска.

Для хранения и визуального обзора найденных результатов поиска на форме предусмотрен объект типа Memo .

void ListFiles_n(AnsiString path,AnsiString filename, TStrings* List)

{ TSearchRec sr;

if ( FindFirst(path+"*.*", faAnyFile, sr ) == 0)

{ do

} else

List->Add(IntToStr(n)+" "+outfile);} }

} while (FindNext(sr) == 0);

FindClose(sr);

}

Application->ProcessMessages();

}

// функция-кнопка Button2Click – поиск файла и запись результатов в область Memo1

void __fastcall TForm1::Button2Click(TObject *Sender)

{ int kk2=10; Memo1->Clear();

GetTimeFormat (NULL,NULL,NULL,"HH':'mm':'ss",lptime,kk2);

strcpy(s,""); strcat(s,"Tbeg="); strcat(s,lptime);

Memo1->Lines->Add (s);

n=0; StatusBar1->Panels->Items[1]->Text="Поиск...";

path=Led_path->Text; filename=Led_file->Text;

ListFiles_n(path,filename,Memo1->Lines);

GetTimeFormat (NULL,NULL,NULL,"HH':'mm':'ss",lptime,kk2);

strcpy(s,"");strcat(s,"Tend="); strcat(s,lptime);

Memo1->Lines->Add (s);

StatusBar1->Panels->Items[1]->Text=

" End of find_file, найдено файлов n= "+IntToStr(n);

}

//-----------------------------------------------

AnsiString Get_Path(AnsiString mes)

{ AnsiString Dir,Root,get_path;

Root = "c:\\";

get_path = SelectDirectory(mes, Root, Dir) ? Dir+"\\" : String("");

return (get_path);

}

AnsiString SlashSep (AnsiString Path, AnsiString FName)

else return(Path+FName);

}

Для запуска найденного файла (или необходимого приложения) используется вспомогательная функция ExecuteFile.

int ExecuteFile

(AnsiString FileName, AnsiString Params, AnsiString DefaultDir, int ShowCmd)

{ char* zFileName;

char* zDir;

char zParams[256];

zFileName=(char *) calloc(256,sizeof(char));

zDir= (char *) calloc(256,sizeof(char));

StrPCopy(zFileName, FileName); //имя файла

StrPCopy(zParams, Params); //передаваемые параметры

StrPCopy(zDir, DefaultDir); //директория int Result= (UINT) ShellExecute(Application->MainForm->Handle,NULL, zFileName,zParams,zDir,ShowCmd);

return (Result);

}

Функция-кнопка Button5Click выполня- (в общем случае это может быть самостоя-ет запуск найденного файла и интерактивно тельное приложение).

выделенного в области объекта типа Memo

void __fastcall TForm1::Button5Click(TObject *Sender)

{ AnsiString F_exe,Params,DefaultDir; int i;

i=Memo1->SelStart; int j= Memo1->SelLength;

if(j==0) {ShowMessage ("Exe-file не выделен"); goto eee;}

F_exe=Memo1->SelText;

StatusBar1->Panels->Items[1]->Text="Выделен для запуска exe-file: "+F_exe;

i= MessageBox

(NULL,"Выполнить запуск exe-file","Exe-file выделен верно?",MB_OKCANCEL);

if (i==IDCANCEL) goto eee;

StatusBar1->Panels->Items[1]->Text="Запуск "+F_exe;

Params=""; DefaultDir= "c:\\"; Application->ProcessMessages();

i=ExecuteFile(F_exe,Params,DefaultDir,SW_SHOW);

StatusBar1->Panels->Items[1]->Text=IntToStr(i)+": End of pgm="+F_exe; eee: }

информации (календарь в виде объекта MonthCalendar , примеры "входа" в Internet , кнопка выхода) и элемент "Exit", выполняющий выход из модуля.

Решение квадратного уравнения выполняется простейшей кнопкой "Решить" типа Button .

Рис. 8. Копия MainForm (c MainMenu) и формы Form2About

В данном demo-модуле реализованы 2 уровня главного меню (0-уровень – это элементы "Demo-модули" и "Exit"). В подменю 1-го уровня для элемента "Demo-модули" включены элементы, которые запускают на

выполнение самостоятельные exe-модули, расположенные в поддиректории "pgm" (здесь это все рассмотренные выше учебные demo-модули).

Для запуска exe-модулей используется функция ExecuteFile (см. п. 6) : int ExecuteFile (AnsiString FileName, AnsiString Params, AnsiString DefaultDir, int ShowCmd).

Приведем функцию N61Click , которая выполняет запуск exe -модуля при выборе из MainMenu элемента " Поиск файла ".

void __fastcall TFormMain::N61Click(TObject *Sender)

{ AnsiString F_exe,Params,DefaultDir;

Params=""; DefaultDir= "c:\\"; Application->ProcessMessages(); int i=ExecuteFile(F_exe,Params,DefaultDir,SW_SHOW);

StatusBar1->SimpleText=F_exe+", Err="+IntToStr(i);

}

Проекты (*.bpr ), реализующие создание рассмотренных demo-программ, можно изучить, а затем вносить в проект и исходные модули (*.cpp ), изменения, исправления, добавлять новые возможности.

Список литературы Учебные демонстрационные программы на C++ в Borland C++ Builder 6

  • Архангельский А.Я. Программирование в С++ Builder 6. М.: Бином, 2003. 1152 с.
  • Архангельский А.Я. С++ Builder 6. Кн. 1. Язык С++: справ. пособие. М.: Бином, 2002. 544 с.
  • Романчик В.С., Люлькин А.Е. Программирование в С++ Builder: пособие для студентов мех.-мат. фак. Минск: БГУ, 2007. 128 с.
  • Шамис В.А. Borland C++ Builder 6. Для профессионалов. СПб.: Питер, 2004. 800 с.
Статья научная