Г.Тяпичев «Начальный курс быстрого программирования на СИ++». Глава1.

 

    Глава 1. Основное в C++ Builder

Предисловие. 1

Быстрая разработка приложений. 2

Запускаем C++ Builder 6. 3

Интегратор программы PROMT. 3

Инспектор объектов (Object Inspector) 3

Каталог объектов (Object TreeView) 4

Панель управления. 4

Форма (Form) 4

Панель компонентов (Component Palette) 4

Просмотрщик классов (Class Explorer) 5

Редактор кодов. 5

Библиотека VCL и компоненты.. 5

Компоненты  для отображение текста - Label, Static Text, Panel 6

Окна редактирования Edit и MaskEdit 7

Многострочные окна редактирования Memo и RichEdit 8

Компоненты выбора из списков – ListBox  и  ComboBox. 10

Кнопки, индикаторы, управляющие элементы.. 11

Кнопка с фиксацией SpeedButton. 11

Группы радиокнопок – компоненты RadioGroup, RadioButton и GroupBox. 12

Полоса состояния StatusBar 13

Системные диалоги. 14

Диалоги открытия и сохранения файлов – компоненты OpenDialog, SaveDialog, 16

Главное меню – компонент MainMenu. 18

Контекстное всплывающее меню – компонент PopupMenu. 19

Горячие клавиши – компонент HotKey. 19

Вместо заключения. 19

 

Глава 1. Основное в C++ Builder

Предисловие

В последние годы было опубликовано довольно много книг, озаглавленных как самоучители программирования в среде C++ Builder. Практически в каждом из подобных самоучителей большую часть книги составляет описание собственно среды C++ Builder разных вариантов и очень мало места отводится для примеров практического создания программ. Не подумайте, что я отмечаю этот факт как недостаток. Совсем не так! Каждая из этих книг замечательна уже тем, что несет читателю информацию об удивительной среде быстрого создания программ C++ Builder. Из доступного мне некоторого числа подобных книг считаю необходимым выделить книгу А. Я. Архангельского «Программирование в C++ Builder 5» [1]. Эта книга может служить отличным справочником и учебником для программирования в C++ Builder.  

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

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

 

Быстрая разработка приложений

Создание систем быстрой разработки компьютерных программ (по-английски RAD Rapid Application Development) вызвано требованием нашего времени.

Начало было положено фирмой Microsoft, создавшей среду для возможностей визуального программирования Visual Basic. Эта среда программирования сформировала новый стиль взаимодействия разработчика программы с компьютером, позволяя наглядно конструировать пользовательский интерфейс с помощью мыши, а не обычным для прежних времен путем написания кодов, их последующей неоднократной трансляцией и выполнением программы, после чего только и можно было посмотреть, как же это выглядит на экране.

Visual Basic нашел широкий спрос при создании компьютерных программ самого разного назначения, помог открыть мир программирования для людей, не слишком  искушенных в тонкостях программирования на низком уровне, но он не свободен от многих проблем и не всегда пригоден для создания приложений, которые должны работать с высокой скоростью. Главные из недостатков – низкая производительность разрабатываемых приложений при их выполнении, недостаточная строгость и объектная ориентированность языка.

Созданные фирмой Borland системы Delphi и C++ Builder – это следующий шаг в развитии среды быстрой разработки приложений. Они исправляют многие дефекты, обнаруженные в Visual Basic. Разработчики этих систем создали инструменты, которые на первый взгляд выглядят похожими на среду Visual Basic, хотя в действительности они заметно лучше.

Интегрированная среда разработки в Delphi и C++ Builder выглядит одинаково. Весь пользовательский интерфейс, все библиотеки, все приемы работы с этими системами практически одинаковы. Если быть более точным, то они различаются только в силу разного времени выпуска соответствующих версий. Версии C++ Builder выпускаются на полгода позже версий Delphi с аналогичными номерами. Поэтому каждая версия C++ Builder совершеннее аналогичной версии Delphi, но слабее последующей версии Delphi.

Основное различие Delphi и C++ Builder заключается в языках программирования, которые лежат в их основе. Delphi базируется на языке Object Pascal, а C++ Builder базируется на языке C++. Эти языки на сегодняшний день являются самыми мощными, при этом многие авторы отдают первенство языку программирования C++. Исторически сложилось так, что эти два языка программирования  сначала существенно различались по своим возможностям, но со временем все более сближаются. Сейчас оба они представляют собой прекрасные инструменты объектно-ориентированного программирования, различающиеся, в основном, синтаксисом. Но C++ все-таки богаче и опережает аналогичные версии Object Pascal. С этой точки зрения он предпочтительнее. Правда, эти преимущества C++ перед Object Pascal проявляются только в достаточно сложных приложениях.

Фирма Borland позаботилась о том, чтобы приложения, разработанные на C++ Builder и на Delphi, можно было достаточно просто конвертировать друг в друга. Таким образом, в одной из этих систем вы можете использовать свои наработки, сделанные в другой системе.  

Перечисленные выше системы для быстрой разработки компьютерных программ служат только для операционной системы Windows. Существуют аналогичные системы и для прогрессирующей операционной системы Linux. Фирмой Borland для Linux создана среда программирования Kylix, которая по способам разработки программ полностью соответствует C++ Builder. В Linux используется также среда программирования для KDE, использующая QT – компоненты. 

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

Запускаем C++ Builder 6

После запуска программы на экране моего компьютера появляется картинка, которая состоит из нескольких отдельных окон. На экране вашего компьютера эта картинка может быть несколько иной. Все зависит от версии программы и её настройки. Все открывшиеся на экране компьютера окна составляют вместе интегрированную среду разработки (IDE) в её начальном состоянии.  На рис. 1.1 представлена копия картинки с экрана моего компьютера.

Рис.1.1. Составные части интегрированной среды разработки

В нижней части рисунка находятся цифры, от которых идут указатели к основным окнам, расположенным на экране в начальный момент. Привожу перечень этих окон.

1.        Интегратор программы машинного перевода PROMT.

2.        Окно инспектора объектов (Object Inspector).

3.        Окно древовидного каталога объектов (Object TreeView).

4.        Окно панели управления C++ Builder.

5.        Окно формы (Form1).

6.        Окно панели компонентов (Component Palette).

7.        Окно просмотрщика (исследователя) классов (Class Explorer).

8.        Окно редактора кодов.

Далее рассмотрим назначение каждого из перечисленных окон.

Интегратор программы PROMT

Этот интегратор не имеет к IDE C++ Builder 6 никакого отношения. Программа PROMT используется мною для быстрого перевода пояснительных текстов системы C++ Builder 6 и комментариев, встретившихся в программах зарубежных авторов.

Большинство программ фирмы Borland позволяют легко и быстро получить помощь – подсказку по любому оператору, типовой функции или по выявленной при компиляции ошибке. Для этого достаточно установить курсор на нужный оператор и нажать сочетание клавиш <Ctrl>+<F1>. Тут же появляется подсказка, разумеется, на английском языке. Теперь нужно выделить мышкой требующий перевода текст подсказки и нажать сочетание клавиш <Ctrl>+<Insert>. Этими действиями мы выделенный текст копируем в буфер обмена (clipboard). После этого нужно  выполнить перевод, для чего следует установить курсор на вторую от верха пиктограмму интегратора и нажать левую клавишу мышки. Качество машинного перевода, выполненного программой PROMT, мягко говоря, не выдерживает никакой критики, но лучшего варианта я пока не знаю.

  

Инспектор объектов (Object Inspector)

Инспектор объектов – очень важная часть среды разработки. Он предназначен для задания свойств (Properties) объектов и определения их реакции на различные события (Events). Понятие «объект» имеет очень широкий смысл, но в данном случае под этим термином подразумевается любой из компонентов, имеющихся в составе данной версии C++ Builder.

Свойства объектов

