- •2. Призначення mfc. Ієрархія класів mfc (картинка иерархии http://realcoding.Net//images/mfc/gl1-5.Jpg). Спеціальні типи даних.
- •3. Організація простої mfc-програми (класи, функції). Послідовність роботи програми.
- •4. Організація обробки повідомлень. Приклади обробки повідомлень.
- •7. Створення головного меню програми (робота у редакторі ресурсів, варіанти підключення).
- •8. Поняття контексту пристрою. Застосування контекстів пристрою. Обробка повідомлення wm_paint.
- •11. Використання меню та акселераторів. Обробка пунктів меню.
- •12. Діалогові вікна модального та немодального типів. Реалізація класів. Особливості конструкторів. Приклади .
- •16. Смуги прокручування та обробка їх повідомлень. Полосы прокрутки
- •19. Встановлення та отримання характеристик тексту. Системні та логічні шрифти.
- •20. Особливості використання системних шрифтів.
- •21. Особливості використання логічних шрифтів.
- •30. Відображення рухомих об’єктів у mfc-програмах.
3. Організація простої mfc-програми (класи, функції). Послідовність роботи програми.
В простейшем случае программа, написанная с помощью MFC, содержит два класса, порождаемые от классов иерархии библиотеки: класс, предназначенный для создания приложения, и класс, предназначенный для создания окна. Другими словами, для создания минимальной программы необходимо породить один класс от CWinApp, а другой - от CFrameWnd. Эти два класса обязательны для любой программы.
simpwin.hpp
#include <afxwin.h> // Класс основного окна приложения
class CMainWin: public CFrameWnd {
public:
CMainWin(); // Декларирование карты сообщений
DECLARE_MESSAGE_MAP()
}; // Класс приложения. Должен существовать только один экземпляр этого класса. Член-функция InitInstance() вызывается при запуске приложения.
class CApp: public CWinApp {
public:
BOOL InitInstance();
};
simpwin.cpp
#include <afxwin.h>
#include <string.h>
#include "SIMPWIN.HPP" // Создание одного и только одного экземпляра приложения
CApp App;
// Реализация
BOOL CApp::InitInstance()
{ // Создание главного окна приложения и его отображение.Член CApp::m_pMainWnd - это указатель на объект главного окна. m_pMainWnd = new CMainWin;
m_pMainWnd->ShowWindow(SW_RESTORE);
m_pMainWnd->UpdateWindow();
// Сигнализируем MFC об успешной инициализации
// приложения.
return TRUE;
}
CMainWin::CMainWin()
{
// Создание окна с заголовком. Используется
// встроенный в MFC
// класс окна, поэтому первый параметр 0.
this->Create(0, "Простейшее приложение на MFC");
}
// Реализация карты сообщений
BEGIN_MESSAGE_MAP(CMainWin /*класс окна*/, CFrameWnd
/*класс-предок*/)
END_MESSAGE_MAP()
4. Організація обробки повідомлень. Приклади обробки повідомлень.
В MFC включен набор предопределенных функций-обработчиков сообщений, которые можно использовать в программе. Если программа содержит такую функцию, то она будет вызываться всякий раз, когда поступает связанное с ней сообщение. При наличии дополнительной информации в сообщении она передается в качестве аргументов функции. Для организации обработки сообщений нужно выполнить следующие действия: В карту сообщений программы должна быть включена команда соответствующего сообщения. Прототип функции-обработчика должен быть включен в описание класса, ответственного за обработку данного сообщения. В программу должна быть включена реализация функции-обработчика.
КОНСПЕКТ: Обработка сообщений MFC программ. При помощи обработки сообщений определяется реакция программы на действие пользователя, на системные события и на события других программ. WM_MOVE - окно сдвинуто. WM_CLOSE - должно быть закрыто. WM_SIZE - сообщение об изменении размера окна. WM_COMMAND - выбран элемент WM_TIMER WM_MOUSEMOVE WM_LBUTTONDOWN WM_MOUSEWHELL. Для обработки сообщений в MFC-программе создается карта сообщений. А в более ранних версиях - при помощь оператора switch. Для обработки сообщений в классе окна объявляется карта сообщений: class CMainWin: public CFrameWnd {public: CMainWin(); DECLARE_MESSAGE_MAP()}; //App.cpp BEGIN_MESSGE_MAP (CMainWin (класс владельца КС), CFrameWnd (родитель владельца)) Для обработки сообщений в карту сообщений записываются макрокоманды
5. Обробка повідомлень WM_CHAR, WM_PAINT.
WM_CHAR - нажата кнопка на клавиатуре. WM_PAINT - необходимо обновление окна.
Пример обработчика нажатия клавиш клавиатуры
char str [80]; // строка символов для вывода
void CMainWin::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{CClientDC dc(this); // получение контекста окна
dc.TextOut(1,1," ", 3); // удаление старого текста
wsprintf(str,"%с", ch); // формирование строки с кодом клавиши
dc.TextOut(1, 1, str, strlen(str)); } // вывод строки в координату (1, 1)
Таким образом, каждый раз, когда необходимо вывести информацию в рабочую область окна, необходимо получить контекст устройства с помощью CClientDC. Частным случаем является применения сообщения WM_PAINT.
Для обновления содержимого рабочего окна программы необходимо отослать сообщение WM_PAINT. Вне его применения содержимое окна может не отображаться. Т.е. каждый раз, когда есть потребность выводить информацию в окно программы, следует обращаться к этому сообщению.
Сообщению WM_PAINT отвечает макрокоманда ON_WM_PAINT(), а макрокоманде – обработчик OnPaint(). Этот обработчик может выглядеть следующим образом:
Пример обработчика сообщения WM_PAINT
void CMainWin::OnPaint()
{CPaintDC dc(this); // получение контекста окна
dc.TextOut(1,1, str, strlen(str));} // отображение символа
В примере приведен обработчик OnPaint(), который обеспечивает вывод на экран символа, введенного с клавиатуры пользователем соответственно обработчику OnChar(), записанному в предыдущем примере. Видно, что для получения контекста устройства здесь использован объект другого типа, а именно CPaintDC. В отличие от CClientDC, который работает только с клиентской частью окна программы, CPaintDC обеспечивает роботу со всей плоскостью окна.
В программе желательным было бы, чтобы Windows самостоятельно решала, когда ей вызвать сообщение WM_PAINT. Это так и происходит, например, когда пользователь программы минимизирует окно, максимизирует, движет экраном, изменяет размеры окна и т.п.. Но иногда необходимо проводить обновление окна принудительно. Для того, чтобы прислать сообщение WM_PAINT, программа вызывает функцию InvalidateRect() – член класса CWnd, которая имеет следующий прототип:
void CWnd::InvalidateRect(LPCRECT lpRegion, BOOL Erase=TRUE);
где lpRegion – указатель на область окна, которую необходимо обновить, Erase – флаг, который в значении TRUE устанавливает изъятие предыдущего содержимого окна. Если указать первому параметру значения NULL, произойдет полное обновление окна. Вызов функции InvalidateRect() обеспечивает принудительную посылку сообщения WM_PAINT и выполнение обработчика OnPaint().
Полное обновление окна, как например:
InvalidateRect(NULL);
занимает много ресурсов системы, которая визуально может выглядеть мерцанием рабочего окна программы. Этого можно избегнуть, задав отдельно область обновления, например:
СRect region(10,10,100,100);
InvalidateRect(region);
в таком случае будет обновляться лишь область, ограниченная прямоугольником с левым верхним углом (10,10) и нижним правым углом (100,100). Такой вариант обновления становится особенно интересным, если необходимо обеспечить подвижность отдельных элементов окна, а этого можно достичь с одновременным применением обработки сообщения таймера WM_TIMER.
6. Обробка повідомлень WM_LBUTTONDOWN, WM_RBUTTONDOWN.
Рассмотрим программу, которая реагирует на нажатие левой и правой кнопок мыши в клиентской области окна, а также на нажатие клавиш. При нажатии левой кнопки в клиентскую область окна, начиная с текущих координат курсора мыши, выводится строка "Нажата левая кнопка", а при нажатии правой кнопки - "Нажата правая кнопка".
При нажатии на левую и правую кнопки соответственно генерируются сообщения WM_LBUTTONDOWN и WM_RBUTTONDOWN, и им соответствуют обработчики с прототипами:
afx_msg void OnLButtonDown(UINT Flags, CPoint Loc);
afx_msg void OnRButtonDown(UINT Flags, CPoint Loc);
Первый параметр указывает на то, была ли при генерации сообщения нажата какая-нибудь клавиша или кнопка мыши. Этот параметр нас не будет пока интересовать. Второй параметр определяет координаты курсора мыши во момент нажатия кнопки. Класс CPoint порождается от структуры POINT, определенной так:
typedef struct tagPOINT {
LONG x;
LONG y;
} POINT;
Таким образом, мы легко можем определить координаты для вывода текстовой строки.
Обработчик сообщения WM_CHAR имеет прототип:
afx_msg void OnChar(UINT Char, UINT Count, UINT Flags);
Нас здесь будет интересовать только первый параметр. Он представляет собой ASCII-код символа, соответствующего нажатой клавише. При нажатии несимвольных клавиш сообщение WM_CHAR не посылается.