Файл Uint.h

Файл Uint1.dfm

object OneForm: TOneForm

Left = 283

Top = 192

Width = 544

Height = 375

Caption = 'OneForm'

Font.Charset = DEFAULT_CHARSET

Font.Color = clWindowText

Font.Height = -11

Font.Name = 'MS Sans Serif'

Font.Style = []

PixelsPerInch = 96

TextHeight = 13

object Button1: TButton

Left = 208

Top = 160

Width = 75

Height = 25

Caption = 'Draw'

TabOrder = 0

OnClick = Button1Click

end

end

Файлы программных модулей

Каждой проектируемой в визуальной среде форме соответствует свой программный модуль, состоящий из двух файлов: заголовочного файла с расширением Н и программного файла с расширениемСРР. Заголовочный файл содержит программный интерфейс формы на языке C++; он генерируется средой C++Builder автоматически. Программный файл содержит реализацию интерфейса формы на языке C++, в частности методы обработки событий; он создается программистом, т. е. вами.

Количество программных модулей может превышать количество форм. Почему? Потому, что в ряде случаев программные модули могут и не относиться к формам, а содержать вспомогательные подпрограммы и данные. Наша задача об идеальном весе очень простая, поэтому в ней имеется только один программный модуль, относящийся к форме. Он состоит из двух файлов: Unitl.h и Unitl.cpp.

Эти файлы необходимо внимательно изучить.

Обычно в редакторе кода виден лишьСРР-файл, поскольку именно в нем записывается алгоритм решения задачи. Н-файл остается скрыт до тех пор, пока вы не выберете в меню команду (по правой кнопке мыши)Open Sourse/Header File (Ctrl+F6). В результате выполнения этой команды в редакторе кода появится страница следующего содержания:

 

P.S. Форма называется OneForm (а не Form1 по умолчанию)

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

#ifndef Unit1H

#define Unit1H

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

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

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

class TOneForm : public TForm

{

__published: // IDE-managed Components

TButton *Button1;

void __fastcall Button1Click(TObject *Sender);

private: // User declarations

public: // User declarations

__fastcall TOneForm(TComponent* Owner);

};

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

extern PACKAGE TOneForm *OneForm;

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

#endif

 

 

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

 

#ifndef Unit1H

#define Unit1H

#endif

Примечания

Директивы препроцессора начинаются с символа # и обрабатываются во время первой фазы компиляции.

Директива # defineпозволяет связать имя или идентификатор с некоторой лексемой или последовательностью лексем Идентификаторы служащие для представления констант, называют обычно объявленными или символическими константами. Идентификаторы, представляющие операторы называются макросами. Однако термин макросы часто применяют и к символическим константам. Макросы могут воспринимать параметры. Следующий пример показывает макросы.

#include <stdio.h>

/* Простой макрос... */

#define PIE 3.14159

/* Макрос, принимающий аргумент .. */

#define SQR(v) ( (v) * (v ))

#define AREA( r, a ) ( 0.5 * SQR (r)* (a) )

int main( void )

{

double angle = 15;

double radius = 321;

angle = angle * PIE/180; /*преобразует градусы в радианы */

printf ( "Площадь сектора: %f \n", AREA( radius, angle ) );

return 0;

}

Аннулирование макроса #undef

 

 

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

Директива#ifndef (от английского if not defined — если не объявлен) проверяет, не была ли объявлена константа UnitlH. Если такое объявление уже было, компилятор пропускает текст до строки с директивой#endif. В противном случае объявляется константа Unit1H и компилируется весь заголовочный файл.

Перейдем к следующим строкам заголовочного файла Unit1.h. Они содержат директивы включения необходимых заголовочных файлов библиотеки VCL:

 

#include <vcl\Classes.hpp>

#include <vcl\Controls.hpp>

#include <vcl\StdCtrls.hpp>

#include <vcl\Forms.hpp>

 

