Шаг 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 Device Interface. Все функции работы с графикой сосредоточенны в gdi32.dll.

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

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

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

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

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

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

Давайте посмотрим отдельно, как работает 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);
        ......
}
Hosted by uCoz