Шаг 10 - Рисуем в окне

Создание проекта

Изменяем проект. Это очень хороший проект. На нем тренироваться и тренироваться...

Создаем код

Нам необходимо переопределить виртуальную функцию прорисовки экрана. Она реализована в виде заглушки afx_msg OnPaint().

class CMainWnd : public CFrameWnd
{
public:
	......
	void MenuSwitch();	// Процедура реакции на выбор пункта меню
	afx_msg void OnPaint();	// Переопределяем функцию рисования в окне
	~CMainWnd();	// Деструктор
private:
	BOOL blMenu;	// какое меню активно
	......
};

Наша программа должна реагировать на события перерисовки экрана.

BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)	// таблица откликов на сообщения
......
	ON_WM_KEYDOWN()	// реакция на нажатие клавиши
	ON_WM_CREATE()	// событие создания окна
	ON_WM_PAINT()	// Это реакция. Если нету этой строчки, бог вам судья.
	ON_COMMAND(ID_FILE_EXIT,MenuExit)	// Вот она, обработка реакции на выбор меню
......
END_MESSAGE_MAP()

А вот и сама функция:

void CMainWnd::OnPaint()
{
	CPaintDC dc(this);	// Получить контекст устройства
	dc.TextOut(200,200,"Hello MFC Programm");	// Написать в нем привет
	dc.MoveTo(300,300);	// Начать рисовать линию
	dc.LineTo(600,105);	// И продолжить рисовать линию
	dc.LineTo(105,105);	// И еще продолжить рисовать линию
}

Вот такое получается окно программы.

10_1.gif (3733 b)

Описание

При программировании под Windows за работу с графикой отвечает GDI Graphics Divice Interface. Все функции работы с графикой сосредоточенны в gdi32.dll.

В программе не только нужно создать графику, нужен код. Этот код должен отвечать за время, место прорисовки. Главным моментом здесь является сообщение WM_PAINT. Это сообщение посылается окну всегда, когда требуется перерисовка экрана. Например: при изменении размера окна, и если окно выходит на передний план, и при запуске программы естественно.

Внимание !!! Windows не хранит массивы пикселей для сохранения окон, как это часто делалось при программировании в DOS. При необходимости "освежить окно" - оно перерисовывается и делает это сообщение WM_PAINT.

Для целей графики и близких к ним в Windows есть понятие контекст устройства. Эти контексты не зависят от самого устройства для программиста. Например, на мониторах разных типов команды одинаковы, при этом ВНИМАНИЕ команды рисования на мониторе и принтере тоже одинаковые. С Windows Вас, как программиста, не интересует какой язык использует принтер. А еще недавно я помню, как приходилось штудировать документацию по принтеру и писать драйвера к своим программам под каждый тип принтера.

Представьте, что вы установили у себя на компьютере новый монитор, и новый принтер, в программе не нужно править ни одного байта, всё будет работать. Кто теперь скажет, что Windows это плохо, а Microsoft не умеет писать программы ?

Первым делом в классе рамки окна мы описали функцию, которая вызывается в ответ на WM_PAINT. Потом в обработчике событий указали, что на это событие реагировать. И написали сам код.

С помощью CPaintDC dc(this); получили контекст нашего окна для рисования. Вывели текст. Установили указатель в точку. Провели линию. Компилируем, запуcкаем на выполнение. Ну прям, как у Пикасо !

Давайте посмотрим отдельно, как работает MoveTo() и LineTo().

10_2.gif (1930 b)

Функция MoveTo() перемещает курсор к указанной точки без рисования. Функция LineTo() рисует линию от текущего положения до указанного и при этом перемещает курсор к указанному положению. То есть после того, как Вы нарисовали линию с помощью LineTo(), курсор оказывается в конечной точке.

Шпаргалка

Опишите функцию рисования.

class CMainWnd : public CFrameWnd
{
......
	afx_msg void OnPaint();
......
}

Создайте реакцию на сообщение.

BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)
......
	ON_WM_PAINT()
......
END_MESSAGE_MAP()

Напишите код рисования.

void CMainWnd::OnPaint()
{
	CPaintDC dc(this);
	......
}

Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 03.09.99 update: 27.06.2001