Ієрархія класів MFC
Бібліотека MFC містить велику ієрархію класів, написаних на С ++. Структура ієрархії приведена на рис. 1. В її вершині знаходиться клас СObject, який містить різні функції, використовувані під час виконання програми і призначені, зокрема, для надання інформації про поточний типі під час виконання, для діагностики, і для серіалізациі.
Для отримання відомостей про часу виконання
діагностика
Кожен клас, похідний від CObject, може за запитом перевірити свій внутрішній стан і видати діагностичну інформацію. Це інтенсивно використовується в MFC при налагодженні.
Серіалізация
Серіалізация - це механізм, що дозволяє перетворити поточний стан об'єкта в послідовний потік байт, який зазвичай потім записується на диск, і відновити стан об'єкта з послідовного потоку, зазвичай при читанні з диска. Це дозволяє зберігати поточний стан програми на диску, і відновлювати його при наступному запуску.
Основні класи
Деякі класи породжуються безпосередньо від CObject. Найбільш широко використовуваними серед них є CCmdTarget, CFile, CDC, CGDIObject і CMenu. Клас ССmdTarget призначений для обробки повідомлень. Клас СFile призначений для роботи з файлами. Клас CDC забезпечує підтримку контекстів пристроїв. Про контекстах пристроїв ми будемо говорити трохи пізніше. У цей клас включені практично всі функції графіки GDI. CGDIObject є базовим класом для різних DGI-об'єктів, таких як пір'я, кисті, шрифти та інші. Клас СMenu призначений для маніпуляцій з меню. Від класу CCmdTarget породжується дуже важливий клас CWnd. Він є базовим для створення всіх типів вікон, включаючи масштабовані ( "звичайні") і діалогові, а також різні елементи управління. Найбільш широко використовуваним похідним класом є CFrameWnd. Як Ви побачите надалі, в більшості програм головне вікно створюється за допомогою саме цього класу.
Від класу CCmdTarget, через клас CWinThread, породжується, напевно, єдиний з найбільш важливих класів, звернення до якого в MFC-програмах відбувається безпосередньо: CWinApp. Це один з фундаментальних класів, оскільки призначений для створення самого додатка. У кожній програмі є один і тільки один об'єкт цього класу. Як тільки він буде створений, додаток почне виконуватися.
Функції-члени в MFC
Більшість функцій, що викликаються в MFC-програмою, є членами одного з класів, визначених у бібліотеці. Більшість функцій API доступні через функції-члени MFC. Тим не менш, завжди можна звертатися до функцій API безпосередньо. Іноді це буває необхідним, але все ж в більшості випадків зручніше використовувати функції-члени MFC.
Глобальні функції в MFC
У бібліотеці є ряд глобальних функцій. Всі вони починаються з префікса Afx. (Коли MFC тільки розроблялася, то проект називався AFX, Application Framework. Після низки суттєвих змін AFX була перероблена в MFC, але колишня назва збереглося в багатьох ідентифікатори бібліотеки і в назвах файлів.) Наприклад, дуже часто використовується функція AfxMessageBox (), що відображає заздалегідь певне вікно повідомлення. Але є і член-функція MessageBox (). Таким чином, часто глобальні функції перекриваються функціями-членами.
файл AFXWIN.H
Все MFC-програми включають заголовки AFXWIN.H. У ньому, а також в різних допоміжних файлах, містяться описи класів, структур, змінних і інших об'єктів MFC. Він автоматично підключає більшість заголовків файлів, що відносяться до MFC, в тому числі і WINDOWS.H, в якому визначені всі функції Windows API та інші об'єкти, які використовуються при традиційному програмуванні на С і "чистому" API.
Каркас MFC-програми
Тепер ми створимо за допомогою MFC невеликий додаток. Воно тільки відображає стандартне вікно Windows, і більше нічого не робить. При закритті вікна додаток завершується. Ця програма стане основою для всіх інших додатків, які ми будемо розглядати.
У найпростішому випадку програма, написана за допомогою MFC, містить два класи, що породжуються від класів ієрархії бібліотеки: клас, призначений для створення додатка, і клас, призначений для створення вікна. Іншими словами, для створення мінімальної програми необхідно породити один клас від CWinApp, а інший - від CFrameWnd. Ці два класи обов'язкові для будь-якої програми.
Крім створення вищезазначених класів, в програмі також повинна бути організована обробка всіх повідомлень, що надходять від Windows. В даному прикладі програма ще нічого корисного не робить, тому відповідати на кожне повідомлення не потрібно. MFC обробить всі повідомлення, які нас не цікавлять. Проте в цьому прикладі присутній карта відгуків на повідомлення, або просто карта повідомлень. Пізніше ми розглянемо її детальніше.
Нижче наведено вихідний код програми. Ми завжди будемо розміщувати декларації класів і їх реалізацію в окремі файли. Це відповідає прийнятій практиці програмування на С ++.
Вихідні тексти прикладу
Мал. 2. Вікно, створене найпростішим додатком на MFC
Результат виконання програми показаний на рис. 2. Розглянемо програму докладніше.
Для створення стандартного вікна в додатку повинен успадковуватися клас від CFrameWnd. В даному прикладі він називається CMainWin. Він містить конструктор і макрос DECLARE_MESSAGE_MAP (). Макрос насправді розгортається в декларацію карти повідомлень, яка визначає, яка член-функція класу повинна викликатися у відповідь на повідомлення Windows. Цей макрос застосовується для будь-якого вікна, в якому обробляються повідомлення. Він повинен бути останнім у декларації класу.
Саме вікно створюється в конструкторі за допомогою виклику функції Create (). Ця функція використовується майже у всіх додатках. Вона виконує дії по створенню вікна. У цьому прикладі наведено найпростіший випадок її використання. Поки нам потрібно знати, що другий параметр визначає заголовок вікна, а перший найчастіше дорівнює NULL.
клас CApp
додатки породжується від CWinApp. Цей клас відповідає за роботу програми. У прикладі використовується член-функція з наступним прототипом: Це віртуальна функція, яка викликається кожен раз при запуску програми. У ній буде вся дії, пов'язані з ініціалізацією програми. Функція повинна повертати TRUE при успішному завершенні і FALSE в іншому випадку. У нашому випадку, в функції спочатку створюється об'єкт класу CMainWin, і покажчик на нього запам'ятовується у змінній m_pMainWnd. Ця змінна є членом класу CWinThread. Вона має тип CWnd * і використовується майже в усіх MFC-програмах, тому що містить покажчик на головне вікно. У наступних двох рядках через неї викликаються функції-члени вікна. Коли вікно створено, викликається функція c прототипом: Параметр визначає, яким чином вікно буде показано на екрані. Найбільш поширені значення наступні:
Вікно приводиться до нормального розміру
При першому виклику в якості першого параметра функції можна підставити член m_nCmdShow, в якому зберігається значення коду відображення вікна, передане в програму при запуску (наприклад, в ярлику Windows 95 користувач може визначити, як показувати вікно при запуску програми).
Функція UpdateWindow () посилає вікна повідомлення про те, що його вміст потрібно перемалювати. Надалі ми розглянемо цей процес докладніше.
В кінці програми поміщена реалізація карти повідомлень:
Перший макрос завжди має два параметри, перший - клас вікна, другий - клас, від якого породжений клас вікна. В даному прикладі карта повідомлень порожня, то є всі повідомлення обробляє MFC.
У прикладі була використана функція Create (), яка насправді має багато параметрів. Її прототип такий:
Перший параметр, ClassName, визначає ім'я класу вікна для віконної підсистеми Windows. Зазвичай його не потрібно явно задавати, так як MFC виконує всю необхідну чорнову роботу. У даних методичних вказівках ми не будемо використовувати своїх класів вікон. Параметр Style задає стиль вікна. За замовчуванням створюється стандартне перекривається вікно. Можна задати свій стиль, об'єднавши за допомогою операції "або" кілька констант з наведених нижче:
Вертикальна смуга прокрутки
Надалі ми не будемо так докладно розписувати тут всі можливі значення констант, тому що завжди можна звернутися до довідки Visual C ++ і отримати докладну інформацію.
Початкове положення і розмір вікна визначаються параметром XYSize. Це структура, яка визначає екранні координати лівого верхнього і правого нижнього кута прямокутника, в якому буде відображено вікно.
Всі інші параметри, які ми будемо використовувати, будуть розглянуті у відповідних розділах.