Основное окно ИСР

СОДЕРЖАНИЕ

Введение………………………………………………………………………..4

Ознакомление с Интегрированной Средой Разработки (ИСР)

C++Builder6 …..…………………………….………..……………..…………6

Библиографический список………..………………………….……....15

ЗАНЯТИЕ 1.Формы и компоненты…………………………………………16

Контрольные вопросы...........................................................................28

Библиографический список…………………………………………...29

ЗАНЯТИЕ 2. Отладка приложений…………………………………………30

Контрольные вопросы...........................................................................43

Библиографический список…………………………………………...44

ЗАНЯТИЕ 3. Компоненты ввода и отображения

текстовой информации………………………………………………..45

Контрольные вопросы...........................................................................63

Библиографический список…………………………………………...63

ЗАНЯТИЕ 4. Диаграммы и графики………………………………………..64

Контрольные вопросы...........................................................................72

Библиографический список…………………………………………...72

ЗАНЯТИЕ 5. Список изображений. Компоненты отображения

иерархических данных. Полоса состояния.

Перетаскивание объектов – технология Drag&Drop……………..…73

Контрольные вопросы...........................................................................88

Библиографический список…………………………………………...89

ЗАНЯТИЕ 6. Главное меню. Контекстное всплывающее меню.

Горячие клавиши………………………………………………………90

Контрольные вопросы.........................................................................102

Библиографический список…………………………………………..102

ЗАНЯТИЕ 7. Отображение хода длительных процессов.

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

Панели и компоненты внешнего оформления……………….……..103

Контрольные вопросы.........................................................................130

Библиографический список…………………………………………..131

ЗАНЯТИЕ 8. Системные диалоги………………………………………….132

Контрольные вопросы.........................................................................146

Библиографический список…………………………………………..146

ЗАНЯТИЕ 9. Технология разработки приложений.

Диспетчеризация действий…………………………………………..147

Контрольные вопросы.........................................................................161

Библиографический список…………………...………….…….…….162

ЗАНЯТИЕ 10. Динамически присоединяемые библиотеки DLL………...163

Контрольные вопросы..........................................................................176

Библиографический список………………………………….………..176

ВВЕДЕНИЕ

При составлении данного учебно-методического пособия (УМП) была поставлена задача – при изучении дисциплины обеспечить условия приобретения студентами практических навыков использования интегрированной среды разработки приложений C++Builder 6 в объеме, предусмотренном программой курса «Работа в C++Builder».

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

Занятие 1(Формы и компоненты) содержит три раздела: включение в проект новой формы, размещение компонентов на форме и депозитарий – хранилище форм и проектов. В разделах соответственно показаны: способы включения в проект новой формы; способы переноса компонентов на форму, смысл понятий родителей и владельцев компонентов, понятия Z-последовательности, действия пользователя в случае многослойного размещения компонентов на форме, способы поиска «пропавших» компонентов, порядок работы с окном Дерева Объектов, представление связей между компонентами в виде диаграммы, работа с группой компонентов; сохранение форм и проектов в депозитарии, способы заимствования формы из депозитария.

Занятие 2(Отладка приложений) содержит описания команд для компиляции и компоновки проекта, примеры сообщений компилятора и компоновщика, описания действия пользователя в случае ошибки выполнения – работа с окном наблюдения, окном оценки и модификации, пошаговое выполнение приложения. Кроме того, рассмотрено использование точек прерывания, Журнала событий и окна Инспектора Отладки.

Занятие 3(Компоненты ввода и отображения текстовой информации) посвящено изучению компонентов для отображения различных надписей на форме, однострочных и многострочных окон редактирования, компонентов, обеспечивающих выбор из списка, и компонента - таблицу, предназначенную для отображения текстовой информации.

Занятие 4(Диаграммы и графики) содержит примеры использования компонентов, позволяющих строить различные диаграммы и графики.

Занятие 5(Список изображений. Компоненты отображения иерархических данных. Полоса состояния. Перетаскивание объектов – технология Drag&Drop) начинается с описания списка изображений – компонента, представляющего собой набор изображений одинаковых размеров. Затем рассмотрены компоненты, служащие для отображения иерархических данных в виде дерева с возможностью выбора нужного узла или узлов. Далее рассмотрен компонент, отображающий полосу состояния. Перетаскивание объектов – технология Drag&Drop рассмотрена на примере работы с деревом. В заключение рассмотрен компонент, позволяющий отображать данные в виде списков, таблиц, крупных и мелких пиктограмм.

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