Свойство объекта – это одна из его характеристик, такая, как, например, ширина  кнопки, название окна, наличие полос прокрутки у списка, цвет и стиль  шрифта, имя файла для рисунка и т.д. Как только мы выбираем и устанавливаем на форму какой-то компонент (объект), то программа автоматически в инспекторе объектов устанавливает доступные этому  компоненту (объекту) свойства и события.

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

Инспектор объектов позволяет быстро и удобно менять любые свойства текущего (выделенного на форме) объекта. При этом вносимые изменения немедленно сказываются на внешнем виде этого объекта. Например, если мы с помощью Инспектора изменим текст надписи на кнопке, это изменение мгновенно отобразится на самой кнопке в проектируемой форме.

События

Для каждого объекта имеется специальный перечень доступных этому объекту событий. 

Событие позволяет программе реагировать на любые действия пользователя так, как это задано программистом. К событиям относятся щелчок мышью на кнопке, выбор пункта меню, изменение состояния переключателя, и иные происшествия как внутри самой программы, так и в операционной системе Windows.

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

В окне Инспектора объектов имеются две вкладки – вкладка свойств выбранного объекта (Properties) и вкладка событий (Events), на которые этот объект может реагировать. Каждая из вкладок содержит панель, состоящую из двух колонок. В первой указываются названия свойств (их менять нельзя), во второй – текущие значения соответствующих свойств. Эти значения должны отвечать определенным ограничениям C++ Builder.

Некоторые свойства меняются простым вводом значения в соответствующей строке. Так, например, мы можем изменить толщину рамки окна в свойстве Border Width, введя вместо 0 число 5.

Некоторые свойства могут иметь вложенную структуру, как, например, свойство Border Icons в левой колонке, и Инспектор объектов откроет доступ к скрытым свойствам. Таким же способом можно свернуть ранее раскрытое свойство Border Width – снова дважды щелкнуть на его названии левой кнопкой мыши.

Каталог объектов (Object TreeView)

В окно каталога объектов программой автоматически заносятся все выбранные нами и установленные компоненты (объекты). Выделенный на форме объект тут же оказывается выбранным и в окне каталога объектов, и наоборот. Значительно улучшает удобство использования интегрированной среды разработки при выполнении сложных программ.

 Панель управления

В верхней части рис. 1.1 располагается главное меню, которое служит основным органом управления средой программирования C++ Builder 6. Чуть ниже меню, в левой стороне находится панель быстрого управления. Это специальная кнопочная панель, которая обеспечивает быстрый доступ к таким наиболее часто используемым командам меню, как Run (Старт), Step Through (Пошаговая отладка), View Unit (Просмотр модуля), View Form (Просмотр формы) и Add to Project (Добавить в проект). Эту панель разработчик может настроить по своему желанию, добавляя в нее наиболее нужные команды и удаляя те, которые используются не очень часто.

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

q      Standard (Стандартная панель)

q      View (Панель просмотра)

q      Debug (Панель отладки)

q      Custom (Панель настройки)

q      Component Palette (Панель компонентов).

 

Форма (Form)

Форма – это окно, которое в большинстве случаев является пользовательским интерфейсом создаваемого приложения. Пустая форма создается автоматически при создании нового приложения с помощью C++Builder. Для создания пользовательского интерфейса в форму нужно просто добавить соответствующие визуальные и невизуальные компоненты. При этом невизуальные компоненты во время создания приложения  будут иметь вид пиктограммы компонента, а во время запуска будут скрыты.

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

 

Панель компонентов (Component Palette)

Панель (или палитра) компонентов располагается сразу же под линейкой главного меню справа и содержит все типы компонентов библиотеки VCL. Эти компоненты сгруппированы на вкладках по своеобразным страницам, названия которых располагаются над ними. Для выбора компонента следует установить на этот компонент курсор и нажать левую клавишу мышки. Затем следует переместить курсор в нужное место на форме и снова нажать левую клавишу мышки. Для установки на форму некоторых компонентов, имеющих геометрические размеры, следует, не отпуская нажатую клавишу, переместить курсор в следующую конечную точку границы компонента и отпустить нажатую клавишу. При этом в окне инспектора объектов появятся все доступные данному компоненту свойства.

 

Просмотрщик классов (Class Explorer)

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

Редактор кодов

На рис. 1.1 редактор кодов как бы «выглядывает» внизу из-под окна формы. Для активизации редактора следует установить курсор на видимый участок редактора и нажать левую клавишу мышки. При этом окно редактора кодов совместно с просмотрщиком классов переместится на первый план, а окно формы окажется скрытым, но верхняя часть окна формы останется видимой. Этим можно будет воспользоваться для быстрой активизации окна формы.

Активизировать любое из этих окон можно также с использованием главного меню.

Рис. 1.2  Интегрированная среда с окном редактора кодов

На рис. 1.2 показано активизированное окно редактора кодов, но малый горизонтальный размер окна очень не удобен для работы, поэтому я обычно убираю Class Explorer, чтобы увеличить размер окна редактора кодов. Такой вариант показан на рис. 1.3.     

Рис. 1.3  Редактор кодов в рабочем состоянии

Иногда бывает необходимо длительное время работать только с редактором кодов. В таком случае окно редактора можно развернуть до максимального размера. Этот вариант показан на рис. 1.4.

Рис. 1.4  Окно редактора кодов максимального размера

 Большую часть времени при программировании приходится работать именно с редактором кодов, поэтому я посчитал нужным более подробно описать подготовку редактора к работе.

 

Библиотека VCL и компоненты

Библиотека визуальных компонентов – VCL—библиотека (Visual Component Library) – является хранилищем  компонентов, используемых для создания приложений с помощью C++Builder. Компонентом называется объект, используемый для создания программы. Это может быть какая-то кнопка, комбинированный список или рисунок. Каждый из компонентов выбирается с помощью щелчка левой кнопкой мыши и перемещается в рабочую область. Компоненты VCL-библиотеки представляют собой код, который скомпилирован для выполнения определенных операций, что избавляет разработчика от необходимости всякий раз создавать его заново.

Кроме того, разработчик может добавлять и создавать собственные компоненты. Таким образом, компоненты VCL-библиотеки избавляют разработчика от выполнения трудоемких и рутинных операций. Они располагаются в панели компонентов Component Palette и некоторые из них более подробно описаны ниже в этой главе.

Все компоненты обладают свойствами, которыми можно управлять с помощью кода  C++Builder. Свойства компонента определяют способ его работы, внешний вид, набор функциональных возможностей и т.д. Их можно модифицировать с помощью вкладки свойств Properties в окне Object Inspector. Параметры свойств можно изменять с помощью кода, но без достаточного опыта работы C++Builder и VCL-библиотекой это делать не рекомендуется.

Окно Object Inspector также содержит вкладку событий Events, в которой можно создавать события для определения способа взаимодействия пользователя с этим компонентом. Кроме того, эти события могут выполнять другие определенные разработчиком действия.

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

Компоненты  для отображение текста - Label, Static Text, Panel

 Для отображения различных надписей на форме используются в основном компоненты Label, Static Text и Panel. Первые два из этих компонентов  специально предназначены для отображения текстов и называются «метки». Основное назначение панели Panel состоит в компоновке компонентов в окне формы. Однако, панель можно использовать и для вывода текстов.

Примеры вывода текста в метки приведены практически в каждой программе следующей главы.

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

Label1->Caption = «Это пример вывода нового текста.»;

Свойство Caption имеет тип строки AnsiString. При присваивании этому типу числовой информации происходит ее автоматическое преобразование в строку. Поэтому вы можете непосредственно осуществлять подобные присваивания. Например, оператор

Label1 - > Caption = 6.8;

На рис. 1.5 показаны некоторые из вариантов оформления текста компонентом Label.

Рис. 1.5. Варианты оформления текстов в Label

