Створення програм у середовищі Borland C Builder, Світ ПК, Видавництво «Відкриті системи»
Заняття друге На першому занятті ми познайомилися із створенням обробників повідомлень. Вся концепція Borland C++ Builder побудована розміщення робочого коду всередині обробників. Обробники важкі розуміння тих, хто писав програми для DOS без використання повідомлень.
Заняття друге
На першому занятті ми познайомилися із створенням обробників повідомлень. Вся концепція Borland C++ Builder побудована розміщення робочого коду всередині обробників. Обробники важкі розуміння тих, хто писав програми для DOS без використання повідомлень. У такому разі потрібно уявити електричний провід, яким тече струм до протилежного полюса. Якщо вам потрібно переконатися, що струм по цьому дроту протікає, ви можете розімкнути ланцюг і вставити в нього вимірювальний прилад або, можливо, просту лампочку. Далі ви можете або замкнути інший контакт лампочки на землю, знеструмивши, таким чином, всі інші прилади в ланцюзі, або підключити другий контакт до іншої ділянки ланцюга, дозволивши текти електриці далі і живити інші прилади. Потік повідомлень у програмі, виконаній C++ Builder, схожий на потік електронів. Вони також проходять через ланцюг підпрограм, завершуючи своє існування десь у надрах бібліотеки компонентів VCL. Встановлюючи обробник, ви ніби "врізаєтесь" в потік повідомлень, перехоплюючи його. Тільки на відміну від лампочки в електроланцюзі обробник "інтелектуальний" і забирає ті повідомлення, які призначені йому. Так само за аналогією з електрикою ви або пропускаєте потік повідомлень далі (викликаєте обробник класу-предка), або не пропускаєте (повідомлення оброблювача класу-предка не передається). Якщо не передати повідомлення далі по ланцюжку, можливопорушення нормальної роботи програми із різноманітними ефектами. Щоправда, бібліотека VCL із C++ Builder досить розумна і не допускає таких ситуацій.
У процесі виконання коду компонента, що відповідає за проходження події, VCL визначає, чи є компонент компонент для даної події і, якщо є, викликає його. Це виглядає приблизно так:
Створення обробників подій C++ Builder наполовину автоматизовано. Коли ви хочете створити обробник, ви перемикаєте вікно інспектора об'єктів у режим Events і робите подвійне натискання на назві тієї події, яку ви хочете перехопити. Зверніть увагу на те, що компонент, чию подію ви перехоплюєте, має бути виділено.
Зауваження. Для кожного компонента є так звана подія за умовчанням. Наприклад, для Button це OnClick. Якщо двічі клацнути на компоненті, C++ Builder створить обробник цієї події.
За промовчанням ім'я створюється з імені виділеного компонента та імені події. Наприклад, Button1Click. Префікс On не додається. Але це не означає, що ви повинні використовувати саме це ім'я. Ви можете набрати нове ім'я, яке вам до вподоби, прямо в інспекторі об'єктів.
Після введення нового імені, C++ Builder автоматично замінить назву функції-обробника у вихідному тексті програми.
Насправді те, що відбувається за кадром, дещо складніше. Коли ви створюєте новий обробник, його опис з'являється не тільки в модулі, але і в заголовку цього модуля в секції __published. Саме в цю секцію C++ Builder складає посилання на всі компоненти, що є у вашій формі, та обробники подій. Ось приклад заголовного файлу для програми з однією кнопкою на формі та обробником її натискання. Виділені рядки ілюструють цей підхід.
Але повернемось до самого оброблювача. Як ви самі можете бачити, у нього немає значення, що повертається, і єдиний аргумент Sender - покажчик на компонент, що згенерував подію. У прикладі це буде покажчик на кнопку Button1. Щоб використовувати його, вам потрібно буде привести його до типу кнопки. Це можна зробити двома способами: старим
Зауваження. Якщо ви збережете файл, коли всередині обробника не буде жодних операторів, то порожній обробник буде прибраний автоматично і з файлу модуля, і з файлу заголовка.
Наступна лабораторна робота буде пов'язана з визначенням стандартних подій для різних компонентів. Для цього створіть командою File – New Application нову програму. Кладіть компоненти на форму по одному і робіть на них подвійне клацання мишею. Подивіться, обробник якоїсь події буде згенерований для того чи іншого компонента. Згодом це допоможе вам розробляти нові програми настільки швидко, наскільки це можливо.
Давайте тепер напишемо маленьку програму з типовим обробником повідомлень. Воно перехоплюватиме всі повідомлення від форми та записуватиме їх до списку компонента Memo. Створіть новий проект та додайте до форми компонент Memo. Встановіть його властивість Enabled рівним false, щоб усі натискання на клавіатурі передавалися формі, а чи не цьому компоненту. Залишіть на формі вільне місце, щоб було кудись клацати мишею. Тепер додайте обробники для всіх подій форми, окрім OnDragDrop та OnDragOver - це зовсім окремий предмет для розмови. У кожному обробнику потрібно додати рядок, що виводить рядок тексту з назвою обробленої події. Це виглядає так:
Тут відбувається звернення до властивості Lines компонента Memo. А через одержуваний покажчик на масив рядківвикликається метод Add(), який додає рядок до масиву і відображає його у вікні компонента Memo. Всі обробники схожі як близнюки-брати, крім OnDestroy. До нього додано рядок
яка зберігає весь текст із вікна компонента Memo у файл trace.txt. Це зроблено для того, щоб після завершення програми ви могли розібратися з усіма подіями, навіть із тими, що відбуваються вже тоді, коли форма знищується. Метод SaveToFile() займається збереженням даних.
Повний вихідний текст програми наводиться у лістингу.
Відкомпілюйте та запустіть вашу програму. Посуньте вікно, закрийте і відкрийте його, клацніть мишею. Якщо все правильно, то в компоненті Memo ви отримаєте вичерпну інформацію про перебіг подій. Зверніть увагу, що найпоширеніша подія - OnMouseMove, що говорить про те, що користувач рухає мишу.
У чому користь такої програми? В тому, що вона дає вам можливість докладно дізнатися не тільки, коли виникає та чи інша подія, але і їх послідовність, що важливо, якщо ви хочете отримати безпомилковий код. Якщо вам цікаво, то ви можете розширити обробники, додавши в них рядки для виведення поточних координат миші або літери натиснутих клавіш, благо відповідні параметри обробників миші та клавіатури є.
Повертаючись до доцільності написання таких "тупих" програм. Часто буває зручніше і швидше написати аналогічну маленьку програму для компонента і простежити його події, ніж розумітися на документації і вирішувати, якого події прив'язати той чи інший код. Що я вам і раджу зробити. Ви витратите день, але знімете з порядку денного велику кількість питань.
Ще одна маленька, але дуже зручна можливість надається C++ Builder. Цеприв'язка поділяються обробників подій. Коли у вас є обробник, ви можете використовувати його для кількох подій. Все що потрібно зробити, - в інспекторі об'єктів виділити подію, до якої ви прив'язуєте обробник, і з списку, що розкривається, вибрати відповідну функцію.
На наступному занятті ми з вами розглянемо методику налагодження програм серед C++ Builder. А як домашнє завдання потренуйтеся з обробниками подій для різних компонентів.