Технологии программирования. Программирование графических интерфейс
.pdf}
afx_msg void OnLButtonDown(UINT, CPoint); DECLARE_MESSAGE_MAP()
};
После определения класса запишем
BEGIN_MESSAGE_MAP(CMyMainWnd, CFrameWnd) ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
И, наконец, в конце файла добавим строки: CMyApp theApp;
void CMyMainWnd::OnLButtonDown(UINT nFlags,
CPoint point){
AfxMessageBox("Левая кнопка мыши");
}
Функции с префиксом Afx определены в MFC как глобальные.
12.Откомпилируем и выполним приложение. При нажатии левой кнопки мыши в окне появляется MessageBox с надписью «Левая кнопка мыши».
13.Нарисуем что-нибудь в окне. Когда окну надо что-либо перерисовать, оно получает сообщение WM_PAINT. Для рисования надо написать обработчик для этого события.
Внесем объявление функции – обработчика события WM_PAINT в класс окна:
class CMyMainWnd : public CFrameWnd{
...
afx_msg void OnLButtonDown(UINT, CPoint); afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
};
Затем добавим макрос в карту сообщений: BEGIN_MESSAGE_MAP(CMyMainWnd, CFrameWnd)
...
ON_WM_PAINT()
61
END_MESSAGE_MAP()
И, наконец, пишем реализацию нашей функции: void CMyMainWnd::OnPaint(){
CPaintDC* pDC=new CPaintDC(this); pDC->Rectangle(5,5,50,50);
}
Откомпилируем и выполним программу. В левом углу должен появится квадратик (рис. 3.7).
Рис. 3.7
14. Добавим в программу обработку таймера, то есть со-
бытия WM_TIMER.
Для этого, во-первых, создадим таймер. В конструктор класса CMyMainWnd добавим следующий код:
CMyMainWnd(){ Create(NULL,"My title");
SetTimer(1, 1000, NULL);
}
Во-вторых, напишем обработчик события WM_TIMER. Для этого следует сделать три действия: добавить соот-
ветствующий метод в класс, написать его реализацию и добавить соответствующий макрос в карту сообщений.
Добавим метод в класс:
...
afx_msg void OnPaint(); afx_msg void OnTimer(UINT);
DECLARE_MESSAGE_MAP()
62
Напишем реализацию этого метода:
void CMyMainWnd::OnTimer(UINT nIDEvent){ MessageBeep(-1);
}
В-третьих, добавим макрос:
...
ON_WM_PAINT()
ON_WM_TIMER()
END_MESSAGE_MAP()
15.Выполним программу. Каждую секунду должен издаваться звук beep.
16.Поскольку таймер – системный ресурс, в конце программы его надо удалить. Для этого внесем в окна класс код для деструктора:
~CMyMainWnd(){
KillTimer(1);
}
17. Заставим программу работать одновременно с двумя таймерами. Добавим в программу ещё один таймер и сразу пишем код в деструкторе класса для уничтожения нового таймера:
CMyMainWnd(){ Create(NULL,"My title"); SetTimer(1, 1000, NULL);
SetTimer(2, 3000, NULL);
}
~CMyMainWnd(){
KillTimer(1);
KillTimer(2);
}
Идентификатор нового таймера 2, он тикает один раз
втри секунды.
18.Отдельный обработчик для второго таймера писать не надо, а изменим обработчик для таймера следующим образом:
63
void CMyMainWnd::OnTimer(UINT nIDEvent){ if(nIDEvent==1)
MessageBeep(-1); else
SetWindowText("Title");
}
У метода OnTimer есть параметр типа UINT. Это идентификатор таймера, для которого обрабатываем сообщение WM_TIMER. Если сообщение поступило от первого таймера, то издаём сигнал,
аесли отвторого, томеняем заголовок окна на «Title».
19.Выполняем программу. Звук раздается один раз в секунду, ичерез трисекундызаголовок окнаменяется.
20.Изменяем интервал у таймера, т.е. сделаем, чтобы сначала он тикал с одной частотой, а затем с другой. Частота должна меняться по щелчку правой кнопки мыши.
Принцип здесь простой: сначала надо убить старый таймер, а затем создать новый с таким же идентификатором.
Для этого напишем обработчик события WM_RBUTTONDOWN, откомпилируем ивыполним программу.
3.6.Упражнения
1.Написать приложение, рисующее в окне различные графические фигуры (окружность, эллипс, прямоугольник, квадрат, сектор, сегмент) в ответ на нажатия клавиш «1», «2», «3», «4», «5», «6» соответственно. Каждую фигуру закрасить своим цветом.
2.Написать приложение, выводящее в центре окна текст различным шрифтом (меняется имя шрифта, размер, цвет, начертание символов) в ответ на нажатия клавиш «1», «2», … и т.д. (всего 9 различных стилей).
3.Написать приложение, рисующее в окне различные графические фигуры (окружность, эллипс, прямоугольник,
64
квадрат, сектор, сегмент) с поясняющей надписью (название фигуры). Фигуры выводятся по сигналу от таймера с заданной частотой. По каждому следующему сигналу таймера изображение на экране (фигуры) меняется.
4.То же, что и 3, но можно изменять частоту таймера при нажатии клавиши «↑» (увеличить), «↓» (уменьшить).
5.Использовать для регистрации класса окна функцию
AfxRegisterWndClass().
65
4. ПРОГРАММИРОВАНИЕ ЭЛЕМЕНТОВ УПРАВЛЕНИЯ
4.1. Элементы управления
Библиотека MFC предоставляет набор классов, которые облегчают создание стандартных элементов управления Windows. Это следующие классы:
CStatic – статический текст или изображение, CButton – командные кнопки, переключатели и флажки,
CListBox – список,
CComboBox – комбинированный список, CEdit – окно редактирования, CScrollBar – полоса прокрутки.
Класс CStatic позволяет выводить на экран текстовые строки, различные закрашенные прямоугольники, значки, курсоры, битовые массивы и расширенные метафайлы.
BOOL Create(LPCTSTR lpszText, DWORD dwStyle, const
RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff);
lpszTex – текст, который должен быть помещен в элемент. dwStyle – стиль элемента. Задается константами вида
WS_XXXX и SS_XXXX.
rect – задает положение и размер элемента управления. Это может быть структура типа RECT или объект класса CRect. pParentWnd – задает родительское окно. Обычно это объ-
ект CDialog.
nID – идентификатор элемента управления.
Класс CButton – это кнопка, которая предоставляет пользователю возможность инициировать определенные приложением действия или позволяет осуществлять выбор. Кнопки могут использоваться по отдельности или группами, могут быть с нанесенным изображением или без него. Типичные примеры кнопок – это
66
командные кнопки (PUSHBUTTON), флажки (CHECK_BOX),
переключатели (RADIOBUTTON). Класс CButton позволяет создать любую из них, задав нужный стиль кнопки в функции
Create().
BOOL Create( LPCTSTR lpszCaption, DWORD dwStyle,
const RECT& rect, CWnd* pParentWnd, UINT nID );
Назначение параметров то же, что и для CStatic. Стиль задается константами с префиксом WS_ и BS_.
Класс CEdit позволяет создавать такой элемент управления Windows, как окно редактирования, которое является простейшим текстовым редактором. Использую CEdit, можно создавать как многострочный редактор текста, так и просто поле для ввода текста.
BOOL Create( DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, UINT nID );
Назначение параметров то же, что и для CStatic. Стиль задается константами с префиксом ES_ и WS_.
Класс CListBox – это список, который представляет собой прямоугольник, внутри которого находится последовательность текстовых или пользовательских элементов, которые пользователь может пролистывать и выбирать. Можно создавать списки, позволяющие выбирать только одну запись (элемент) или несколько одновременно. Когда выбирается элемент в списке, он выделяется и окно-список посылает родительскому окну сообщение. Вообще, список может посылать несколько сообщений родительскому окну. Для них всех предусмотрены специальные макросы, позволяющие добавить в карту сообщений функции обработки. Эти макросы имеют префикс ON_LBN_.
Стиль кнопки задается константами с префиксом LBS_
и WS_
67
Класс CComboBox представляет собой комбинацию окна списка и окна редактирования. Часть комбинированного списка– непосредственно список – может выводиться на экран все время (стиль CBS_SIMPLE) или может как бы раскрываться из поля редактирования (CBS_DROPDOWN и CBS_DROPDOWNLIST).
Текущая выбранная запись выводится в окне редактирования и может быть как доступна (CBS_SIMPLE и CBS_ DROPDOWN),
такинедоступна(CBS_DROPDOWNLIST) дляредактирования. Ниже приводятся некоторые полезные функции – члены
классов.
CListBox и CComboBox.
int AddString( LPCTSTR lpszItem );
Добавляет строку в список и возвращает индекс новой строки в списке. Если список не имеет стиля LBS_SORT, то строка будет добавлена в конец списка.
int InsertString( int nIndex, LPCTSTR lpszItem );
Вставляет строку в позицию nIndex.
int DeleteString( UINT nIndex );
Удаляет из списка элемент в позиции nIndex и возвращает число оставшихся в списке элементов,
void ResetContent( );
Удаляет все элементы из списка:
int FindString( int nStartAfter, LPCTSTR lpszItem ) const;
Ищет строку в списке, начиная поиск после строки с индексом nStartAfter. Возвращает индекс найденной строки или LB_ERR в случае неудачи.
int SelectString( int nStartAfter, LPCTSTR lpszItem ) const;
То же, что и предыдущая функция. Кроме того, выделяет найденную строку.
int GetCount( ) const;
Возвращает количество элементов в списке.
Библиотека MFC предоставляет удобное средство для работы со строками. Строки CString состоят из символов типа
68
TCHAR. Если символ _UNICODE не определен, TCHAR соответствует типу char. Строки CString автоматически расширяются и сокращаются в зависимости от фактической длины строки.
В классе CString определены методы, выполняющие все основные операции над строками – копирование, сравнение, присваивание.
Строки CString можно использовать совместно со строками языка Си. Вы можете применять объекты класса CString как строки Си, можете их использовать в качестве параметров функций, которые принимают параметры типа const char* или
LPCTSTR.
4.2. Создание простого SDI-приложение
Например, надо разработать приложение, которое создает окно следующего вида (рис. 4.1).
Рис. 4.1
69
В окне размещаются четыре кнопки CButton, окно редактирования CEdit, список № 1 CListBox , список № 2 CComboBox и три текста CStatic («Список № 1», «Список № 2», «Строка ввода»).
При нажатии кнопки «Переместить» в списке CListBox последняя строка перемещается в начало списка.
При нажатии кнопки «Добавить» выделенная в списке CListBox строка добавляется в список CComboBox. То же самое происходит при двойном щелчке левой кнопкой мыши на строке в списке CListBox.
При нажатии кнопки «Ввести» строка, введенная в CEdit, добавляется в список CListBox.
При нажатии кнопки «Очистить» CListBox очищается. Любой стандартный элемент управления можно создать
двумя способами: в редакторе ресурсов; прямо в исходном тексте приложения.
Будем создавать элемент управления в исходном тексте приложения.
Как и другие объекты классов библиотеки MFC, инкапсулирующие визуальные объекты Windows, элементы управления создаются в два этапа: сначала необходимо создать объект данного класса, а затем вызвать функцию – член класса Create для создания соответствующего элемента управления Windows и связывания его с созданным объектом класса. Для обычного окна это делается в функции OnCreate().
Если элемент управления создается в блоке диалога, он автоматически уничтожается, когда пользователь закрывает диалоговое окно. Если элемент управления создается программно внутри окна, то его необходимо уничтожить. Если он был создан с помощью new, то, соответственно, необходимо выполнить delete для уничтожения объекта.
70