Приведет к появлению в метке надписи «6,8». Но если вы хотите занести в метку  смешанную информацию, в которой будут содержаться строковые символы и  числовые переменные величины, то следует числовые величины преобразовать в строковые символы посредством функций FloatToStr и IntToStr, переводящими соответственно числа с плавающей запятой и целые числа в строку символов. Для формирования текста, состоящего из нескольких фрагментов, можно использовать операцию «+», которая для строк означает их склеивание (конкатенацию). Например, если в программе имеется целая переменная var, отображающая число сотрудников некоторой организации, то вывести в метку Label1 информацию об этом можно оператором:

Label1 -> Caption = «Число сотрудников: » + IntToStr(var)+ «человек.»;

Во всех компонентах цвет фона определяется свойством Color, а цвет надписи – подсвойством Color свойства Font. Например, в большинстве меток задается цвет фона clWhite – белый. Если цвет специально не задавать, то цвет фона обычно сливается с цветом контейнера, содержащего метку, так что фон просто не заметен.

Для метки Label цвет и шрифт – единственно доступные элементы оформления надписи. Компоненты StaticText и Panel имеют кроме того свойство BorderStyle, определяющее рамку текста – бордюр. При стиле sbsNone метка StaicText по виду не отличается от метки Label. Вероятно, если уж использовать бордюр, то наиболее приятным будет стиль sbsSunken. Некоторые из вариантов оформления текста в метках   StaticText представлены на рис. 1.6.

Рис. 1.6. Варианты оформления текста в StaticText

Компонент Panel кроме свойства BorderStyle имеет еще свойства BevelInner, BevelOuter, BevelWidth, BorderWidth, которые предоставляют богатые возможности оформления надписи. Таким образом, с точки зрения оформления выводимого текста максимальные возможности дает Panel и минимальные – Label. На рис. 1.7 представлены некоторые из вариантов оформления текста в Panel.

Рис. 1.7. Некоторые из вариантов оформления текста в Panel

Размер меток label и StaticText определяется также свойством. AutoSize. Если это свойство установлено в true, то вертикальный и горизонтальный размеры компонента определяются размером надписи. Если же AutoSize равно false, то выравнивание текста внутри компонента определяется свойством Alignment, которое позволяет выравнивать текст по левому краю, правому краю или центру клиентской области метки. В панели Panel также имеется свойство AutoSize, но оно не относится к размерам подписи Caption. Однако свойство выравнивания Alignment работает и для панели.

В метке Label имеется свойство WordWrap – доступность переноса слов длинной надписи, превышающей длину компонента, на новую строчку. Чтобы такой перенос мог осуществляться, надо установить свойство WordWrap в true, свойство AutoSize в false (чтобы размер компонента не определялся размером надписи) и сделать высоту компонента такой, чтобы в нем могло поместиться несколько строк. Если WordWrap не установлено в true при AutoSize равном false, то длинный текст, не помещающийся в рамке метки, просто обрезается.

В метке StaticText перенос длинного текста осуществляется автоматически, если значение AutoSize установлено в false и размер компонента достаточен для размещения нескольких строк. Для того, чтобы в StaticText осуществлялся перенос при изменении пользователем размеров окна, надо осуществлять описанную выше перерисовку компонента методом Repaint в обработчике события формы OnResize.

В панели размещение надписи в нескольких строках невозможно.

Можно отметить еще одно свойство меток Label и StaticText, превращающее их в некоторое подобие управляющих элементов. Это свойство FocusControl – фокусируемый компонент. Если в свойстве метки Caption поместить перед одним из символов символ амперсант «&», то символ, перед которым поставлен амперсант, отображается в надписи метки подчеркнутым (сам амперсант вообще не отображается). Если после этого обратиться к свойству метки FocusControl, то из выпадающего списка можно выбрать элемент, на который будет переключаться фокус, если пользователь нажмет клавиши  ускоренного доступа: клавишу <Alt> + <подчеркнутый символ>. Подобные клавиши ускоренного доступа предусмотрены в управляющих элементах: разделах меню и кнопках. Благодаря свойству FocusControl метки могут обеспечить клавишами ускоренного доступа иные элементы, например, окна редактирования  в режиме ReadOnly.

Окна редактирования Edit и MaskEdit

Примеры применения окон редактирования можно смотреть в программах, помещенных в следующей главе.

Внешнее оформление окон редактирования определяется свойством BorderStyle. В компонентах Edit и MaskEdit вводимый и выводимый текст содержится в свойстве Text и имеет тип AnsiString. Это свойство можно устанавливать в процессе проектирования или задавать программно. Выравнивание текста, как это имело место в метках и панелях, невозможно. Перенос строк тоже невозможен. Текст, не помещающийся по длине в окно, просто сдвигается и пользователь может перемещаться по нему с помощью курсора. Свойство AutoSize в окнах редактирования имеет смысл, отличный от смысла аналогичного свойства меток: автоматически подстраивается под размер текста только высота, но не ширина окна.

Окна редактирования снабжены многими функциями, свойственными большинству редакторов. Например, в них предусмотрены типичные комбинации «горячих» клавиш: <Ctrl> + <C> – копирование выделенного текста в буфер Clipboard (команда Copy), <Ctrl> + <X> – вырезание выделенного текста в буфер Clipboard (команда Cut), <Ctrl> + <V> – отмена последней команды редактирования.

 Свойство AutoSelect определяет, будет ли автоматически выделяться весь текст при передаче фокуса в окно редактирования. Его имеет смысл задавать равным true в случаях, когда при переключении в данное окно пользователь будет вероятнее всего заменять текущий текст, а не исправлять его. Имеются также свойства только времени выполнения SelLength, SelStart, SelText, определяющие соответственно длину выделенного текста, позицию перед первым символом выделенного текста и сам выделенный текст. Например, если в окне имеется текст «выделение текста» и в нем пользователь выделил слово «текста», то SelLength = 6, SelStart = 10 и SelText = «текста». Если выделенного текста нет, то свойство SelStart просто определяет текущее положение курсора.

Окна редактирования можно использовать и просто как компоненты отображения текста. Для этого надо установить в true их свойство ReadOnly и целесообразно установить AutoSelect в false. В этом случае пользователь не сможет изменять отображаемый текст и окно редактирования становится подобным меткам. Но имеются и определенные отличия. Во-первых, окна редактирования оформлены несколько иначе. А главное – окна редактирования могут вмещать текст, превышающий их видимую длину. В этом случае пользователь может прокручивать текст, перемещая курсор в окне. Такими особенностями не обладает ни одна метка. Некоторые из вариантов оформления окна Edit представлены на рис. 1.8.

Рис. 1.8. Примеры оформления окна Edit

Свойство Text окон редактирования имеет тип строки AnsiString. При вводе из окна числовой информации надо использовать функции StrToFloat – преобразование строки в значение с плавающей запятой, и StrToInt – преобразование строки в целое значение. Если вводимый текст не соответствует числу (например, содержит недопустимые символы), то функции преобразования генерируют исключение EconverError. Поэтому в программе необходимо предусмотреть обработку этого исключения. Например:

int var;  // объявление переменной var

try

(

var = StrToInt(Editl ->Text);

)

catch  (EconvertError&)

(

ShowMessage («Вы ввели ошибочное число; повторите ввод»);

)

Этот код обеспечивает сообщение пользователю об ошибке ввода и предотвращает ошибочные вычисления. Впрочем, окно Edit можно спроектировать так, что пользователь просто не сможет ввести в него неправильные символы. Свойство MaxLength определяет максимальную длину вводимого текста. Если MaxLength = 0, то длина текста не ограничена. В противном случае значение MaxLength указывает максимальное число символов, которое может ввести пользователь.

Свойство Modified, доступное только во время выполнения, показывает, проводилось ли редактирование текста в окне. Если вы хотите использовать это свойство, то в момент начала работы пользователя с текстом Modified надо установить в false. Тогда при последующем обращении к этому свойству можно по его значению (true или false) установить, было или не было произведено редактирование.

Свойство PasswordChar позволяет превращать окно редактирования в окно ввода пароля. По умолчанию значение PasswordChar равно «#0» -- нулевому символу. В этом случае это обычное окно редактирования. Но если в свойстве указать иной символ (например, символ звездочки «*»), то при вводе пользователем текста в окне будут появляться именно эти символы, а не те, которые вводит пользователь. Тем самым обеспечивается секретность ввода пароля.

