Практика работы в среде визуального программирования
Начало работы в Visual C++
Вывод текста в окно программы
Создадим программу, которая будет считать символы с клавиатуры и отображать их в клиентском окне. Для этого будем обрабатывать сообщение Windows WM_CHAR. Свяжем с ним функцию OnChar(UINT nChar, UINT nRepCnt, UINT nFlags ). Назовем программу Key. Будем создавать ее с помощью MFC Application Wizard, интерфейс SDI (Single Document Interface).
Этапы написания программы
- буфер под хранение полученных символов.
- Организовать чтение символов с клавиатуры.
- Сохранить символы в документе.
- Отобразить текст.
1. Подготовка буфера для хранения символов
Определим в классе CKeyDoc, прототип которого содержится в заголовочном файле KeyDoc.h, строку-объект StringData класса MFC CString. Для этого добавим следующий код:
class CKeyDoc : public CDocument
{
……
DECLARE DYNCREATE(CKeyDoc)
Public:
CString StringData;
……
};Проинициализируем переменную пустой строкой " ". Это делается в конструкторе объекта документа, расположенном в файле KeyDoc.cpp. Конструктор объекта документа CKeyDoc:
CKeyDoc::CKeyDoc()
{
// TODO:
StringData="";
}2. Чтение символов с клавиатуры
При нажатии клавиши Windows посылает сообщение WM_CHAR. Его надо связать с методом OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) объекта вида. Для этого используем утилиту Class View
- Вызовем контекстное меню класса CKeyView (нажмем правой кнопкой по имени класса в окне утилиты Class View )
выберем пункт Properties. - Во всплывшем окне свойств нажмем на кнопку Messages.
- Выбираем в списке сообщений WM_CHAR. Раскрываем список действий в пустом поле напротив названия сообщения нажатием левой кнопкой мыши. Выбираем единственный вариант <Add> OnChar. Мастер автоматически создаст обработчик OnChar и откроет файл KeyView.cpp для редактирования тела метода.
3. Сохранение символа в документе
Введенный символ находится в параметре nChar и его необходимо сохранить в строковом объекте StringData. Обработчик OnChar:
void CKeyView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CKeyDoc *pDoc = GetDocument(); //Получение указателя на объект документа
ASSERT_VALID(pDoc); //Проверка указателя
if(!pDoc)
return;
pDoc->StringData += char(nChar); //Обновление строки символов
Invalidate(); //Вызов метода OnDraw
}Макрос ASSERT_VALID проверяет, что полученный указатель действительно ссылается на документ (иначе ошибка).
4. Отображение текста
Вывод будем осуществлять в методе OnDraw(CDC* pDC) класса вида. Для вызова метода OnDraw используется функция Invalidate. Метод OnDraw:
void CKeyView::OnDraw(CDC *pDC)
{
…
pDC->TextOut(0,0,pDoc->StringData);
}Скомпилируем и запустим программу. Усложним задачу. Потребуем, чтобы текст выводился в центре клиентской области окна. Для решения поставленной задачи изменим метод OnDraw. Измененный метод OnDraw:
void CKeyView::OnDraw(CDC* pDC)
{
CKeyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CRect rect; //Переменная для хранения размеров клиентской области
GetWindowRect(&rect); //Получение размеров клиентской области
int x=rect.Width()/2; //Задание координаты X центра клиентской области
int y=rect.Height()/2; //Задание координаты Y центра клиентской области
CSize size = pDC->GetTextExtent(pDoc->StringData); //Определение размеров выводимой строки в пикселях
x -= size.cx/2; //Сдвиг координаты X на половину длины выводимой строки влево
y -= size.cy/2; //Сдвиг координаты Y на половину высоты выводимой строки вверх
pDC->TextOut(x,y,pDoc->StringData); //Вывод строки в центр клиентской области
}Работа с курсором и мышью
Напишем программу, которая будет создавать курсор, в выбранной произвольной точке клиентской области и выводить текст с указанной позиции. Создадим SDI программу под названием Mouse. Воспользуемся материалом предыдущего пункта: создадим обработчик сообщения WM_CHAR. Чтобы создать курсор, необходимо знать его размеры (обычно высота равна высоте символа, а ширина 1/8 ширины символа). Курсор будем создавать в методе OnDraw. Чтобы определить размеры курсора, необходимо получить данные из структуры TEXTMETRIC. Для этого необходимо создать объект типа TEXTMETRIC и заполнить его поля, используя метод GetTextMetrics(&tm) . Но сначала добавим в прототип класса CMouseView следующие переменные
void CMouseView::OnDraw(CDC* pDC)
{
CMouseDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
TEXTMETRIC textmetric; //Переменная для хранения информации о шрифте
pDC->GetTextMetrics(&textmetric); //Получение информации о шрифте
CSize size=pDC->GetTextExtent(pDoc->StringData); //Получение размеров выводимой строки в пикселях
CreateSolidCaret(textmetric.tmAveCharWidth/8,textmetric.tmHeight); //Создаём курсор
CaretPosition.x=size.cx; //Присваивание x корд. конца
CaretPosition.y=0; //Присваивание y корд.
SetCaretPos(CaretPosition); //Задаем позицию курсора
ShowCaret(); //Вывод на экран курсора
pDC->TextOut(0,0,pDoc->StringData);
}Рассмотрим задачу вывода строки с места, на который указывает указатель мыши. Свяжем сообщение WM_LBUTTONDOWN с методом OnLButtonDown(UINT nFlags, CPoint point) . Параметр Cpoint (объект класса CPoint) содержит текущие координаты указателя мыши. Для очистки строкового объекта используется метод Empty() класса CString. Обработчик нажатия левой кнопки мыши OnLButtonDown:
void CMouseView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
x=point.x; //Запоминаем координату X места где была нажата левая кнопка мыши
y=point.y; //Запоминаем координату Y места где была нажата левая кнопка мыши
CMouseDoc* pDoc = GetDocument(); //Получаем указатель на объект документа
ASSERT_VALID(pDoc); //Проверяем правильность указателя
pDoc->StringData.Empty(); //Очищаем выводимую строку
Invalidate(); //Вызываем OnDraw
CView::OnLButtonDown(nFlags, point);
}В методе класса OnDraw сделаем изменения:
CaretPosition.x=x+size.cx; //Присваивание x корд. конца CaretPosition.y=y; …… pDC->TextOut(x,y,pDoc->StringData);
Скомпилируем и запустим приложение.