Научиться создавать многооконные приложения, применять модальные и немодальные окна.
До сих пор мы с вами все приложения делали с одним единственным окном. А между тем, в современном программировании редко встречаются программы, имеющие только одно окно. Даже простые стандартные утилиты, вроде Калькулятора calc.exe или игры "Сапер" - winmine.exe имеют по нескольку окон. Я недавно закончил проект для одной организации, проект этот можно считать средней сложности, а он содержит 102 окна! В этой лекции мы с вами научимся делать многооконные приложения.
Имеется два типа интерфейсов: SDI (Single Document Interface - однодокументный интерфейс) и MDI (Multi Document Interface - многодокументный интерфейс). SDI-приложения работают одновременно с одним документом, MDI-приложения предназначены для одновременной работы со множеством однотипных документов. При этом все документы располагаются внутри одного контейнера, которым служит, как правило, главная форма. Компания Microsoft не рекомендует использовать MDI-интерфейсы, хотя сама использует их в различных служебных программах, например, в консолях вроде Диспетчера устройств. Кроме того, разработка MDI-приложений в Lazarus пока не реализована, так что подробно рассматривать MDI-интерфейсы мы не будем, хотя вкратце и коснемся этой темы. Но вначале - SDI.
В SDI-приложениях окна могут быть двух видов - модальные и немодальные. Создаются они одинаково, разница заключается только в способе вывода этих окон на экран. Модальное окно блокирует программу, не даёт с ней работать, пока вы это окно не закроете. Стандартный пример модального окна - окно "О программе", которое присутствует почти в любом приложении. Как правило, такое окно находится в меню "Справка". Пока вы не нажмете "ОК", закрыв это окно, вы не сможете работать с основной программой.
Немодальные окна позволяют переключаться между ними, и программой, и работать одновременно и там, и там. Типичный пример - окна Lazarus - вы можете переключаться между Инспектором объектов, Редактором кода, Редактором форм, и другими окнами - они не мешают друг другу, так как все они немодальные.
Изучим работу с различными окнами на примерах.
Если вы помните, в лекции №18 мы делали лабораторную работу - Блокнот-шифровальщик. Там мы предусмотрели в меню "Справка" подменю "О программе", но само окно не делали. Пришло время исправить это упущение. Вы должны были сохранить проект в папку 18-01 под именем CodeBook. Убедитесь, что Lazarus закрыт, и загрузите файл CodeBook.lpi - это информационный файл проекта. В результате, загрузится Lazarus с этим проектом (с тем же успехом можно было бы загрузить файл CodeBook.lpr).
Выберите команду меню "Файл -> Создать форму" или нажмите одноименную кнопку на Панели инструментов. Появится новая форма с именем по умолчанию Form1. Мы с вами договаривались называть все формы понятными именами, и в начале имени ставить префикс f, что означает форму. Поэтому в свойстве Name этой формы напишите fAbout, затем нажмите кнопку "Сохранить все" (или выберите "Файл -> Сохранить все"), и модулю этого нового окна дайте имя About. Переключитесь клавишей <F12> в Редактор кода - вы увидите вкладки модулей:
(рис 20.1) Вкладки модулей в Редакторе кода
Два из этих модулей - Main и About имеют формы. Переходя по этим вкладкам можно переключаться между модулями. Но нам сначала нужно сделать само окно "О программе". Так что клавишей <F12> переключитесь обратно в Редактор форм. Прежде всего, в свойстве BorderStyle формы fAbout выберите значение bsDialog, так как нам не нужно, чтобы пользователь имел возможность изменять размеры окна, разворачивать или сворачивать его. Затем в свойстве Position выберите poMainFormCenter, чтобы окно появлялось по центру главного окна. До сих пор мы не устанавливали это значение у окон, так как все наши приложения содержали единственное, оно же главное окно. Окно "О программе" - не главное, поэтому его желательно выводить на экран по центру главного окна. Главным в проекте считается окно, созданное первым, его мы обычно называем fMain.
В свойстве Caption формы напишите "О программе".
Установите на форму простую панель TPanel, очистите ее свойство Caption. Чтобы сделать из панели красивую рамку, установите в её свойстве BevelInner значение bvLowered.
Далее, на панель установите две метки TLabel и один TMemo. В TMemo мы будем выводить многострочный текст с пояснением о назначении программы. Поскольку нам не нужно, чтобы пользователь мог редактировать этот текст, свойство ReadOnly компонента Memo1 установите в True. Текст в Memo1 придется вводить встроенным Редактором через свойство Lines.
Ниже панели установите кнопку TBitBtn с вкладки Additional Палитры компонентов, в свойстве Kind кнопки выберите значение bkOK.
Для экономии места я не буду подробно расписывать, как вводить в метки текст, менять у компонентов шрифты и размеры - вы прекрасно должны уметь делать это сами. В результате у вас должна получиться примерно такая форма:
(рис 20.2) Форма fAbout
Замечу, что во всех компонентах я выбирал свой любимый шрифт - Times New Roman - вы же можете выбрать свой, только подберите подходящие размер и начертание.
Отдельно остановлюсь на строчке Copyright. Слово Копирайт (англ. Copyright) означает авторское право. Причем авторское право может быть двух видов - имущественное и неимущественное. Если вы делаете программу на заказ, то имущественное авторское право принадлежит заказчику - он может устанавливать эту программу на сколько угодно компьютеров, продавать или дарить ее. Неимущественное право в любом случае принадлежит автору программы, то есть, вам. Оно подразумевает, что программу нельзя переименовывать или изменять её код без вашего согласия, и что в программе вы обязательно должны упоминаться, как автор. Таким образом, если вы делаете программу на заказ, вы не обязаны вместе с программой отдавать исходный код вашего проекта! Иначе получится, что вы передаете заказчику не только имущественное, но и неимущественное право, а это уже будет цена продукта на порядок выше.
Так вот, в строчке Copyright указывается имущественный правообладатель. Если вы делаете программу на заказ, здесь вы должны указать заказчика. Себя же вы можете упомянуть строчкой ниже, установив еще одну метку, и начав ее текст, как "Автор: ". Но поскольку в данном проекте заказчика у нас нет, то все авторские права принадлежат нам. Кстати, указывайте не мою, а свою фамилию, ведь я добровольно выкладываю этот код для общего использования, а проект по моим описаниям делали все же вы!
И еще. Знак авторского права © имеет в таблице символов код 0169. Чтобы вставить его в Caption метки, при вводе текста нажмите <Alt>, и удерживая его, наберите 0169. Затем отпустите <Alt>. Символ должен появиться в метке. Вместо этого знака иногда указывают упрощенный вариант: "(с)". Сделайте, как считаете нужным.
Окно мы сделали, нужно теперь научить программу выводить его по требованию пользователя. Кнопкой <F12> перейдите в Редактор кода, затем, щелкнув по вкладке Main, перейдите на модуль главной формы. Вот так, сходу, мы ещё не сможем вызвать форму fAbout, сначала нужно подключить её модуль к главной форме. В разделе uses главной формы, после модуля MyCript через запятую добавьте модуль новой формы About. Теперь мы сможем вызывать это окно!
Сгенерируйте событие OnClick для команды меню "Справка -> О программе" (если вы еще помните, для этого достаточно просто выбрать данную команду). Её код очень простой:
procedure TfMain.HelpAboutClick(Sender: TObject);
begin
fAbout.ShowModal;
end;
Метод ShowModal, указанный в коде, вызывает на экран окно fAbout в модальном режиме. Пока окно не закроется, с программой работать будет нельзя. Как только оно закроется, управление передастся обратно в программу. Сохраните проект, запустите его на выполнение и убедитесь, что окно "О программе" вызывается по требованию пользователя и закрывается кнопкой "ОК". Однако не спешите закрывать проект, он нам еще понадобится.
Как уже упоминалось, немодальные окна могут быть открыты одновременно с основной программой, и не мешают её работе. Чтобы продемонстрировать работу немодальных окон, снабдим наш проект Блокнота-шифровальщика еще одной полезной функцией - статистикой. Создадим еще одно маленькое окно, в котором будем выводить количество строк в тексте, количество слов и символов.
Создайте новую форму командой "Файл -> Создать форму" или одноименной кнопкой на панели инструментов Lazarus. Форму (свойство Name) назовите fStats, а ее модуль сохраните под именем Stats. Далее, в свойстве Caption формы напишите "Статистика". Свойство BorderStyle установим в bsDialog, чтобы пользователь не мог менять размеры формы, а Position - в poMainFormCenter, чтобы окно появлялось по центру главного окна.
Теперь нам понадобятся шесть меток TLabel. Первые три установите в левой части формы, одну под другой. Эти метки мы переименовывать не будем, так как нам не придется обращаться к ним программно. В первой напишите "Строк:", во второй "Слов:" и в третьей "Символов:". Не забывайте ставить двоеточие после этих слов. Затем в правой части, так же одну под другой, установим еще три метки, их уже переименуем. В свойстве Name этих меток напишите, соответственно, LinesCount, WordsCount и CharsCount, а в свойстве Caption всех трех меток установите "0" (ноль).
В центре нижней части формы с вкладки Additional Палитры компонентов установите кнопку TBitBtn, в свойстве Kind которой выберите значение bkOK. В результате, у вас должна получиться примерно такая форма:
(рис 20.3) Форма fStats
Сгенерируйте следующее событие OnClick для кнопки "ОК":
procedure TfStats.BitBtn1Click(Sender: TObject);
begin
Close;
end;
То есть, когда пользователь нажмет на эту кнопку, окно статистики закроется.
Далее перейдем в модуль главного окна fMain. Чтобы мы могли оттуда вызвать новое окно, нужно через запятую добавить его модуль Stats в конец раздела uses, как это мы делали с модулем About в прошлом примере. Сюда же добавьте еще два модуля: LCLProc и StrUtils. В первом реализованы UTF8-функции, одна из них нам понадобится для определения количества символов. Во втором реализовано множество полезных строковых функций, включая и ту, которая нам нужна для подсчета количества слов в тексте:
(рис 20.4) Присоединенные модули
Теперь подумаем, каким образом мы будем вызывать окно статистики. Лучше всего поместить вызов статистики в раздел меню "Файл". Дважды щелкните по MainMenu1, чтобы вызвать редактор меню. В разделе меню "Файл" выделите подраздел "Сохранить как…", щелкните по нему правой кнопкой и выберите команду "Вставить новый пункт (после)". В свойстве Name нового подпункта введите FileStat, а в свойстве Caption напишите "Статистика":
(рис 20.5) Новый подпункт в меню
Теперь закройте Редактор меню; выбрав команду "Файл -> Статистика" сгенерируйте событие OnClick для нового подпункта. Код события следующий:
procedure TfMain.FileStatClick(Sender: TObject);
begin
fStats.Show;
end;
Как видите, здесь мы вызываем форму fStats, но не методом ShowModal, как в прошлом примере, а методом Show. В результате окно будет показано, как немодальное. Однако этого недостаточно, чтобы окно показывало статистику. Нам нужно еще подсчитать и вывести на экран количество строк, слов и символов.
Выделите компонент Memo1. В Инспекторе объектов перейдите на вкладку "События" и сгенерируйте для него событие OnChange, дважды щелкнув по нему. Это событие возникает всякий раз при изменении текста в Memo1, тут мы и будем считать статистику. Код события следующий:
procedure TfMain.Memo1Change(Sender: TObject);
begin
//считаем символы:
fStats.CharsCount.Caption:= IntToStr(UTF8Length(Memo1.Text));
//слова:
fStats.WordsCount.Caption:= IntToStr(WordCount(Memo1.Text, StdWordDelims));
//строки:
fStats.LinesCount.Caption:= IntToStr(Memo1.Lines.Count);
end;
Тут для нас много нового, так что разберем код подробней. Вначале функцией UTF8Length (см. лекцию №6) мы получили количество символов в тексте Memo1, включая служебные символы перехода на новую строку. Это - целое число, которое нам пришлось преобразовать в строковую форму с помощью функции IntToStr, чтобы мы могли присвоить эту строку свойству Caption метки CharsCount. Обратите внимание, что метка находится не на этой, а на другой форме, поэтому нам пришлось сначала указать имя этой формы, затем имя метки и уж потом свойство Caption.
Слова в тексте считать сложнее, для этого мы воспользовались новой для нас функцией WordCount. Функция описана в модуле StrUtils, который мы подключили, она возвращает количество слов в указанном тексте, и имеет следующий синтаксис:
function WordCount(const S: String; const WordDelims:TSysCharSet):integer;
Константа S содержит текст, в котором подсчитываются слова, в нашем случае, это Memo1.Text. Константа WordDelims содержит список символов-разделителей, которыми может отделяться одно слово от другого. Проще всего в этом параметре воспользоваться системной константой StdWordDelims, которая уже описана в том же модуле, и объявлена следующим образом:
const StdWordDelims = [#0..' ', ',', '.', ';', '/', '\', ':', '''', '"', '`'] + Brackets;
То есть, в этой константе перечислены основные символы-разделители слов. Функция возвращает целое число - количество слов в указанном тексте. Преобразовав его в символьную форму, мы присваиваем это значение свойству Caption метки WordsCount.
А вот количество строк даже считать не нужно, оно содержится в свойстве Memo1.Lines.Count. Нам остается лишь преобразовать его в символьную форму, и присвоить соответствующей метке. Теперь каждый раз, как в Memo1 изменится текст (пользователь ввел символ, скопировал текст в Memo или удалил текст), это событие будет пересчитывать количество слов, символов и строк, и выводить их в форму fStats, даже если ее не видно. Выбрав команду меню "Файл -> Статистика", пользователь сможет вывести окно статистики. Более того, он может, не закрывая этого окна, вернуться в главную форму и продолжать набирать текст. Окно статистики при этом будет параллельно отображать результаты:
(рис 20.6) Немодальное окно статистики в действии
Сохраните проект, запустите его на выполнение и убедитесь, что окно статистики не мешает работе главного окна. Проект Блокнота-шифровальщика нам потребуется ещё в лекциях №№ 28 и 29, так что не удаляйте его.
В отличие от Delphi, в Lazarus пока не реализована возможность создания MDI-приложений, а поскольку MDI-интерфейсы считаются устаревшими, то возможно, она и не будет реализована. Но знать об этих интерфейсах нужно, поэтому вкратце коснемся этой темы, тем более, что я могу ошибаться, и в следующих версиях Lazarus разработчики эту возможность все же реализуют. Принцип создания MDI-приложений следующий:
FormStyle (стиль формы) родительского окна следует выбрать значение fsMDIForm.FormStyle дочернего окна следует выбрать значение fsMDIChild.FormStyle этих форм следует оставить значение по умолчанию fsNormal.Для реализации MDI-интерфейса сами разработчики рекомендуют установить дополнительный компонент
Русскоязычной страницы этого компонента, к сожалению, нет, так что вам придется воспользоваться каким-нибудь переводчиком, например, Promt.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.