Занятие 7(Отображение хода длительных процессов. Кнопки, индикаторы, управляющие элементы. Панели и компоненты внешнего оформления) включает в себя изучение компонентов для отображения хода процессов, занимающих заметное время; кнопок, индикаторов, управляющих элементов – ползунков и полос прокрутки; компонентов-заголовков, компонента-таймера, компонента-календаря; панелей общего назначения, многостраничных панелей, инструментальных панелей, перестраиваемых панелей.

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

Занятие 9(Технология разработки приложений. Диспетчеризация действий) имеет цель – приобретение навыков проектирования интерфейса через общий подход, который начинается с составления списка действий для работы с проектируемым проиложением. На примерах показано, как список действий реализуется с помощью компонентов – диспетчеров действий.

Занятие 10(Динамически присоединяемые библиотеки DLL) содержит описание назначения и способов реализации динамически присоединяемых библиотек DLL. Приведен пример создания DLL. Также на примерах показано, как реализовать статическое и динамическое связывание DLL с проектируемым приложением.

Ознакомление с Интегрированной Средой Разработки (ИСР)

C++Builder 6

Интегрированная Среда Разработки (Integrated Development Environment – IDE, или ИСР) – это среда, в которой есть все необходимое для быстрой разработки (проектирования) сложных прикладных программ (приложений). ИСР интегрирует в себе редактор кодов, отладчик, инструментальные панели, редактор изображений, инструментарий баз данных, что позволяет проектировать, запускать и тестировать приложения.

Проекты C++Builder

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

Головной файл проекта (.cpp) C++Builder создает файл .cpp для головной функции WinMain, инициирующей приложениеи запускающей его на выполнение
Файл опций проекта (.bpr) Этот текстовый файл содержит установки опций проекта и указания на то, какие файлы должны компилироваться и компоноваться в проект. Файл сохраняется в формате XML
Файл ресурсов проекта (.res) Двоичный файл, содержащий ресурсы проекта: пикто-граммы, курсоры и т.п. По умолчанию содержит только пиктограмму проекта. Может дополняться с помощью Редактора Изображений
Файл реализации модуля (.cpp) Каждой создаваемой пользователем форме соответствует текстовый файл реализации модуля, используемый для хранения кода. Пользователь может создавать модули, не связанные с формами
Заголовочный файл модуля (.h) Каждой создаваемой пользователем форме соответствует не только файл реализации модуля, но и его заголовочный файл с описанием класса формы. Пользователь может и сам создавать необходимые заголовочные файлы
Файл формы (.dfm) Это двоичный или текстовый файл, который C++Builder создает для хранения информации о фор- мах пользователя. Пользователь может смотреть этот файл в текстовом виде или в виде формы. Каждому файлу формы соответствует файл модуля (.cpp)
Заголовочный файл компонента (.hpp) Файл создается при создании пользователем нового компонента. Пользователю также часто приходится подключать к проекту эти файлы из библиотеки компонентов C++Builder, расположенные в каталоге Include\VCL
Файл группы проектов (.bpg) Текстовый файл, создаваемый в C++Builder при созда-нии пользователем группы проектов
Файлы пакетов (.bplи .bpk) Эти двоичные файлы используются C++Builder при работе с пакетами: .bpl– файл самого пакета, .bpk– файл, определяющий компиляцию и компоновку пакета
Файл рабочего стола проекта (.dsk) В этом текстовом файле C++Builder хранит информацию о последнем сеансе работы с проектом: открытых окнах, их размерах и положении. Благодаря этому файлу в новом сеансе работы пользователь сразу видит тот же экран, который был в предыдущем сеансе. Файл создается только при включении опции Опции автосохранения |Рабочий стол проекта ( на странице Предпочтения–многостраничного окна Опции среды общих настроек среды, вызываемого командой Инструменты|Опции среды)
Файлы резервных копий (.~bp, .~df, .~cp, .~h) Это соответственно файлы резервных копий для файлов проекта, формы, реализации модуля и заголовочного. Если пользователь что-то безнадежно испортит в своем проекте, он может соответственно изменить расширения этих файлов и таким образом вернуться к предыдущему не испорченному варианту

Следующая группа файлов создается компилятором:

Исполняемый файл (.exe) Это исполняемый файл проектируемого приложения. Он является автономным исполняемым файлом, для которого больше ничего не требуется, если только пользователь не использует библиотеки, содержащиеся в пакетах, DLL, OCX и т.д.
Объектный файл модуля (.obj) Это откомпилированный файл модуля (.cpp), который компонуется в окончательный исполняемый файл
Динамически присоединяемая библиотека (.dll) Этот файл создается в случае, если пользователь проектирует свою собственную DLL
Файл таблицы символов (.tds) Двоичный файл, используемый отладчиком в процессе отладки приложения
Файлы выбороч-ной компоновки (.il?) Файлы с расширением, начинающемся с il(.ilc, .ild, .ilf, .ils), позволяют повторно компоновать только те файлы, которые были изменены после последнего сеанса

C++Builder может использовать файлы Windows:

Файлы справки (.hlp) Это стандартные файлы справки Windows, которые могут быть использованы приложением C++Builder
Файлы изображе-ний или графичес-кие файлы (.wmf, .bmp, .ico) Эти файлы обычно используются в приложениях Win-dows для создания привлекательного и дружественного пользовательского интерфейса

Из всех перечисленных файлов (а могут использоваться еще и другие) важнейшими являются файлы .cpp, .h, .dfm, .bpr, .res. Это файлы, которые необходимо перенести на другой компьютер, чтобы продолжить на нем работу над проектом. Все остальные файлы C++Builder создаст автоматически в процессе компиляции проекта и его отладки.

Главной частью приложения является головной файл .cpp(файл проекта, исходный файл проекта) с функцией WinMain, с которой начинается выполнение программы и которая обеспечивает инициализацию других модулей. Она создается и модифицируется C++Builder автоматически в процессе разработки приложения. Имя, которое дает пользователь файлу проекта, когда сохраняет его, становится именем исполняемого файла.

Все изменения файла проекта при добавлении новых форм, изменении имен форм и т.п. поддерживаются C++Builder автоматически. Для просмотра исходного файла проекта надо выполнить команду Проект|Вид источника. Но обычно просмотр не требуется.

Информация о формах C++Builder хранится в трех файлах: .dfm, .cpp, и .h. Информация о внешнем виде формы, ее размерах, местоположении на экране и т.д. хранится в файле с расширением .dfm, который по умолчанию имеет текстовый вид. Для хранения файла формы в двоичном виде нужно щелкнуть на форме правой кнопкой мыши, и во всплывшем меню выключить индикатор Текст DFM.

Основной файл, с которым работает пользователь, – это файл реализации модуля .cpp, в котором хранится код, соответствующий данной форме. В текстовом заголовочном файле с расширением .hхранится объявление класса используемой формы. Весь основной текст этого файла C++Builder формирует автоматически по мере проектирования пользователем формы. Но иногда требуется вручную вводить в этот файл объявления каких-то функций, типов, переменных. В C++Builder заголовочный файл загружается в окно Редактора Кода автоматически.

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

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

Чтобы создать в проекте новый модуль, не связанный с какой-либо формой, надо выполнить команду Файл|Новый|Другое и в открывшемся многостраничном окне Новые элементы дважды щелкнуть на пиктограмме Модуль страницы Новый.

По окончании работы над проектом следует удалить вспомогательные файлы – .obj, .res,.tds,.il?, ~*. Объем файлов .tds может быть очень большим (мегабайты).

Основное окно ИСР

Основное окно ИСР появляется на экране после запуска C++Builder 6.

В верхней части окна ИСР находится полоса главного меню. Главное меню имеет следующие разделы (меню).

Файл – позволяет создать новый проект, новую форму, открыть ранее созданный проект или форму, сохранить проекты или формы в файлах с заданными именами.

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

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

Вид – позволяет вызывать на экран различные окна, необходимые для проектирования.

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

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

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

База данных – позволяет использовать инструментарий для работы с базами данных.

Инструменты – позволяет настраивать ИСР и выполнять различные вспомогательные программы, например: вызывать редактор изображений, работать с программами, конфигурирующими базы данных и т.д. Кроме того, в это меню можно включать любые разделы, вызывающие те или иные приложения.

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

Помощь – содержит разделы, помогающие работать со встроенной в C++Builder справочной системой.

Помимо главного меню в C++Builder имеется система контекстных всплывающих меню, которые появляются, если пользователь поместил курсор мыши в каком-то окне или на каком-то компоненте и щелкнул правой кнопкой мыши. Большинство разделов контекстных меню дублирует основные разделы главного меню. Но есть и разделы, отсутствующие в главном меню и позволяющие ускорить программирование.

Ниже полосы главного меню в окне ИСР расположены две инструментальные панели. Левая панель (состоит из нескольких панелей) содержит два ряда быстрых кнопок, дублирующих некоторые наиболее часто используемые команды меню. Правая панель содержит палитру компонентов библиотеки визуальных компонентов. Палитра компонентов содержит ряд страниц, закладки которых видны в ее верхней части.

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

В основном поле окна слева видны два окна: сверху – Дерева Объектов, под ним – Инспектора Объектов (Инспектора проекта). Окно Дерева Объектов будет отображать иерархическую связь визуальных и невизуальных компонентов и объектов проектируемого приложения. А Инспектор Объектов – это основной инструмент, с помощью которого пользователь задает свойства компонентов и обработчики событий. Правее этих окон видно окно пустой формы, готовой для переноса на нее компонентов. Под ним расположено окно Редактора Кода. Чтобы увидеть его, окно формы необходимо сдвинуть.

Проектирование приложения – расчет по формуле z=f(x,y)

1.Создайте для проекта приложения каталог (папку Windows) с именем PROBA и запустите C++Builder 6.

2.Создайте новый проект командой Файл|Новый|Приложение.

3.Сразу сохраните файл модуля и проект командой Файл|Сохранить все. Во время работы над проектом удобно использовать соответствующую быструю кнопку. При первом сохранении C++Builder спросит сначала имя файла сохраняемого модуля, а затем – имя головного файла проекта. Файл модуля и головной файл проекта имеют одинаковое расширение .cpp и поэтому они должны различаться именами, чтобы не затереть на диске друг друга. Итак, файлу модуля дайте имя Formula, а файлу проекта – PR_Formula.В последующих сеансах работы можно открыть сохраненный проект командой Файл|Открыть проект ( или Повторно открыть).

4.Перейдите в Инспектор Объектов, щелкнув левой кнопкой мыши на свойстве Caption (надпись). Данное по умолчанию значение Form1 свойства Caption замените на значение РАСЧЕТ ПО ФОРМУЛЕ. Перейдите в форму, щелкнув на ней левой кнопкой.

5.В процессе первого проектирования приложения полезно иметь в качестве справки результат проектирования, представленный на рис.1.

Основное окно ИСР - student2.ru

Рис.1 – форма по окончании проектирования

6.Перенесите па пустую форму кнопку Button со страницы Стандарт палитры компонентов. Для этого выделите пиктограмму кнопки (она седьмая слева). При этом первая слева кнопка-указатель приобретет вид ненажатой кнопки. Это означает намерение поместить компонент (в данном случае кнопку) на форму. Если нажать кнопку-указатель, то это будет означать отказ от размещения выбранного компонента. Итак, выделив пиктограмму кнопки, щелкните курсором мыши в нижней части формы, посредине. На форме появится кнопка, которой C++Builder присвоит имя по умолчанию – Button1. Теперь свойствам перенесенного на форму компонента – кнопке присваивают нужные значения. (Во время присваивания компонент должен оставаться выделенным, т.е. окруженным рамкой с маркерами. Для выделения компонента достаточно щелкнуть на нем левой кнопкой мыши. Для удаления ошибочно перенесенного на форму компонента нужно выделить его и нажать клавишу Delete.) Перейдите в Инспектор Объектов и измените ее свойство Caption (надпись), которое по умолчанию равно Button1, на РАСЧЕТ. Установите свойство кнопки Height(высота) равным 30. Раскройте двойным щелчком свойство Font (шрифт), установите свойство шрифта Height(высота) равным 10, затем также двойным щелчком раскройте подсвойство Style (стиль) и установите в trueсвойство fsBold(жирный). Затем перейдите в форму, щелкнув на ней курсором мыши. Выделение с кнопки будет снято.

7.Над кнопкой РАСЧЕТ поместите на форме панель Panel1. На странице Стандарт палитры компонентов пиктограмма панели – вторая справа. Результат расчета по формуле будем выводить в панель, и поэтому, перейдя в Инспектор Объектов, очистите свойство Caption у панели. Высоту шрифта установите равной 20. Поварьируйте такими свойствами панели, как BevelInnerи BevelOuter, которые определяют вид (утопленный – bvLoweredили выпуклый – bvRaised)основного поля и рамки панели. Установите BevelInner= bvLoweredи BevelOuter= bvRaised.

8.Над панелью поместите метку Label1 (на странице Стандарт – четвертая слева). Укажите на метке надпись РЕЗУЛЬТАТжирным шрифтом, высотой 20.