Встретив директиву#include, компилятор просто подставляет содержимое заданного файла вместо нее и продолжает трансляцию модуля (т. е. фактически осуществляется компиляция всех записанных заголовочных файлов). Среда C++Builder формирует эти строки без вашего участия (в зависимости от используемых компонентов), но, в принципе, список подключенных файлов можно изменять и вручную.

Далее в заголовочном файле объявлен класс формы. По умолчанию он называетсяTform1 и порожден от стандартного классаTForm. Помещенные на форму компоненты представлены полями формы. Если нас на форме шесть компонентов, поэтому и полей в описании класса тоже будет шесть. Имена полей совпадают с именами компонентов, заданными в инспекторе объектов (В поле Name компонента).

После полей идут заголовки методов обработки событий. Название каждого такого метода среда C++Builder формирует автоматически на основании имени компонента и имени генерируемого им события. Например, для кнопкиButton1метод обработки событияOnClick называетсяButtonlClick.

Обратите внимание, что поля, представляющие компоненты формы, и методы обработки событий получают атрибут видимости __published (он принимается по умолчанию для всех наследниковTForm). Благодаря этому вы можете работать с ними на визуальном уровне, например видеть их имена в инспекторе объектов. Поскольку среда C++Builder умеет понимать содержимое секции __published на этапе проектирования, никогда не модифицируйте эту секцию вручную, пользуйтесь визуальными инструментами: палитрой компонентов и инспектором объектов. Запомните:

· Когда вы помещаете на форму компоненты, среда C++Builder добавляет в описание класса соответствующие поля, а когда вы удаляете компоненты с формы, среда C++Builder удаляет их поля из описания класса.

· Когда вы определяете в форме или компонентах обработчики событий, среда C++Builder определяет в классе соответствующие методы, а когда вы удаляете весь код из методов обработки событий, среда C++Builder удаляет и сами методы.

Для вашего удобства в классе формы заранее объявлены пустые секцииprivateиpublic, в которых вы можете размещать любые вспомогательные поля, методы и свойства. Визуальная среда C++Builder их "не видит", поэтому с ними можно работать только на уровне исходного текста в редакторе кода.

Следует обратить внимание на ключевое слово __fastcall в заголовках методов. Оно указывает, что при вызове данного метода параметры передаются через внутренние регистры процессора, а не как обычно — через стековую память. Это увеличивает быстродействие программы, поэтому все стандартные функции из библиотеки VCL объявлены таким образом.

После описания класса объявлена ссылка на объект данного класса, это необходимо для того, чтобы использовать объект класса в других программных модулях.

 

extern PACKAGE TOneForm *OneForm;

 

Н-файл определяет интерфейс программного модуля. Реализация интерфейса выполняется в СРР-файле:

 

Описание: smart_init аргумент #pragma pakage (smart_init) гарантирует, что малогабаритные модули инициализируются в порядке определенном их зависимостями. (Включенное по умолчанию в пакетный исходный файл.) Естественно, Вы должны использовать #pragma pakage для .CPP файлов, которые созданы как пакеты. Это pragma влияет на порядок инициализации этого устройства компиляции. Для устройств, инициализация происходит в следующем порядке: 1. Их ", использует" зависимости, что, если unitA зависит от unitB, unitB должно быть проинициализировано перед unitA. 2. Порядок связи. 3. Приоритетный порядок в пределах устройства.  
Файл Uint1.cpp

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

#include <vcl.h>

#pragma hdrstop

 

#include "Unit1.h"

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

#pragma package(smart_init)

#pragma resource "*.dfm"

TOneForm *OneForm;

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

__fastcall TOneForm::TOneForm(TComponent* Owner)

: TForm(Owner)

{

}

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

 

void __fastcall TOneForm::Button1Click(TObject *Sender)

{

 

/*OneForm->Canvas->Brush->Color=clRed;

OneForm->Canvas->Ellipse(100,100,30,30);*/

Close();}

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

 