Компонент MaskEdit отличается от Edit тем, что в нем можно задать строку маски в свойстве EditMask. Это позволяет обеспечить синтаксически безошибочный ввод пользователем таких данных, как номера телефонов, паспортные данные, адреса, даты, время и т. п.  Маска состоит из трех разделов, между которыми ставится точка с запятой «. В первом разделе – шаблоне записывается специальным образом символы, которые можно вводить в каждой позиции, и символы, добавляемые самой маской; во втором разделе записывается 1 или 0 в зависимости от того, надо или нет, чтобы символы, добавляемые маской, включались в свойство Text компонента; в третьем разделе указывается символ, используемый для обозначения позиций, в которых еще не осуществлен ввод. Прочитать результат ввода можно или в свойстве Text , которое в зависимости от вида второго раздела маски включает или не включает в себя символы маски, или в свойстве EditText, содержащем введенный текст вместе с символами маски. Некоторые примеры оформления окна MaskEdit представлены на рис. 1.8.

Вводить маску можно непосредственно в свойство EditMask. Но удобнее пользоваться специальным редактором масок Mask Editor, вызываемым при нажатии кнопки с многоточием в строке свойства EditMask в Инспекторе Объектов. В редакторе масок окно sample Masks содержит наименования стандартных масок и примеры ввода с их помощью. В окно input Mask надо ввести маску. Если вы выбираете одну из стандартных масок, то окно input Mask автоматически заполняется и вы можете, если хотите, отредактировать эту маску. На рис. 1.9 представлено окно Mask Editor, в котором можно выполнять различные действия по редактированию масок.

Рис. 1.9. Окно редактора Mask Editor

Окно Character for Blanks определяет символ, используемый для обозначения позиций, в которых еще не осуществлен ввод (третий раздел маски). Индикатор Save Literal Characters определяет второй раздел маски: установлен, если второй раздел равен 1, и не установлен, если второй раздел равен 0.

Рассмотрим  пример. Если с помощью EditMask надо ввести, например, целое число без знака, состоящее не более, чем из двух цифр, можно задать маску «99;0;». Если число обязательно должно быть двузначным, то маска должна иметь вид «00;0;».

Многострочные окна редактирования Memo и RichEdit

Компоненты Memo и RichEdit  являются окнами редактирования многострочного текста. Они так же, как и окно Edit, снабжены многими функциями, свойственными большинству редакторов. В них предусмотрены типичные комбинации «горячих» клавиш: <Ctrl> + <C> – копирование выделенного текста в буфер обмена Clipboard (команда Copy), <Ctrl> + <X> – вырезание выделенного текста в буфер Clipboard (команда Cut), <Ctrl> + <V> – вставка текста из буфера Clipboard в позицию курсора (команда Paste), <Ctrl> + <Z> – отмена последней команды редактирования.

 В компоненте Memo формат (шрифт, его атрибуты, выравнивание) одинаков для всего текста и определяется свойством Font. При последующем чтении этого файла в Memo формат будет определяться текущим состоянием свойства Font компонента Memo, а не тем, в каком формате ранее вводился текст.

Компонент RichEdit работает с текстом в обогащенном формате RTF. При желании вы изменить атрибуты вновь вводимого фрагмента текста, для этого следует задать свойство SelAttributes. Это свойство типа TextAttributes, которое в свою очередь имеет подсвойства: Color (цвет), Name (имя шрифта), Size (размер), Style (стиль) и ряд других. Например, введите на форму компонент RichEdit, диалог выбора шрифта FontDialog со страницы библиотеки  Dialogs, кнопку Button, которая позволит пользователю менять атрибуты текста и еще одну кнопку Button для завершения работы программы. В обработчик щелчка кнопки введите текст:

if(FontDialog ->Execute() )

RichEditl -> SelAttributes -> Assign(FontDialog1) -> Font);

RichEdit1 -> SetFocus();

Запустите приложение и увидите (рис. 1_10), что вы можете менять атрибуты текста, выполняя отдельные фрагменты различными шрифтами, размерами, цветами, стилями.

Рис. 1.10. Делаем выбор шрифта

Устанавливаемые атрибуты влияют на выделенный текст (рис. 1.11) или, если ничего не выделено, то на атрибуты нового текста, вводимого начиная с текущей позиции курсора (позиция курсора определяется свойством SelStart).

Рис. 1.11. Измененный текст

В компоненте имеется также свойство DefAttributes, содержащее атрибуты по умолчанию. Эти атрибуты действуют до того момента, когда изменяются атрибуты в свойстве SelAttributes. Но значения атрибутов в DefAttributes сохраняются и в любой момент эти значения могут быть методом Assign присвоены атрибутам свойства SelAttributes, чтобы вернуться к прежнему стилю.

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

Свойства TabCount и Tab имеют смысл при вводе текста только при значении свойства компонента WantTabs = true. Это свойство разрешает пользователю вводить в текст символ табуляции. Если WantTabs = false, то нажатие пользователем клавиши табуляции просто переключит фокус на очередной компонент и символ табуляции в текст не введется.

Это были основные отличия Memo и RichEdit. Теперь остановимся на общих свойствах этих окон редактирования.

Свойства Alignment и WordWrap имеют тот же смысл, что, например, в метках, и определяют выравнивание текста и допустимость переноса длинных строк. Установка свойства ReadOnly в true задает текст только для чтения. Свойство MaxLength определяет максимальную длину вводимого текста. Если MaxLength = 0, то длина текста не ограничена. Свойства WantReturns и WantTab определяют допустимость ввода пользователем в текст символов перевода строки и табуляции.

Свойство ScrollBars определяет наличие полос прокрутки текста в окне. По умолчанию ScrollBars = ssNone, что означает их отсутствие. Пользователь может в этом случае перемещаться по тексту только с помощью курсора. Можно задать свойству ScrollBars значения ssHorizontal, ssVertikal или ssBodh, что будет соответственно означать наличие горизонтальной, вертикальной или обеих полос прокрутки.

Основное свойство окон Memo и RichEditLines, содержащее текст окна в виде списка строк и имеющее тип TStrings. Начальное значение текста можно установить в процессе проектирования, нажав кнопку с многоточием около свойства Lines в окне Инспектора Объектов. Перед вами откроется окно редактирования списков строк. Вы можете редактировать или вводить текст непосредственно в этом окне, или нажать кнопку CodeEditor и работать в обычном окне Редактора Кода. В этом случае, завершив работу с текстом, выберите из контекстного меню, всплывающего при щелчке правой кнопкой мыши, команду Close Page и ответьте утвердительно на вопрос, хотите ли вы сохранить текст в соответствующем свойстве окна редактирования.

Во время выполнения приложения вы можете заносить текст в окно редактирования с помощью методов свойства Lines типа Tstrings. Весь текст, представленный одной строкой типа String, внутри которой используются разделители типа символов возврата каретки и перевода строки, содержится в свойстве Text.

Доступ к отдельной строке текста вы можете получить с помощью свойства AnsiString Strings[int Index]. Индексы, как и везде в C++ Builder, начинаются с 0. Так что Memo1->Lines->Strings[0] – это текст первой строки. Учтите, что если окно редактирования изменяется в размерах при работе с приложением и свойство WordWrap = true, то индексы строк будут изменяться при переносах строк, так что в этих случаях индекс строки будет меняться.

Свойство только для чтения Count указывает число строк в тексте.

Для очистки текста в окне надо выполнить процедуру Clear. Этот метод относится к самому окну, а не к его свойству Lines.

Для занесения новой строки в конец текста окна редактирования можно воспользоваться методами Add или Append свойства Lines. Для загрузки текста из файла применяется метод LoadFromFile. Сохранение текста в файле осуществляется методом SaveToFile.