9.Перенесите в верхнюю часть формы со страницы Дополнительно два окна редактирования с присоединенными к ним метками LabeledEdit, расположив их на одной горизонтали. Измените надписи в метках компонентов LabeledEditна ЗНАЧЕНИЕ X и ЗНАЧЕНИЕ Y соответственно. Для этого щелкните на символе ‘+’ в свойстве EditLabelэтих компонентов и измените надпись в свойстве Caption раскрывшихся списков свойств меток на ЗНАЧЕНИЕ X и ЗНАЧЕНИЕ Y соответственно. Задайте для меток жирный шрифт высотой 10. Закройте свойствоEditLabel,щелкнув на символе ‘-’ перед этим свойством. Затем высоте шрифта присвойте значение 10, а свойству Text компонентов - значения 1,3 и 5,6 соответственно.

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

11. Выделите кнопку РАСЧЕТ на форме, щелкнув на ней курсором мыши. Перейдите в Инспектор Объектов, откройте в нем страницу событий (События), найдите (второе сверху) событие кнопки OnClick (щелчок) и сделайте двойной щелчок в окне справа от имени этого события. Это стандартный способ задания обработчиков любых событий. Но перейти в обработчик события OnClick(только этого события) можно и иначе: достаточно сделать двойной щелчок на кнопке. В обоих случаях окажетесь в окне Редактора Кода и увидите там функцию с заголовком, который складывается из имени класса формы (TForm1), имени компонента (Button1) и имени события без префикса On (Click). Курсор находится в позиции, с которой вписывается обработчик события. Например, в случае формулы

Основное окно ИСР - student2.ru

он может выглядеть так (курсив):

void __fastcall TForm1::Button1Click(TObject *Sender)

{

double x,y,z;

x=StrToFloat(LabeledEdit1->Text);

y=StrToFloat(LabeledEdit2->Text);

z=(exp(x*x+2.37)-pow(x,1.5))/sqrt(fabs(y*y*y+atan2(y,x)));

Panel1->Caption="z="+FloatToStr(z);

}

12.Перейдите в этом файле выше и после директивы #include”Formula.h” добавьте директиву #include <math.h>.

13.Сохраните проект быстрой кнопкой Сохранить все и запустите приложение на выполнение командой Запуск|Запустить или нажмите соответствующую быструю кнопку, или нажмите «горячую» клавишу F9. После недолгой компиляции, сопровождающейся временным появлением на экране окна компилятора, появится окно приложения. Щелкнув на кнопке РАСЧЕТ, в панели получите результат выполнения приложения (рис.2).

Основное окно ИСР - student2.ru

Рис.2 – форма с результатом выполнения приложения

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

14.Введите форматированный вывод в строку в обработчике. Для этого используется функция FloatToStrF с синтаксисом:

System::AnsiString FloatToStrF(Extended Value,

TFloatFormat Format, int Precision, int Digits).

Число Value функция преобразует в строку с помощью формата типа TfloatFormatс синтаксисом: enum TfloatFormat{ffGeneral, ffExponent, ffFixed, ffNumber, ffCurrency};

Возможные значения формата определяют следующие правила форматирования:

ffGeneral Основной числовой формат. Число преобразуется по формату с фиксированной точкой или научному в зависимости от того, какой из них оказывается короче. Начальные нули удаляются, десятичная точка ставится только при необходимости. Фиксированный формат используется, если число разрядов слева от точки не больше указанной точности Precisionи если значение не меньше 0.00001. В противном случае используется научный формат, в котором параметр Digitsопределяет число разрядов степени – от 0 до 4
ffExponent Научный формат. Число преобразуется в строку вида “–d.ddd…E+dddd”. Общее число цифр, включая одну перед десятичной точкой, задается параметром Precision. После символа “E” всегда следует знак “+” или “–“ и до четырех цифр. Параметр Digits определяет минимальное число разрядов степени – от 0 до 4
ffFixed Формат с фиксированной точкой. Число преобразуется в строку “–ddd.ddd…”. По крайней мере одна цифра всегда предшествует десятичной точке. Число цифр после десятичной точки задается параметром Digits, который может лежать в пределах от 0 до 18. Если число разрядов слева от десятичной точки больше указанного параметром Precision, то используется научный формат

Соответствующую строку в обработчике измените следующим образом:

Panel1->Caption=”z=”+FloatToStrF(z,ffExponent,5,2);

После ввода команды Сохранить все запустите приложение на выполнение (рис.3).

Основное окно ИСР - student2.ru

Рис.3 – форматирование результата

Теперь в окна редактирования можно вводить значения Основное окно ИСР - student2.ru и Основное окно ИСР - student2.ru (между целой и дробной частью числа ставьте запятую!) и получать результат Основное окно ИСР - student2.ru , нажимая на кнопку РАСЧЕТ.Поэкспериментируйтесформатами ffGeneral и ffFixed.

15.Выйдите из среды C++Builder.

Наши рекомендации