Программный файл начинается с включения стандартного заголовочного файла библиотеки VCL, в котором объявлены часто вызываемые подпрограммы, а также классы помещенных на форму компонентов:

 

#include <vcl\vcl.h>

 

Затем следует директива #pragma hdrstop,появление которой связано с тем, что стандартные заголовочные файлы имеют достаточно большие размеры (десятки и сотни тысяч строк), поэтому компилятор затрачивает много времени на трансляцию этих файлов каждый раз, когда вы заново компилируете проект. Для решения этой проблемы компилятор транслирует заголовочные файлы в объектный код только один раз и помещает его в специальный файл с расширением CSM. Имя CSM-файла совпадает с именем проекта. При повторной компиляции проекта C++Builder не транслирует подключаемые файлы, а просто считывает их объектный код из CSM-файла, что существенно (в 3—4 раза) ускоряет процесс получения выполняемого ЕХЕ-файла. При появлении в модуле нового заголовочного файла компилятор транслирует его содержимое и добавляет в CSM-файл. Этот механизм эффективен только для стандартных библиотечных Н-файлов, поскольку их содержимое никогда не изменяется. В остальных случаях он не нужен и останавливается специальной директивой#pragma hdrstop.

 

Рассмотрим следующую строку программы #include "Unitl.h"

Эта директива подключает заголовочный файл Unitl.h к программному файлу.

 

Следующая директива компилятора #pragma resource "*.dfm"служит для подключения файла описания формы.

 

Этой директивой подключается только один DFM-файл, в котором описана форма данного программного модуля. Имя DFM-файла получается путем замены звездочки на имя файла, в котором записана директива.

 

Далее объявлена ссылка на объект формы: TOneForm *OneForm;

OneForm — это переменная, которая содержит указатель на объект классаTOneForm.Конструирование объектаOneForm выполняется в главном программном файле (рассмотрено ниже).

После всех объявлении в программном файле реализуются методы обработки событий. Среда C++Builder создает для них пустые заготовки, а вы начиняете их операторами:

 

void __fastcall TOneForm::Button1Click(TObject *Sender)

{

OneForm->Canvas->Brush->Color=clRed;

OneForm->Canvas->Ellipse(100,100,30,30);

}

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

 

При внимательном изучении исходного текста модуля остается невыясненным один вопрос: чем обеспечивается вызов методаButtonlClickпри нажатии на форме кнопки, ведь эти методы как бы "повисают в воздухе". Все очень просто. Загляните в DFM-файл, точнее, в его текстовое представление, приведенное выше. Кроме установки значений свойств вы найдете установку и обработчика события:

 

object Button1 : Tbutton

OnClick = ButtonlClick

еnd

 

Таким образом обеспечивается привязка методов формы к соответствующим событиям.

 

Главный программный файл и файл проекта

В самом деле, как компилятору узнать, какие конкретно файлы входят в проект? Должно же быть какое-то организующее начало? Да, и оно есть.

В каждом проекте существует главный программный файл с расширением СРР и соответствующий ему файл проекта с расширением *.mak в C++Builder1 и с расширением *.bpr в C++Builder поздних версий. Имена главного программного файла и файла проекта всегда совпадают.( По умолчанию Project1.cpp и Project1.bpr) (Изменить можно Save Project as…)

В главном программном файле перечислены все программные модули и располагается стандартная для программ на языке C++ функцияWinMain, обеспечивающая запуск приложения.

В файле проекта содержатся указания по компиляции и компоновке всех файлов, составляющих проект.

Когда вы по команде File | New Application начинаете разработку нового приложения, среда C++Builder автоматически создает главный программный файл и файл проекта. По мере создания новых форм содержимое этих файлов видоизменяется автоматически.

Чтобы увидеть главный программный файл приложения, используйте менеджер проектов (Project Manager) выбрав Project1.cpp. В редакторе кода появится новая страница со следующим текстом: