Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция Первое приложение.doc
Скачиваний:
7
Добавлен:
13.09.2019
Размер:
98.82 Кб
Скачать

Первое приложение

Создадим следующее простое приложение. На форме расположим кнопку и при ее нажатии на форме должен появиться красный кружок.

Рассмотрим из каких файлов состоит проект приложения.

Проект приложения состоит из четырёх основных типов файлов:

  • Файлы описания форм — двоичные файлы с расширением DFM, описывающие формы с компонентами. В этих файлах запоминают­ся начальные значения свойств, установленные вами в инспекторе объектов.

  • Файлы программных модулей — текстовые файлы с расширени­ем Н и СРР, содержащие исходные коды форм на языке C++. Н-файлы содержат интерфейсные части форм, а СРР-файлы — части реализации. В СРР-файлах вы записываете код обработчиков со­бытий.

  • Главный программный файл — текстовый файл с расширением СРР, содержащий список всех используемых программных моду­лей, а также стандартную для всех программ на языке C++ фун­кцию WinMain(), обеспечивающую запуск приложения. Главный программный файл создается и контролируется средой C++Builder автоматически.

  • Файл проекта — текстовый файл с расширением .mak в Builder 1 и .bpr для Builder 3, содержа­щий всю необходимую информацию для компилятора, используе­мую при трансляции и сборке программных модулей. Он тоже создается автоматически.

Файлы описания форм

Первая составная часть проекта — это двоичный файл с расширением DFM, описывающий форму. В DFM-файле сохраняются все уста­новки свойств формы и ее компонентов, сделанные вами во время проектиро­вания приложения. Количество DFM-файлов равно количеству используемых в приложении форм. Например, в нашем примере исполь­зуется только одна форма, поэтому и DFM-файл только один — Unit1.dfm.

Иногда в литературе DFM-файл называют графическим образом формы. Это всего лишь сравнение, профессиональный программист должен знать о форме чуточку больше. На самом деле образ формы в DFM-файле не является графи­ческим, он скорее описательный. В DFM-файле попросту хранятся исходные значения для свойств формы и ее компонентов, заданные вами в инспекторе объектов. Хотя DFM-файл — двоичный, у него существует текстовое представ­ление.

DFM-файл нужен только на этапе проектирования. При сборке приложения данные DFM-файла помещаются в область ресурсов выполняемого ЕХЕ-файла. Во время работы приложения они интерпретируются, в результате форма и ее компоненты получают нужные свойства и отображаются на экране так, как вы задали при проектировании.

Файл 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.

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

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

Файл Uint.h

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

#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

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

Директива #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. Помещенные на фор­му компоненты представлены полями формы. У нас на форме шесть компо­нентов, поэтому и полей в описании класса тоже шесть. Имена полей совпа­дают с именами компонентов, заданными в инспекторе объектов.

После полей идут заголовки методов обработки событий. Название каждого такого метода среда 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;

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

Файл 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);

}

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

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

#include <vcl\vcl.h>

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

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

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

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

Этой директивой подключается только один 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++Builder3. Имена главного программного файла и файла проекта всегда совпадают.

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

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

Чтобы увидеть главный программный файл приложения, вычисляющего иде­альный вес, выберите в меню C++Builder команду View | Project Source. В редакторе кода появится новая страница со следующим текстом: