Багатодокументна MDI-вікна в Delphi
У нашому випадку програма запускається і відразу створюється дочірнє вікно. До речі, ми поки ще не написали ніде, що якісь вікна потрібно створювати, вони самі звідкись з'являються. У нас є класи, у нас в розділі var є необхідні змінні, але ніде не видно коду, який ініціалізує ці змінні і поміщає в них екземпляри класів. Справа в тому, що всі форми потрапляють в список автоматично створюваних, а ініціалізацію ви можете знайти в вихідному коді проекту (меню Project | View Source (Проект | Подивитися исходник).
У лівій частині вікна перераховані ті форми, які будуть створюватися автоматично (Auto-create forms (Автосоздаваемие форми)). Виділіть тут childForm (наше дочірнє вікно) і перемістіть його в список Available forms (Доступні форми), натиснувши кнопку між списками у вигляді одиночної стрілки, спрямованої
вправо. Тепер дочірня форма не буде створюватися автоматично. Ця дія доведеться робити вручну.
Встановіть на головну форму панель і розтягніть її по верхньому краю вікна (властивість Align треба встановити в aiTop). Тепер на панель встановимо кнопку і дамо їй заголовок Створити (рис. 9.15).
При натисканні на цю кнопку ми будемо вручну створювати вікно. Для цього напишемо наступний код:
procedure TMainForm.CreateButt # 111; nclick (Sender: TObj ect); begin
ChildForm: = TChildForm.Create (Owner); end;
Тут ми присвоюємо змінної ChildForm покажчик на нове створене вікно TChildForm.create. Мінлива ChildForm оголошена в модулі дочірнього вікна в розділі var:
Запустіть програму і спробуйте декілька разів натиснути на кнопку Створити. У вас повинно скластися відразу кілька дочірніх вікон, як показано на рис. 9.16.
Але якщо ви спробуєте закрити будь-який з них, воно просто згорнеться. Щоб вікно закривалося, потрібно створити обробник події Onciose для дочірньої форми і в ньому написати:
procedure TChildForm.FormClose (Sender: TObject; var Action: TCloseAction);
Тут змінної Action (дія) присвоюється значення caFree. Ця змінна передається обробнику події в якості другого параметра. Ми змінюємо дію, яке виконується за замовчуванням для клієнтських багатодокументна вікон на caFree, що змушує форму знищитися. Як ви могли переконатися, за замовчуванням для MDI-додатків вікно згортається.
Відразу ж подивимося, які ще значення може отримувати змінна Action:
- caNone - нічого не робити, т. е. вікно не буде закрито;
- caHide - заховати вікно, але при цьому воно не буде знищено, а пам'ять не буде звільнена. Це значення за замовчуванням для SDI-вікон. За закриття вони просто ховаються, але не знищуються, тому їх досить створити тільки один раз, і можна потім викликати скільки завгодно раз;
- caMinimize - не закривати, а тільки мінімізувати вікно. Саме це значення використовується за умовчанням для дочірніх вікон в MDI-додатках.
Ось тепер наше додаток готове.
Як бачите, для різних типів додатків використовується один і той же тип вікна TForm, що дуже зручно. Але ви повинні пам'ятати, що TForm може працювати трохи по-різному, і враховувати це при написанні реальних додатків.
Наостанок розглянемо кілька корисних властивостей і методів форми, приклади яких вже реалізовані в розглянутих вище програмах.
- ActiveMDichild - вказує на активне дочірнє вікно.
- MDichiidCount - ціле число, яке вказує на кількість дочірніх вікон.
- MDichiidren - через це властивість можна отримати доступ до будь-якого дочірньому вікна.
Наприклад, друге вікно можна отримати за допомогою MDichiidren [2]. Припустимо, вам треба змінити заголовок активної дочірньої форми. Як дізнатися,
яка з них активна, коли їх кілька? Дуже просто. Створіть в головній формі кнопку і за її натисканні напишіть:
procedure TMainForm.ButtonlClick (Sender: TObject); begin
ActiveMDIChild.Caption: = 'Активне дочеренее вікно';
У цьому коді ми змінюємо властивість caption активної форми. Якщо немає активної дочірньої форми (буває, коли дочірніх форм взагалі немає), то властивість
ActiveMDIChild одно nil.
Давайте спробуємо змінити заголовки всіх дочірніх вікон. Для цього запустимо цикл від 0 до MDichiidcount і змінимо все заголовки:
for i: = 0 to MDIChildCount-1 do MDichiidren.Caption: = 'Новий заголовок';
Є ще кілька цікавих методів.
- Arrangeicons - вибудувати іконки всіх дочірніх вікон.
- Cascade - вибудувати каскадом всі дочірні вікна.
- Next - наступне дочірнє вікно.
- Previous - попереднє дочірнє вікно.
- Tile - теж вибудувати дочірні вікна, тільки мозаїкою.
Зверніть увагу, що MDI-вікно ми не відображаємо. Воно саме показується на екрані, а ми тільки викликаємо конструктор для створення нового екземпляра. Чому? Подивіться на властивість visible у дочірнього вікна. Зверніть увагу, що воно дорівнює true. Коли це властивість одно true, то вікно мабуть і має відобразитися на екрані, а коли ми змінюємо властивість Formstyle на fsMDichild, то властивість visible теж автоматично стає рівним true.
Враховуйте цей нюанс. Якщо ви випадково зробили вікно дочірнім, а потім поміняли назад на fsNormal, то після запуску це вікно відразу ж відобразиться на екрані (якщо форма в списку автоматично створюваних), тому що властивість visible залишиться рівним істині.