- •О.С. Зеленський
- •Розділ 1. Загальні відомості створення додатку windows
- •1.1. Створення додатку Windows за допомогою майстра AppWizard
- •1.2. Варіанти майстрів для різних проектів
- •1.3. Короткий опис sdi програми
- •1.4. Короткий опис mdi програми
- •1.5. Короткий опис простого діалогового додатку
- •Контрольні питання
- •Розділ 2. Повідомлення і команди
- •2.1. Обробка повідомлень
- •2.2. Цикли обробки повідомлень
- •2.3. Карти повідомлень
- •Контрольні питання
- •Розділ 3. Документи та види
- •3.1. Клас додатку
- •3.2. Клас головного вікна
- •3.3. Клас документа
- •3.4. Класи виду
- •Контрольні питання
- •Розділ 4. Робота з клавіатурою, мишею і меню
- •4.1. Робота з клавіатурою
- •4.2. Робота з мишею
- •4.3. Робота з меню
- •Контрольні питання
- •Розділ 5. Виведення на екран
- •5.1. Класи графічних об'єктів
- •5.2. Робота зі шрифтами
- •5.3. Робота з пензликами та малювання графічних фігур
- •5.4. Робота з пензликом
- •5.5. Робота зі скролінгом
- •5.6. Приклад роботи з таблицями
- •5.7. Малювання на екрані маніпулятором "миша"
- •5.8. Завантаження та виведення на екран бітових зображень
- •5.9. Копіювання бітових образів
- •5.10. Малювання графічних об'єктів з використанням резинових контурів та метафайлів
- •5.11. Виділення графічних об'єктів у прямокутній області
- •5.12. Універсальний приклад роботи з двовимірною графікою з використанням резинового контуру
- •5.13. Запис на диск та зчитування з диску графічних об'єктів
- •5.14. Побудова кругових діаграм і гістограм
- •5.15. Користувацький режим роботи з графікою на прикладі малювання годинника Clock
- •Контрольні питання
- •Завдання
- •Розділ 6. Друк і попередній перегляд документів
- •6.1. Вибір і налаштування параметрів друку
- •6.2. Створення контекста пристрою
- •6.3. Друк документів і бібліотека mfc
- •6.4. Масштабування
- •6.5. Друк багатосторінкового документа
- •Контрольні питання
- •Розділ 7. Робота з файлами
- •7.1. Приклад роботи з файлами на основі класів cFile, cStdioFile та потоку fstream
- •7.1.1. Робота з класом cFile
- •7.1.2. Робота з потоком fstream
- •Можливі режими доступу
- •7.1.3. Робота з класом cStdioFile
- •7.2. Серіалізація даних, клас cArchive
- •7.3. Використання реєстру в додатках
- •Контрольні питання
- •Завдання
- •Розділ 8. Діалогові вікна
- •8.1. Створення діалогового вікна та простіші елементи керування
- •8.2. Робота зі списками і комбінованими полями
- •8.3. Ускладнений приклад зі списками
- •8.4. Робота з повзунками
- •8.5. Виведення бітових матриць в діалозі та у вікні виду
- •8.6. Лінійний регулятор, лінійний індикатор, інкриментний регулятор
- •8.7. Стандартні діалоги вибору файлів, шрифтів та кольору
- •8.8. Взаємоз'вязок діалога, документа та виду при розробці додатку
- •8.8.1. Клас cDialDoc
- •8.8.2. Клас cDialView
- •8.8.3. Клас Cdlg
- •8.9. Формування вхідного документа на основі діалогу
- •Контрольні питання
- •Завдання Робота з типовими елементами керування
- •Робота зі списками і комбінованими полями
- •Список літератури
2.3. Карти повідомлень
Використання карти повідомлень (Message maps) лежить в основі підходу, який реалізується в MFC для програмування Windows-додатків. Суть його полягає в тому, що від розробника потрібно тільки написати функції обробки повідомлень і включити в свій клас карту повідомлень, яка фактично скаже: "Я буду обробляти таке-то повідомлення". Після цього головна програма буде відповідати за те, щоб повідомлення було передано саме тій функції, яка буде його обробляти. В результаті виключається необхідність розробляти функцію WinMain(), яка повинна була б передавати повідомлення іншій функції - WndProc() (її також потрібно було б розробити), а остання повинна була б аналізувати повідомлення і викликати відповідну функцію обробки.
Порада. Якщо вам доводилося працювати з Visual Basic, то ви напевно знайомі з такими процедурами обробки подій (event procedure), як, наприклад, "клацання мишею". Функція обробки повідомлення в програмі на C++ відіграє ту ж роль, як і процедура обробки події. Карта повідомлень - це спосіб зв'язати подію з його обробником.
Карта повідомлень складається з двох частин: одна - у файлі заголовка для класу .h, а інша - у відповідному файлі реалізації .срр. Вони, як правило, формуються майстрами, хоча в деяких випадках ви можете зробити це (чи частково відредагувати їх) і самостійно. Наведемо частину тексту файлу заголовка одного з класів простого додатка ShowString:
//{{AFX_MSG(CShowStringApp)
afx_msg void OnAppAbout();
// УВАГА!! Тут ClassWizard буде додавати і
// видаляти функції-члени.
// не редагуйте текст у цих блоках!
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
Тут оголошується функція OnAppAbout(). Спеціальним чином оформлений коментар дозволяє ClassWizard визначити, які саме повідомлення перехоплюються цим класом. DECLARE_MESSAGE_MAP – це макрос, розширюваний препроцесором компілятора Visual C++, в якому оголошуються змінні і функції, які беруть участь у цьому фокусі з перехопленням повідомлень.
Карта повідомлень у файлі ShowString.срр, також досить проста:
BEGIN_MESSAGE_MAP(CShowStringApp, CWinApp)
//{{AFX_MSG_MAP(CShowStringApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
//}}AFX_MSG_MAP
// Стандартні команди роботи з файлами документів.
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
// Стандартні команди налаштування принтера.
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()
Макроси карти повідомлень
Макроси BEGIN_MESSAGE_MAP і END_MESSAGE_MAP, так само як DECLARE_MESSAGE_MAP у файлі заголовка, оголошують члени (змінні і функції), які програма повинна використовувати для того, щоб розібратися в картах всіх об'єктів системи. Існує досить великий набір макросів, які використовуються для роботи з картою повідомлень. Деякі з них перераховані нижче.
DECLARE_MESSAGE_MAP. Використовується у файлі заголовка для того, щоб оголосити, що у файл тексту програми буде включена карта повідомлень.
BEGIN_MESSAGE_MAP. Визначає-початок карти повідомлень у тексті програми.
END_MESSAGE_MAP. Визначає кінець карти повідомлень у тексті програми.
ON_COMMAND. Використовується для того, щоб перенаправити обробку деякою команди функції-члену класу.
ON_COMMAND_RANGE. Використовується для того, щоб перенаправити обробку групи команд, ідентифікатори яких лежать в заданому діапазоні, однієї функції-члену класу.
ON_CONTROL. Використовується для того, щоб перенаправити обробку коду повідомлення від елемента керування, введеного програмістом, функції-члену класу.
ON_CONTROL_RANGE. Використовується для того, щоб перенаправити обробку групи кодів повідомлень, значення яких знаходяться в заданому діапазоні, однієї функції-члену класу.
ON_MESSAGE. Використовується для того, щоб перенаправити обробку деякого повідомлення, введеного програмістом, функції-члену класу.
ON_REGISTERED_MESSAGE. Використовується для того, щоб перенаправити обробку деякого зареєстрованого повідомлення, введеного програмістом, функції-члену класу.
ON_UPDATE_COMMAND_UI. Використовується для того, щоб перенаправити оновлення, пов'язане із заданою командою, функції-члену класу.
ON_COMMAND_UPDATE_UI_RANGE. Використовується для того, щоб перенаправити однієї і тієї ж функції-члену класу оновлення, пов'язане з групою команд, ідентифікатори яких знаходяться в заданому діапазоні значень.
ON_NOTIFY. Використовується для того, щоб перенаправити функції-члену класу обробку заданого коду повідомлення, який супроводжується додатковими даними від елемента керування.
ON_NOTIFY_RANGE. Використовується аналогічно макросу ON_NOTIFY, але застосовується для групи елементів, повідомлення від яких повинні оброблятися однією і тією ж функцією-членом класу. Група задається інтервалом кодів ідентифікаторів елементів управління, які є дочірніми вікнами по відношенню до того вікна, яке ці повідомлення перехоплює.
ON_NOTIFY_EX. Використовується для того, щоб перенаправити обробку заданого коду повідомлення, супроводжуваного додатковими даними від елемента керування, функції-члену класу. Остання, у свою чергу, повинна повернути TRUE або FALSE з тим, щоб сигналізувати, чи потрібно передавати далі це уточнене повідомлення іншому об'єкту для можливої реакції.
ON_NOTIFY_EX_RANGE. Використовується аналогічно макросу ON_NOTIFY_EX, але застосовується для групи елементів, повідомлення від яких повинні оброблятися однією і тією ж функцією-членом класу. Елементи управління, які передають повідомлення такого формату, є дочірніми вікнами по відношенню до того вікна, яке ці повідомлення перехоплює.
На додаток до перерахованих існує ще близько ста макросів, по одному на кожне стандартне повідомлення, які направляють відповідне повідомлення функції-члена. Наприклад, ON_CREATE направляє повідомлення WM_CREATE функції On_Create(). При користуванні такими макросами не можна змінювати імена функцій. Ці макроси, як правило, включаються в карту повідомлень самим ClassWizard.