Свойство SelStart  компонентов Memo и RichEdit указывает позицию курсора в тексте или начало выделенного пользователем текста. Свойство CaretPos указывает на структуру, поле X которой содержит индекс символа в строке, перед которым расположен курсор, а поле Y – индекс строки, в которой находится курсор. Таким образом, учитывая, что индексы начинаются с 0, значения RichEdit–>CaretPos.y + 1 и RichEdit1–>CaretPos.x + 1 определяют соответственно номер строки и символа в ней, перед которым расположен курсор.

Компоненты выбора из списков – ListBox  и  ComboBox

Примеры компонентов ListBox и ComboBox, обеспечивающих выбор из списка, можно найти в последующих главах книги.

Компоненты ListBox и ComboBox отображают списки строк. Использование этих компонентов позволяет обеспечить безошибочный ввод информации пользователем в тех случаях, когда он должен выбрать ответ из конечного множества альтернатив. Компоненты списков отличаются друг от друга прежде всего тем, что ListBox только отображает данные и позволяет пользователю выбрать из них то, что ему надо, а ComboBox позволяет также редактировать данные. Кроме того различается форма отображения списков. ListBox отображает список в раскрытом виде и автоматически добавляет в список полосы прокрутки, если все строки не помещаются в окне компонента. ComboBox позволяет отображать список как в развернутом виде, так и в виде выпадающего списка, что обычно удобнее, так как экономит площадь окна приложения. О том, как выглядят эти компоненты на форме, показано на рис. 1.11.

Рис. 1.12 Компоненты на форме

Основное свойство обоих компонентов, содержащее список, –Items, имеющее рассмотренный ранее тип Tstrings. Заполнить его во время проектирования можно, нажав кнопку с многоточием около этого свойства в окне Инспектора Объектов. При этом открывается окно редактирования. Каждая записанная в нем строка будет соответствовать строке списка.

Если MultiSelect = false (значение по умолчанию), то пользователь может выбрать только один элемент списка. В этом случае можно узнать индекс выбранной строки из свойства ItemIndex, доступного только во время выполнения. Если ни одна строка не выбрана, то ItemIndex = -1. Это означает, что ни один элемент списка не выбран. Если вы хотите задать этому свойству какое-то другое значение, т. е. установить выбор по умолчанию, который будет показан в момент начала работы приложения, то сделать это можно, например, в обработчике события OnCreate формы.

Если допускается множественный выбор (MultiSelect = true), то значение ItemIndex соответствует тому элементу списка, который находится в фокусе. При множественном выборе проверить, выбран ли данный элемент, можно проверив свойство bool Selected[int Index].

На способ множественного выбора при MultiSelect = true влияет свойство ExtendedSelect. Если ExtendedSelect = true, то пользователь может выделить интервал элементов, выделив один из них, затем нажав клавишу <Sift> и переведя курсор к другому элементу. Выделить не прилегающие друг к другу элементы пользователь может, если будет удерживать во время выбора нажатой клавишу <Ctrl>. Если же ExtendedSelecr = false, то клавиши <Shift> и <Ctrl> при выборе не работают.

Свойство Columns определяет число столбцов, в которых будет отображаться список, если он не помещается целиком в окне компонента ListBox.

 Свойство Sorted позволяет упорядочить список по алфавиту. При Sorted = true новые строки в список добавляются не в конец, а по алфавиту.

Свойство Style, установленное в IbStandart (значение по умолчанию) соответствует списку строк. Другие значения Style позволяют отображать в списке не только текст, но и изображения.

 На рис. 1.12 показаны два рассматриваемых компонента в работающем приложении.

Рис. 1.13. Компоненты на окне работающего приложения.

 Рассмотрим теперь компонент ComboBox.

Выбор пользователя или введенный им текст можно определить по значению свойства Text. Если же надо определить индекс выбранного пользователя элемента списка, то можно воспользоваться обсуждавшимся в компоненте ListBox свойством ItemIndex, доступным только во время выполнения. Все сказанное ранее об ItemIndex и о задании его значения по усолчанию справедливо и для компонента ComboBox. Причем для ComboBox задание начального значения ItemIndex еще актуальнее, чем для ListBox. Если начальное значение не задано, то в момент запуска приложения окно редактирования списка будет отображать на один из элементов списка, а значение свойства Text. Значит надо или вводить в приложение оператор, задающий в первый момент значение ItemIndex, или вводить во время проектирования в свойство Text какое-то приглашение к дальнейшим действием. Иначе пользователь будет в недоумении, что надо делать с этим списком.

Если в окне проводилось редактирование данных, то IntemIndex = –1. По этому признаку можно определить, что редактирование проводилось.

Свойство MaxLength определяет максимальное число символов, которые пользователь может ввести в окно редактирования. Если MaxLength = 0, то число вводимых символов не ограничено.

Как и в компоненте ListBox, свойство Sorted позволяет упорядочить список по алфавиту. При Sorted =  true новые строки в список добавляются не в конец, а по алфавиту.

Кнопки, индикаторы, управляющие элементы

Управляющие кнопки Button и BitBtn

Примеры кнопок Button, BitBtn и рассмотренной в следующем разделе кнопки SpeedButton встречаются очень часто во всех главах книги, поэтому делать для них специальный рисунок, по моему мнению, не стоит. Простейшей и, пожалуй, наиболее часто используемой кнопкой является кнопка Button, расположенная на странице библиотеки Standard. Реже используется кнопка BitBtn, отличающаяся, прежде всего, возможностью отобразить на ее поверхности изображение. Большинство свойств, методов и событий у этих видов кнопок одинаковы.

Основное с точки зрения внешнего вида свойство кнопки – Caption (надпись). В надписях кнопок можно предусматривать использование клавиш ускоренного доступа, выделяя для этого один из символов надписи. Перед символом, который должен соответствовать клавише ускоренного доступа, ставится символ амперсанта «&». Этот символ не появляется в надписи, а следующий за ним символ оказывается подчеркнутым. Тогда пользователь может вместо щелчка на кнопке нажать в любой момент клавишу <Alt> совместно с клавишей выделенного символа.

Например, если в вашем приложении имеется кнопка выполнения какой-то операции, вы можете задать ее свойство Caption равным «&Выполнить». На кнопке эта надпись будет иметь вид «Выполнить». И если пользователь нажмет клавиши <Alt>+<B>, то это будет эквивалентно щелчку на кнопке.

Основное событие любой кнопки – OnClick, возникающее при щелчке на ней. Именно в обработчике этого события записываются операторы, которые должны выполняться при щелчке пользователя на кнопке. Помимо этого есть еще ряд событий, связанных с различными манипуляциями клавишами и кнопками мыши. Свойство Cancel, если установить его в true, определяет, что нажатие пользователем клавиши <Esc> будет эквивалентно щелчку на данной кнопке. Это свойство целесообразно задавать равным true для кнопок Отменить в различных диалоговых окнах, чтобы можно было выйти из диалога, нажав на эту кнопку или нажав клавишу <Esc>.

Свойство Defult, если его установить в true, определяет, что нажатие пользователем клавиши ввода <Enter> будет эквивалентно нажатию на данную кнопку, даже если данная кнопка в этот момент не находится в фокусе. Правда, это сработает, если в фокусе находится какой-то оконный компонент. Если же в момент нажатия на клавишу <Enter> в фокусе находится другая кнопка, то все-таки сработает именно кнопка в фокусе.

Еще одно свойство – ModalResult используется в модальных формах. В обычных приложениях значение этого свойства должно быть равно mrNone.

Из методов, присущих кнопкам, имеет смысл отметить один – Click. Выполнение этого метода эквивалентно щелчку на кнопке, т. е. вызывает событие кнопки OnClick. Этим можно воспользоваться, чтобы продублировать какими-то другими действиями пользователя щелчок на кнопке. Пусть, например, вы хотите, чтобы при нажатии пользователем клавиши с символом «С» или «с» в любой момент работы с приложением выполнялись операции. Предусмотренные в обработчике события OnClick кнопки Button1. Поскольку неизвестно, какой компонент будет находиться в фокусе в момент этого события, надо перехватить его на уровне формы. Такой перехват осуществляется, если установить свойство формы KeyPreview в true. Тогда в обработчике события формы OnKeyPresss можно написать оператор

if((Key==-¢C¢) || (Key==-¢c¢))  Button1->Click( );

Если пользователь ввел символ «С» или «с», то в результате будет выполнен обработчик щелчка кнопки Button1.

Кнопка с фиксацией SpeedButton

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

У кнопок SpeedButton, как и у других кнопок, имеется свойство Caption – надпись, но в этих кнопках оно обычно оставляется пустым, так как вместо надписи используется пиктограмма. Изображение на кнопке задается свойством Glyph точно так же, как для кнопок BitBtn. И точно так же свойство NumGlyphs определяет число используемых пиктограмм, свойства Layout и Margin определяют расположение изображения, а свойство Spacing – расстояние между изображением и надписью (если, конечно, вы все-таки хотите использовать надпись на кнопке).

Особенностью кнопок SpeedButton являются свойства GroupIndex (индекс группы), AllowAllUp (разрешение отжатого состояния всех кнопок группы) и Down (исходное состояние – нажатое). Если GeoupIndex = 0, то кнопка ведет себя так же, как Button и BitBtn. При нажатии пользователем кнопки она погружается, а при отпускании возвращается в нормальное состояние. В этом случае свойства AllowAllUp и Dowa не влияют на поведение кнопки.

Если GroupIndex>0 и AllowAllUp = true, то кнопка при щелчке пользователя на ней погружается и остается в нажатом состоянии. При повторном щелчке пользователя на кнопке она освобождается и переходит в нормальное состояние (именно для того, чтобы освобождение кнопки состоялось, необходимо задать AllowAllUp = true). Если свойство Dowa во время проектирования установлено равным true, то исходное состояние кнопки – нажатое.

Группы радиокнопок – компоненты RadioGroup, RadioButton и GroupBox

Радиокнопки образуют группы взаимосвязанных индикаторов, из которых обычно может быть выбран только один. Они используются для выбора пользователем одной из нескольких взаимоисключающих альтернатив. Впрочем, радиокнопки могут использоваться не только для выбора, но и для отображения аналогичных данных. В этом случае управление кнопками осуществляется программно. Примеры размещения радиокнопок вы можете увидеть на рис. 1.14.

Рис. 1.14. Компоненты GroupBox и другие

Начнем рассмотрение радиокнопок с компонента RadioGroup – панели группы радиокнопок. Это панель, которая может содержать регулярно расположенные столбцами и строками радиокнопки. Надпись в левом верхнем углу панели (см. рис. 1.14) определяется свойством Items, имеющим тип TStrings. Щелкнув на кнопке с многоточием около этого свойства в окне Инспектора Объектов, вы попадете в редактор списков строк. В этом редакторе вы можете занести надписи, которые хотите видеть около кнопок, по одной в строке. Сколько строчек вы запишете – столько и будет кнопок.

Кнопки, появившиеся в панели после задания значений Items, можно разместить в несколько столбцов (не более 17), задав свойство Columns. По умолчанию Columns = 1, т. е. кнопки размещаются друг под другом.

Определить, какую из кнопок выбрал пользователь, можно по свойству ItemIndex, которое показывает индекс выбранной кнопки. Индексы, как всегда в C++ Builder, начинаются с 0. По умолчанию ItemIndex = -1, что означает отсутствие выбранной кнопки. Если вы хотите, чтобы в момент начала выполнения приложения какая-то из кнопок была выбрана (это практически всегда необходимо), то надо установить соответствующее значение ItemIndex можно программно во время выполнения приложения.

В некоторых случаях желательно нерегулярное расположение кнопок. Такую возможность дают компоненты RadioButton, сгруппированные панелью GroupBox . Панель GroupBox выглядит на форме так же, как RadioGroup, и надпись в ее верхнем левом углу также определяется свойством Caption. Эта панель сама по себе пустая. Ее назначение – служить контейнером для других управляющих элементов, в частности, для радиокнопок RadioButton. Отдельная радиокнопка RadioButton особого смысла не имеет, хотя и может служить индикатором, включаемым и выключаемым пользователем. Но в качестве индикаторов обычно используются другие компоненты – CheckBox.

Рассмотрим свойства радиокнопки RadioButton. Свойство Caption содержит надпись, появляющуюся около кнопки. Значение свойства Alignment определяет, с какой стороны от кнопки появляется надпись: taLeftJustify – слева, taRightJustify – справа (это значение принято по умолчанию). Свойство Checkked определяет, выбрана данная кнопка пользователем или нет. Поскольку в начале выполнения приложения обычно надо, чтобы одна из кнопок группы была выбрана по умолчанию, ее свойство Checked надо установить в true в процессе проектирования. Если вы поэкспериментируете, то заметите, что в true можно установить значение Checked только у одной кнопки из группы.

Радиокнопки RadioButton могут размещаться не только в панели GroupBox, но и в любой панели другого типа, а также непосредственно на форме. Группа взаимосвязанных кнопок в этих случаях определяется тем оконным компонентом, который содержит кнопки. В частности, для радиокнопок, размещенных непосредственно на форме, контейнером является сама форма. Таким образом, все кнопки, размещенные непосредственно на форме, работают как единая группа, т. е. только в одной из этих кнопок можно установить значение Checked в true.

Полоса состояния StatusBar

Очень важным компонентом, в окне которого во время выполнения программы может периодически появляться тексты актуальных сообщений, является компонент StatusBar – так называемая «полоса состояния».

Компонент StatusBar представляет собой ряд панелей, отображающих полосу состояния в  стиле Windows. Обычно эта полоса размещается внизу формы. Один из возможных вариантов размещения этого компонента показан на рис. 1.15.

Рис.1.15. Вариант размещения StatusBar на форме

Свойство SimplePanel определяет, включает ли полоса состояния одну или множество панелей. Если SimplePanel = true, то вся полоса состояния представляет собой единственную панель, текст которой задается свойством SimpleText. Такой вариант показан на рис. 1.16.

Рис. 1.16. Вариант с единственной панелью

Если же SimplePanel = false, то полоса состояния является набором панелей, задаваемых свойством Panels. В этом случае свойство SizeGrip определяет, может ли пользователь изменять размеры панелей в процессе выполнения приложения.

Каждая панель полосы состояния является объектом типа TStatusPanels. Свойства панелей вы можете задавать специальным редактором наборов, изображенном на рис. 1.17.

Рис. 1.17. Окно редактора

 Вызвать редактор можно тремя способами: из Инспектора Объектов кнопкой с многоточием около свойства Panels, двойным щелчком на компоненте StatusBar или из контекстного меню, выбрав команду Panels Editor. В окне редактора вы можете перемещаться по панелям, добавлять новые или уничтожать существующие. При перемещении по панелям  в окне Инспектора Объектов вы будете видеть их свойства.

Основное свойство каждой панели – Text, в который заносится отображаемый в панели текст. Его можно занести в процессе проектирования, а затем можно изменить программно во время выполнения. Другое существенное свойство панели – Width (ширина).

Программный доступ к текстам отдельных панелей можно осуществлять через свойство Panels и его индексированное подсвойство Items[x]. Например, оператор:

StatusBar->Panels->Items[0]->Text = «текст1»;

Напечатает текст «текст1» в первой панели.

Количество панелей полосы состояния можно определить из подсвойства Count свойства Panels. Например, следующий оператор очищает тексты всех панелей:

For (int i = 0; i < StatusBar1->Panels->Count; i++)

{

StatusBar1->Panels->Items[i]->Text = “”;

}

На рис. 1.18 изображена форма проекта одного из простейших приложений, где полоса состояния состоит из нескольких панелей.

Рис. 1.18. Форма с несколькими панелями в полосе состояния

На рис. 1.19 показано рабочее окно программы, к которой принадлежит форма рис. 1.18.

Рис. 1.19. Рабочее окно учебной программы

Далее в листинге 1.1 разместим текст файла Unit1.cpp, который входит в состав проекта.

Листинг 1.1. Файл Unit1.cpp

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

 

#include <vcl.h>

#pragma hdrstop

 

#include "Unit1.h"

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

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

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

__fastcall TForm1::TForm1(TComponent* Owner)

        : TForm(Owner)

{

 Caption = "Панель StatusBar ";

 Label1->Caption = "Свойство SimplePanel = false";

}

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

 

void __fastcall TForm1::Button2Click(TObject *Sender)

{

 StatusBar1->Panels->Items[3]->Text = "Текст от кнопки 1";

}

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

void __fastcall TForm1::Button3Click(TObject *Sender)

{

 StatusBar1->Panels->Items[3]->Text = "Это уже второй текст, записан от кнопки 2";

}

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

void __fastcall TForm1::Button1Click(TObject *Sender)

{

 Close();

}

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

 

В этой главе приведенный выше листинг является единственным. По сути дела размещенный в нем файл Unit1.cpp исключительно простой и не требует каких то пояснений, но если для вас он покажется непонятным, то пропустите его. Через несколько занятий с проектами этой книги он станет для вас совершенно понятным.

Системные диалоги

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

Разработчики C++ Builder позаботились о том, чтобы включить в библиотеку простые для исполнения компоненты, реализующие соответствующие диалоговые окна. Они размещены на странице библиотеки Dialogs. В таблице 1.1 приведен перечень этих диалогов.

Таблица 1.1. Системные диалоги и их фрагменты

Компонент

Страница

Описание

OpenDialog

«Открыть файл»

Dialogs

Предназначен для создания окна диалога «Открыть файл».

SaveDialog

«Сохранить файл»

Dialogs

Предназначен для создания окна диалога «Сохранить файл».

OpenPictureDialog

«Открыть рисунок»

Dialogs

Предназначен для создания окна диалога «Открыть рисунок», открывающего графический файл.

SavePictureDialog

«Сохранить рисунок»

Dialogs

Предназначен для создания окна диалога «Сохранить рисунок» -- сохранение изображения в графическом файле.

FontDialog

«Шрифты»

Dialogs

Предназначен для создания окна диалога «Шрифты» -- выбор атрибутов шрифта.

ColorDialog

«Цвет»

Dialogs

Предназначен для создания окна диалога «Цвет» -- выбор цвета.

PrintDialog

«Печать»

Dialogs

Предназначен для создания окна диалога «Печать».

PrinterSetupDialog

«Установка принтера»

Dialogs

Предназначен для создания окна диалога «Установка принтера».

FindDialog

«Найти»

Dialogs

Предназначен для создания окна диалога «Найти» -- контекстный поиск в тексте.

ReplaceDialog

«Заменить»

Dialogs

Предназначен для создания окна диалога «Заменить» -- контекстная замена фрагментов текста.

FileListBox

(список файлов)

Win 3.1

Отображает список всех файлов каталога.

DirectoryListBox

(структура каталогов)

Win 3.1

Отображает структуру каталогов диска.

DriveComboBox

(спискок дисков)

Win 3.1

Выпадающий список доступных дисков.

FilterComboBox

(список фильтров)

Win 3.1

Выпадающий список фильтров для поиска файлов.

CDirectoryOutline

(дерево каталогов)

Samples

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

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

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

Основной метод, которым производится обращение к любому диалогу, -- Execute. Эта функция открывает диалоговое окно и, если пользователь произвел в нем какой-то выбор, то функция возвращает true. При этом в свойствах компонента – диалога запоминается выбор пользователя, который можно прочитать и использовать в дальнейших операциях. Если же пользователь в диалоге нажал кнопку Отмена или клавишу <Esc>,то функция Execute возвращает false. Поэтому стандартное обращение к диалогу имеет вид:

if (<имя компонента – диалога> -> Execute())

 <оператор, использующий выбор пользователя>;

 

Диалоги открытия и сохранения файлов – компоненты OpenDialog, SaveDialog,

Описания таких компонентов, как различные диалоги, очень обширные и привести в этой книге все описания практически невозможно. Имеется масса другой справочной литературы, например,[1], где можно найти всю необходимую информацию. В этой главе я приведу только очень краткое описание работы с компонентами  OpenDialog  и SaveDialog . 

Компоненты OpenDialog – диалог «Открыть файл» и SaveDialog – диалог «Сохранить файл как…», пожалуй, используются чаще всего, в большинстве приложений. Вам самим довольно часто приходилось ими пользоваться.

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

Типы искомых файлов, появляющиеся в диалоге в выпадающем списке Тип файла, задаются свойством Filter.В процессе проектирования это свойство проще всего задать с помощью редактора фильтров, который вызывается нажатием кнопки с многоточием около имени этого свойства в Инспекторе Объектов. При этом открывается окно редактора, в левой панели редактора Filter Name вы записываете тот текст, который увидит пользователь в выпадающем списке Тип файла диалога. А в правой панели Filter записываются разделенные точками с запятой шаблоны фильтра. Например, задано два фильтра: текстовых файлов с расширениями .txt и doc и любых файлов с шаблоном «*.*».

После выхода из окна редактирования фильтров заданные вами шаблоны появляются в свойстве Filter в виде строки вида:

Текстовые (*.txt, *.doc) | *txt; *.doc| все файлы /*.*

В этой строке тексты и шаблоны разделяются вертикальными линиями. В аналогичном виде, если требуется, можно задавать свойство Filter программно во время выполнения приложения.

Свойство FilterIndex определяет номер фильтра, который будет по умолчанию показан пользователю в момент открытия диалога. Например, значение FilterIndex = 1 задает по умолчанию первый фильтр.

Свойство InitialDir определяет начальный каталог, который будет открыт в момент начала работы пользователя с диалогом.

Свойство DefaultExt определяет значение расширения файла по умолчанию. Если значение этого свойства не задано, пользователь должен указать в диалоге полное имя файла с расширением. Если же задать значение DefaultExt, то пользователь может писать в диалоге имя без расширения. В этом случае будет принято заданное расширение.

Свойство Title позволяет вам задать заголовок диалогового окна.

 Свойство Options определяет условия выбора файла. Множество опций, которые вы можете установить программно или во время проектирования, включает:

ofAllowMultiSelect

Позволяет пользователю выбирать несколько файлов

ofGreatePrompt

В случае, если пользователь написал имя несуществующего файла, появляется замечание и запрос, надо ли создать файл с заданным именем

ofEnableIncludeNotify

Разрешает посылать в диалог сообщения

ofEnableSizing

Разрешает пользователю изменять размер диалогового окна

ofExtensionDifferent

Этот флаг, который можно прочитать после выполнения диалога, показывает, что расширение файла, выбранного пользователем, отличается от DefaultExt

ofFileMustExist

В случае, если пользователь написал имя несуществующего файла, появляется сообщение об ошибке

ofHideReadOnly

Удаляет из диалога индикатор Открыть только для чтения

ofNoChangeDir

После щелчка пользователя на кнопке ОК восстанавливает текущий каталог, независимо от того, какой каталог был открыт при поиске файла

ofNoDereferenceLinks

Запрещает переназначать клавиши быстрого доступа в диалоговом окне

ofNoLongNames

Отображаются только не более 8 символов имени и трех символов расширения

ofNoNetworkButton

Убирает из диалогового окна кнопку поиска в сети. Действует только если флаг ofOldStyleDialog включен

ofNoReadOnlyReturn

Если пользователь выбрал файл только для чтения, то генерируется сообщение об ошибке

ofNoTestFileCreate

Запрещает выбор в сети защищенных файлов и не доступных дисков при  сохранении файла

ofNoValidate

Не позволяет писать в именах файлов неразрешенные символы, но не мешает выбирать файлы с неразрешенными  символами

ofOldStyleDialog

Создает диалог выбора файла в старом стиле

ofOverwritePrompt

В случае, если при сохранении файла пользователь написал имя существующего файла, появляется замечание, что файл с таким именем существует, и запрашивается желание пользователя переписать существующий файл

ofPathMustExist

Генерирует сообщение об ошибке, если пользователь указал в имени файла несуществующий каталог

ofReadOnly

По умолчанию устанавливает индикатор Открыть только для чтения при открытии диалога

ofShareAware

Игнорирует ошибки нарушения условий коллективного доступа и разрешает, несмотря на них, производить выбор файла

ofShowHelp

Отображает в диалоговом окне кнопку Справка

  

По умолчанию все перечисленные опции, кроме ofHideReadOnly, выключены.

В приведенной таблице даны опции, используемые в 32-разрядных версиях C++ Builder.

В компонентах диалогов открытия и сохранения файлов предусмотрена возможность обработки ряда событий. Такая обработка может потребоваться, если рассмотренных опций, несмотря на их количество, не хватает, чтобы установить все диктуемые конкретными приложениями ограничения на выбор файлов. Событие OnCanClose возникает при нормальном закрытии пользователем диалогового окна после выбора файла. При отказе пользователя от диалога – нажатии кнопки Отмена, клавиши Esc и т. д. событие OnCanClose не наступает. В обработке события OnCanClose вы можете произвести дополнительные проверки выбранного пользователем файла и, если по условиям вашей задачи этот выбор не допустим, вы можете известить об этом пользователя и задать значение false передаваемому в обработчик параметру CanClose. Это не позволит пользователю закрыть диалоговое окно.

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

Мы рассмотрели диалоги открытия и сохранения файлов произвольного типа. В библиотеке C++ Builder 5 и выше имеются также специализированные диалоги открытия и сохранения графических файлов: OpenPictureDialog и SavePictureDialog. От окон, открываемых компонентами OpenDialog и SaveDialog , они отличаются удобной возможностью просматривать изображения в процессе выбора файла.

Свойства компонентов OpenPictureDialog и SavePictureDialog ничем не отличаются от свойств компонентов OpenDialog и SaveDialog. Единственное отличие – заданное значение по умолчанию свойства Filter в OpenPictureDialog и SavePictureDialog. В этих компонентах заданы следующие фильтры:

All(*.jpg;*.jpeg; *.bmp; *.ico; *.emf; *.winf)

*.jpg; *.jpeg;

*.bmp; *.ico; *emf; *.winf

JPEG Image File (*.jpg)

*.jpg

JPEG Image File (*.jpeg)

*.jpeg

Bitmaps (*.bmp)

*.bmp

Icons (*.ico)

*.ico

Enhanced Metafiles (*.emf)

*.emf

Metafiles (*.winf)

*.winf

  

В этих фильтрах перечислены все типы графических файлов, с которыми может работать диалог. Так что вам остается удалить, если хотите, фильтры тех файлов, с которыми вы не хотите работать, добавить, может быть, фильтр «Все файлы (*.*)» и перевести на русский язык названия типов.

Главное меню – компонент MainMenu

В C++ Builder имеются два компонента, представляющие меню: MainMenu – главное меню, и PopupMenu – всплывающее меню. Оба компонента расположены на странице Standard. Эти компоненты имеют много общего. Начнем рассмотрение с компонента MainMenu.

Это невизуальный компонент.

Основное свойство компонента – Items. Его заполнение производится с помощью Конструктора Меню, вызываемого двойным щелчком на компоненте MainMenu или нажатием кнопки с многоточием рядом со свойством Items в окне Инспектора Объектов. Весь процесс построения главного меню приложения достаточно подробно описан в главе 2 (раздел «Проект 3»).

При выборе нового раздела вы увидите в Инспекторе Объектов множество свойств данного раздела. Дело в том, что каждый раздел меню, т. е. каждый элемент свойства Items, является объектом типа TMenuItem, обладающим своими свойствами, методами,  событиями.

Свойство Caption обозначает надпись раздела. Заполнение этого свойства подчиняется тем же правилам, что и заполнение аналогичного свойства в кнопках, включая использование символа амперсанта для обозначения клавиш быстрого доступа. Если вы в качестве значения Caption очередного раздела введете символ минус “- “, то вместо раздела в меню появится разделитель.

Свойство Name задает имя объекта, соответствующего разделу меню. Очень полезно давать этим объектам осмысленные имена.

Свойство Default определяет, является ли данный раздел разделом по умолчанию своего  подменю, т. е. разделом, выполняемым при двойном щелчке пользователя на родительском разделе.

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

Еще одним свойством, позволяющим вводить маркеры в разделы меню, является RadioItem. Это свойство, установленное в true, определяет, что данный раздел должен работать в режиме радиокнопки  совместно с другими разделами, имеющими то же значение свойства GroupIndex. По умолчанию значение GroupIndex равно 0. Для каждого раздела могут быть установлены во время проектирования или программно во время выполнения свойства Enabled (доступен) и Visible (видимый). Если установить Enabled = false, то раздел будет изображаться серой надписью и не будет реагировать  на щелчок пользователя. Если же задать Visible = false, то раздел вообще не будет виден, а остальные разделы сомкнутся, заняв место невидимого. Свойства Enabled и Visible используются для того, чтобы изменить состав доступных пользователю разделов в зависимости от режима работы приложения.

Начиная с C++ Builder 4 предусмотрена возможность ввода в разделы меню изображений. За это ответственны свойства разделов Bitmap и ImageIndex.

Мы рассмотрели все основные свойства объектов, соответствующих разделам меню. Основное свойство раздела – OnClick, возникающее при щелчке пользователя на разделе или при нажатии «горячих» клавиш быстрого доступа. 

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

На этом мы пока закончим очень краткое рассмотрение компонента MainMenu. Для большего количества информации смотрите  информационные материалы в инструкциях для пользователей C++Builder.

Контекстное всплывающее меню – компонент PopupMenu

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

Контекстному меню соответствует компонент PopupMenu. Поскольку в приложении может быть несколько контекстных  меню, то и компонентов PopupMenu может быть несколько. Оконные компоненты: панели, окна редактирования, а также метки и др. имеют свойство PopupMenu, которое по умолчанию пусто, но куда можно поместить имя того компонента PopupMenu, с которым будет связан данный компонент.

Формирование контекстного всплывающего меню производится с помощью Конструктора Меню, вызываемого двойным щелчком на PopupMenu, точно так же, как это делалось для главного меню.

В остальном работа с PopupMenu не отличается от работы с MainMenu. Только не возникает вопросов объединения меню разных форм: контекстные меню не объединяются. 

Горячие клавиши – компонент HotKey

Компонент HotKey, расположенный в библиотеке на странице Win32, является вспомогательным, обеспечивающим возможность задания самим пользователем горячих клавиш, определяющих быстрый доступ к разделам меню. К тому же этот компонент позволяет задать такие сочетания горячих клавиш, которые не предусмотрены в выпадающем списке свойства разделов меню ShortCut.

Вместо заключения

На этом мы заканчиваем рассмотрение очень малой части компонентов библиотеки VCL. С каждой новой версией C++Builder число задействованных компонентов увеличивается, кроме того, многие разработчики сами создают компоненты собственной разработки, которые в больших количествах можно найти в Интернете на сайтах фирм – разработчиков компьютерных программ. Если вы решили серьезно заняться программированием, то необходимо с самого начала собирать и сохранять всю попадающуюся вам в руки информацию о различных компонентах. Очень много различных компонентов можно найти у программистов, работающих с языком Паскаль. Дело в том, что Delphi, созданный на языке Паскаль, и C++Builder, созданный на C/C++, являются «родными братьями» и запросто понимают языки друг друга.

Первая глава этой книги несет в себе чисто справочную информацию, которую следует прочитать, но не стоит заучивать. При дальнейшей работе над книгой вам еще не раз придется сюда заглядывать в поисках описаний свойств некоторых компонентов. Советую вам всю свою энергию и настойчивость направить на доскональное изучение материала, расположенного в главах 2, 3, 4 и 5. Материал именно этих глав составляет учебную основу этой книги.