Статті - робота з формами lazarus - інформаційний портал для розробників на free pascal -

Відкриття форм в модальному режимі

Найбільш очевидним застосуванням програмного відкриття додаткової форми є вибір або пошук будь-якого значення в довіднику з наступним поверненням, наприклад, коду знайденого елемента в основну форму. Таку форму треба відкривати модально, так як немає сенсу продовжувати виконання основної програми, поки не зроблений вибір і форма не закрита. Спробуємо це реалізувати.

Як приклад створимо новий проект і на головну форму помістимо пару полів введення і кнопок:

Статті - робота з формами lazarus - інформаційний портал для розробників на free pascal -

В якості тестової задачі будемо відкривати додаткову форму з полем введення, в якому спочатку повинен міститися текст з відповідного поля введення головної форми. Далі передбачимо зміна цього тексту і повернення оновленого значення в головну форму. Для цього спочатку створимо додаткову форму приблизно такого вигляду:

Статті - робота з формами lazarus - інформаційний портал для розробників на free pascal -

Як програмного інтерфейсу для передачі параметра будемо використовувати властивість TestValue, яке визначимо в секції public класу форми. Також визначимо і реалізуємо більш ніж очевидні методи для установки і зчитування значення властивості, а також обробник події натискання на кнопку, в якому властивості форми ModalResult присвоюється значення mrOK, що і призводить до закриття (але не знищення!) Форми.

Однак, найбільший інтерес представляє функція RunTestForm. Як можна помітити, вона визначена поза класом форми, хоча і в тому ж модулі. Це може здатися дивним програмістам VB, де модуль класу повністю ототожнюється з самим класом. Як і в Delphi, в Lazarus це не так. Хоча в одному модулі можна визначити тільки одну форму (інакше візуальний дизайнер форм не зможе працювати), інші елементи програми не обов'язково реалізовувати окремо. У нашому випадку функція RunTestForm містить код, необхідний для створення форми, передачі їй початкового значення поля введення і повернення відредагованого значення. Очевидно, що RunTestForm за змістом пов'язана з класом форми, тому буде розумно (хоча і зовсім не обов'язково) розташувати її в модулі форми.

Тепер подивимося, як використовувати все це в основній формі. Додамо в оброблювачі подій натискання на кнопки виклики функції RunTestForm, в результаті чого розділ реалізації модуля головної форми придбає такий вигляд:

Відкриття форм в немодальному режимі

Отже, для початку визначимося, що призначення, поведінку немодального форми і принципи роботи з нею зовсім інші. Перш за все, немодальні форми не пристосовані для повернення значень, так як після їх відкриття програма не зупиняється в очікуванні закриття форми, а залишиться активним. Через це, якщо не вжити спеціальних заходів, покажчик на що відкривається форму буде втрачено після завершення роботи коду, який її створює (в нашому випадку - це функція RunTestForm). Чи так це жахливо? У більшості випадків - ні. Пам'ятайте, що при створенні екземпляра форми в конструктор передавався параметр Application? Так ось: Application - це об'єкт, який представляє все наше додаток. При такому створенні форми він буде пам'ятати про її присутності, а ми зможемо цим скористатися. Створимо в головній формі список, який будемо заповнювати іменами форм, відкритих в додатку. Основна форма при цьому дещо зміниться і буде виглядати приблизно так:

Статті - робота з формами lazarus - інформаційний портал для розробників на free pascal -

Зверніть увагу, що ми задекларували новий метод FillWindowsList, який якраз і виконує заповнення списку форм додатки. Його реалізація не дуже складна:

Тут є певний цікавий момент. Справа в тому, що об'єкт Application містить єдиний список всіх компонентів, якими володіє, тому доводиться перевіряти, що черговий компонент є саме TForm.

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

Нижче представлений весь код секції реалізації модуля основної форми. Зверніть увагу, що викликаючи метод RunTestForm ми вже не чекаємо повертається, але зате викликаємо процедуру заповнення списку вікон програми.

Тепер створимо додаткову форму, яку будемо відкривати з головної форми в немодальному режимі. Зовні вона нічим не буде відрізнятися від розглянутої в попередньому розділі модальної форми, а ось код дещо зміниться. Зверніть увагу, що властивість TestValue тепер тільки для запису, а метод RunTestForm став процедурою замість функції.

З'явилася і нова глобальна змінна - лічильник форм Form2Count. Вона знадобиться нам, коли створюваному примірнику форми ми будемо привласнювати ім'я. Всі об'єкти додатки повинні мати унікальні імена, однак LCL про це ніяк не дбає, тому доведеться діяти самостійно. Код, пов'язаний зі змінною Form2Count досить тривіальний, тому зупинятися на ньому не будемо.

Реалізація теж досить сильно змінилася. Показ форми тепер проводиться викликом методу Show, а не ShowModal, тому виконання програми не передається в створювану форму до її закриття, а триває. Про закриття і звільнення ресурсів тепер повинна піклуватися сама форма. Для цього в процедурі обробки події закриття форми ми призначимо змінної CloseAction значення caFree. Натискання на кнопку тепер викликає не установку значення ModalResult, а явне звернення до методу Close.

Якщо Ви не просто читали цю статтю, а створювали попутно описану тестову програму, саме час її запустити. Тільки знову не забудьте прибрати додаткову форму зі списку автоматично створюються при старті програми.