Академический Документы
Профессиональный Документы
Культура Документы
ЛЕКЦИЯ 14
КОНТЕКСТ УСТРОЙСТВА _______________________________________________________________ 2
Класс CDC и его производные ____________________________________________________________ 2
Объявление контекста___________________________________________________________________ 2
РАБОТА С ТЕКСТОМ ____________________________________________________________________ 3
Вывод текста. Функция TextOut ___________________________________________________________ 3
Вывод текста в прямоугольнике отсечения. Функция ExtTextOut ________________________________ 3
Цвет фона. Функции GetBkColor, SetBkColor _________________________________________________ 4
Цвет символов текста. Функции GetTextColor, SetTextColor_____________________________________ 4
Выравнивание текста. Функции GetTextAlign, SetTextAlign _____________________________________ 4
Пример рисования текста ________________________________________________________________ 5
ЦВЕТОВАЯ СИСТЕМА RGB ______________________________________________________________ 6
ДИАЛОГОВОЕ ОКНО ВЫБОРА ЦВЕТА ___________________________________________________ 7
Конструктор класса CColorDialog__________________________________________________________ 7
Отображение диалогового окна. Функция DoModal ___________________________________________ 7
Получение выбранного цвета. Функция GetColor _____________________________________________ 7
Получение дополнительных цветов. Функция GetSavedCustomColors ____________________________ 7
Пример использования диалогового окно выбора цвета _______________________________________ 8
МОДЕЛЬ ПЕРЬЕВОГО ПЛОТТЕРА________________________________________________________ 8
Перемещение карандаша. Функция MoveTo _________________________________________________ 8
Рисование отрезка. Функция LineTo ________________________________________________________ 9
Рисование точки. Функция SetPixel_________________________________________________________ 9
Получение цвета точки. Функция GetPixel ___________________________________________________ 9
РИСОВАНИЕ ГРАФИЧЕСКИХ ПРИМИТИВОВ ____________________________________________ 9
Рисование прямоугольника. Функция Rectangle ______________________________________________ 9
Рисование округлённого прямоугольника. Функция RoundRect __________________________________ 9
Рисование эллипса. Функция Ellipse ______________________________________________________ 10
Рисование эллиптической дуги. Функция Arc _______________________________________________ 10
Рисование эллиптической дуги и хорды. Функция Chord ______________________________________ 10
Рисование ломаной линии. Функция Polyline________________________________________________ 10
Рисование многоугольника. Функция Polygon _______________________________________________ 11
КАРАНДАШ. КЛАСС CPEN ______________________________________________________________ 11
Конструкторы класса СРеn ______________________________________________________________ 11
Создание карандаша. Функция CreatePen __________________________________________________ 12
Создание указателя на карандаш. Тип HPEN _______________________________________________ 12
Использование объекта. Функция SelectObject ______________________________________________ 12
Получение атрибутов объекта. Функция GetObject___________________________________________ 13
НАСТРОЙКА РЕЖИМА ОТОБРАЖЕНИЯ_________________________________________________ 13
Выбор единиц измерения. Функция SetMapMode ____________________________________________ 13
Задание произвольных единиц измерения. Функции SetViewportExt и SetWindowExt ________________ 14
Размер прямоугольника. Структура SIZE __________________________________________________ 14
Настройка начала координат. Функции SetViewportOrg и SetWindowOrg _________________________ 14
Получение размеров клиентской области. Функция GetClientRect ______________________________ 14
Пример настройки режима отображения ___________________________________________________ 15
КИСТЬ. КЛАСС CBRUSH ________________________________________________________________ 16
Конструкторы класса CBrush_____________________________________________________________ 16
Образец физической кисти. Структура LOGBRUSH __________________________________________ 16
Создание кисти________________________________________________________________________ 17
Пример создания и использования кисти __________________________________________________ 17
ТОЧЕЧНЫЙ РИСУНОК. КЛАСС CBITMAP _______________________________________________ 18
Создание точечного рисунка. Функция CreateBitmap _________________________________________ 18
Создание ресурса точечного рисунка _____________________________________________________ 18
Загрузка ресурса точечного рисунка. Функция LoadBitmap ____________________________________ 19
Выжол Ю.А.
Лекция 14 Работа с графикой 2
КОНТЕКСТ УСТРОЙСТВА
Контекстом устройства называется область памяти, используемая в системе Windows для выполне-
ния графических операций. Графический вывод может выполняться как на экран, так и на принтер. Объек-
ты класса CDC (Class Device Contacts) содержат множество встроенных методов, используемых в процес-
се рисования в контексте устройства. Все рисование в Windows выполняется через контекст устройства.
Контексты устройств упрощают задачи программирования. Дело в том, что они могут соответство-
вать самым разным устройствам, например, экрану монитора или принтеру. Если вы рисуете через кон-
текст устройства, то изображение будет правильно отображаться на разных устройствах, в том числе на
экране и на принтере без изменения кода.
CObject
CDC
CClientDC
CMetaFileDC
CPaintDC
CWindowDC
Объявление контекста
Для рисования в клиентской области окна удобно использовать виртуальную функцию прорисовки
экрана. Она реализована в виде заглушки afx_msg OnPaint. Как правило, MFC Class Wizard сам добавля-
ет скелет кода этой функции в код класса диалогового окна.
class CGraphDlg : public CDialog
{
protected:
afx_msg void OnPaint () ;
DECLARE_MESSAGE_MAP ()
…
};
Выжол Ю.А.
Лекция 14 Работа с графикой 3
Функция OnPaint вызывается в тот момент, когда окно получает сообщение WM_PAINT. Это со-
общение посылается окну всегда, когда требуется перерисовка экрана. Например, при увеличении разме-
ра окна, если окно выходит на передний план, при запуске программы.
Поскольку наша программа должна реагировать на событие перерисовки экрана, то карта сообще-
ний должна содержать вызов соответствующей функции ON_WM_PAINT
BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)
ON_WM_PAINT
…
END_MESSAGE_MAP()
Переопределяем функцию перерисовки окна.
void CMainWnd::OnPaint()
{
// объявление экземпляра класса CPaintDC для работы с клиентской областью окна
// связывает его с контекстом устройства текущего диалогового окна
CPaintDC dc ( this ) ;
dc.TextOut ( 200 , 200 , "Hello MFC Program" ) ; // Написать в окне привет
}
Если вам необходимо перерисовать окно не только при его увеличении, но и при уменьшении, то
целесообразно создать функцию обработки события изменения размеров окна, которая содержит команду
посылки сообщения WM_PAINT.
void CGraphDlg::OnSize ( UINT nType , int cx , int cy )
{
CDialog::OnSize ( nType , cx , cy ) ;
SendMessage ( WM_PAINT ) ; // посылаем команду родительскому окну перерисовать окно
}
РАБОТА С ТЕКСТОМ
Выжол Ю.А.
Лекция 14 Работа с графикой 4
virtual BOOL ExtTextOut ( int x , int y , UINT nOptions , LPCRECT lpRect , LPCTSTR lpszString ,
UINT nCount , LPINT lpDxWidths ) ;
Возвращаемое значение: ненулевое, если функция успешно выполнена, и ноль в противном случае.
Параметры:
x,y определяет логические координаты строки.
lpszString указатель на строку символов, значение которой будет нарисовано.
str объект типа CString, значение которой будет нарисовано.
lpRect указатель на структуру RECT, которая определяет размеры и положение прямоуголь-
ника. Этот параметр может быть недействителен (NULL). Вы можете также использо-
вать объект типа CRect для этого параметра.
nCount определяет количество символов, которые будут нарисованы.
LpDxWidths указатель на массив целых чисел, которые определяют интервал между соседними
символами. Если параметр недействителен (NULL), то функция использует стандарт-
ный интервал между символами.
nOptions определяет тип прямоугольника, которые будут нарисованы.
Этот параметр может содержать одно, два, или ни одного из следующих значений:
ETO_CLIPPED текст, который вышел за границы прямоугольника, будет отсечен.
ETO_OPAQUE прямоугольник будет закрашен текущим цветом фона.
Выжол Ю.А.
Лекция 14 Работа с графикой 5
TA_RIGHT координата определяет положение правого края строки.
Вторая категория флагов определяет положение строки в вертикальном направлении относительно
y-координаты:
TA_BASELINE координата определяет положение базовой линии строки.
TA_BOTTOM координата определяет положение нижнего края строки.
TA_TOP координата определяет положение верхнего края строки (по умолчанию).
Третья категория определяет, обновлены ли текущие координаты после вызова функции вывода
текста:
TA_NOUPDATECP не обновляет текущую координату (по умолчанию)
TA_UPDATECP обновляет текущую x-координату. Новое положение находится с правой
стороны рабочего прямоугольника. Когда этот флаг установлен, координа-
ты, указанными в вызовах функции TextOut, не используются.
Выжол Ю.А.
Лекция 14 Работа с графикой 6
dc.SetTextAlign ( TA_CENTER | TA_BASELINE );
dc.TextOut ( L/2 , 15 , Title ); // рисование заголовка в центре окна
CRect TextRec; // параметры текстовой области
// вычисление параметров текстовой области
TextRec.top =H/4; TextRec.left = L / 4 ;
TextRec.bottom = 3 * H / 4 ; TextRec.right = 3 * L / 4 ;
dc.SetBkColor ( crWhite ) ; // установка цвета фона
dc.SetTextColor ( crRed ) ; // установка цвета текста
dc.ExtTextOut ( L / 2 , H / 2 , ETO_OPAQUE | ETO_CLIPPED , &TextRec , Text , NULL ) ;
}
S B G R
4 байта
Для инициализации переменной, которая хранит цвет, удобно использовать как шестнадцатеричную
систему исчисления, так и макрос RGB прототип которого имеет вид:
COLORREF RGB ( BYTE red , BYTE green , BYTE blue) ;
Выражения для основных цветов в виде шестнадцатеричной константы и с помощью вызова макро-
са RGB будут иметь вид:
Чёрный 0x00000000 RGB ( 0 , 0 , 0 )
Белый 0x00FFFFFF RGB ( 255 , 255 , 255 )
Светло-серый 0x00E4E4E4 RGB ( 232 , 232 , 232 )
Тёмно-серый 0x00A0A0A0 RGB ( 160 , 160 , 160 )
Красный 0x000000FF RGB ( 255 , 0 , 0 )
Зелёный 0x0000FF00 RGB ( 0 , 255 , 0 )
Синий 0x00FF0000 RGB ( 0 , 0 , 255 )
Жёлтый 0x0000FFFF RGB ( 255 , 255 , 0 )
Выжол Ю.А.
Лекция 14 Работа с графикой 7
Все цвета, которые имеют равные соотношения первичных компонентов, проявляются в виде оттен-
ков серого цвета.
Разложить цвет на составляющие можно с помощью макросов GetRValue, GetGValue, GetBValue.
Выжол Ю.А.
Лекция 14 Работа с графикой 8
Пример использования диалогового окно выбора цвета
Ниже приведён код обработки события щелчка на кнопке IDC_COLOR в классе CcolDlg.
void CColDlg :: OnColor ( )
{
// создание экземпляра класса окна выбора цвета; цвет по умолчанию - красный
CColorDialog dlg ( 0x000000FF ) ;
// вывод на экран окна выбора цвета
if ( dlg.DoModal ( ) == IDOK ) // если при закрытии окна пользователь нажал кнопку ОК
{
CString str ; // текст сообщения
COLORREF color ; // выбранный цвет
BYTE red , green , blue ;
// составляющие цвета
color = dlg.GetColor ();
// получение цвета, выбранного пользователем
red = GetRValue ( color ) ;
// определение красной составляющей цвета
green = GetGValue ( color ) ;
// определение зелёной составляющей цвета
blue = GetBValue ( color ) ;
// определение синей составляющей цвета
// Формирование строки текста сообщения, цвета выводятся в виде шестнадцатеричных чисел
str.Format ( "Выбран цвет 0x%08X, содержащий:\n"
"\t0x%02X - красного\n"
"\t0x%02X - зеленого\n"
"\t0x%02X - синего", color , red , green , blue ) ;
// вывод окна сообщений
MessageBox ( str , "Выбран цвет" ) ;
}
В результате работы этого фрагмента кода на экран будет выведено следующее окно сообщений.
Выжол Ю.А.
Лекция 14 Работа с графикой 9
Синтаксис:
CPoint MoveTo ( int x , int y ) ;
CPoint MoveTo ( POINT point ) ;
Выжол Ю.А.
Лекция 14 Работа с графикой 10
на дуге. Дуга рисуется в направлении против часовой стрелки. Так как дуга не является замкнутой линией,
то заполнение текущей кистью не выполняется.
Синтаксис:
BOOL RoundRect( int x1 , int y1 , int x2 , int y2 , int x3 , int y3 ) ;
BOOL RoundRect ( LPCRECT lpRect , POINT point ) ;
Параметры:
x1 , y1 , x2 , y2 координаты двух противоположных вершин прямоугольника.
x3 , y3 размер эллипса, используемого для округления.
lpRect указатель на структуру RECT, которая определяет размеры и положение прямоуголь-
ника.
point размер эллипса, используемого для округления.
Выжол Ю.А.
Лекция 14 Работа с графикой 11
nCount определяет количество точек в массиве (не менее 2)
Пример: В приведённом ниже примере создаётся массив точек, определяющих крест. Массив содержит 7
точек – 4 вершины и центр креста, который используется трижды. Крест рисуется с помощью ломаной ли-
нии с центром в точке x, y.
CClientDC dc ( this ) ; // контекст устройства – текущее диалоговое окно
const n = 7 ; // количество точек в массиве
int x = 200 , y = 100 ; // координаты центра креста
int h = 10 ; // длина луча
// объявление и инициализация массива вершин креста
POINT ptD [ n ] = {{ x-h , y } , { x , y } , { x , y-h } , { x , y } , { x+h , y } , { x ,y } , { x , y+h }} ;
dc.Polyline ( ptD , n ); // рисование креста
CObject
CGdiObject
CPen
Выжол Ю.А.
Лекция 14 Работа с графикой 12
CPen penBlue ( PS_SOLID , 3 , RGB ( 0 , 0 , 255 )) ;
Третья версия конструктора предназначена для создания объектов класса с одновременным созда-
нием карандашей Windows.
CPen ( int nPenStyle, int nWidth , const LOGBRUSH* pLogBrush , int nStyleCount = 0 , const DWORD*
lpStyle = NULL );
Выжол Ю.А.
Лекция 14 Работа с графикой 13
dc.Rectangle ( &rt ) ; // рисуем прямоугольник
Выжол Ю.А.
Лекция 14 Работа с графикой 14
MM_ANISOTROPIC режим позволяет настраивать с помощью функций SetWindowExt и Set-
ViewportExt размерность осей координат и их направления (отдельно для
каждой)
Выжол Ю.А.
Лекция 14 Работа с графикой 15
пользовать функцию GetClientRect, которая определена в классе CWnd и у всех его потомков соответст-
венно. Функция копирует координаты клиентской области в структуру, на которую указывает параметр.
void GetClientRect ( LPRECT lpRect ) const ;
lpRect указатель на структуру типа RECT или объект типа CRect. После вызова функции поля
left и top будут равны 0, а поля right и bottom будут содержать ширину и высоту окна в
пикселях.
Выжол Ю.А.
Лекция 14 Работа с графикой 16
CObject
CGdiObject
CBrush
Выжол Ю.А.
Лекция 14 Работа с графикой 17
COLORREF lbColor ; // цвет кисти
LONG lbHatch ; // тип штриховки или указатель на точечный рисунок
} LOGBRUSH ;
Члены структуры:
lbStyle определяет стиль кисти и должен принимать одно из следующих значений:
BS_HOLLOW пустая кисть
BS_NULL пустая кисть
BS_HATCHED штрихуемая кисть
BS_SOLID сплошная кисть
BS_PATTERN в качестве кисти используется точечный рисунок
lbColor определяет цвет кисти, если поле lbStyle равно BS_HATCHED или BS_SOLID;
игнорируется, если поле lbStyle равно BS_HOLLOW или BS_PATTERN.
lbHatch определяет тип штриховки, если поле lbStyle равно BS_HATCHED. В этом случае поле
может принимать те же значения, что и параметр nIndex в конструкторе класса CBrush.
Структура LOGBRUSH используется функциями CreateBrushIndirect и ExtCreatePen.
Создание кисти
Если кисть создана с помощью первого конструктора и является пустым объектом, то перед исполь-
зованием его необходимо проинициализировать с помощью одной из следующих функций:
BOOL CreateSolidBrush ( COLORREF crColor ) ;
Функция создает однотонную кисть с заданным цветом.
BOOL CreateHatchBrush ( int nIndex , COLORREF crColor ) ;
Функция создает кисть со штриховкой заданного цвета и направления.
BOOL CreatePatternBrush ( CBitmap* pBitmap ) ;
Функция создает кисть на основе битового массива размером 8x8.
BOOL CreateBrushIndirect ( const LOGBRUSH* lpLogBrush ) ;
Функция создаёт кисть, используя двухцветный (1 бит на пиксель) точечный рисунок. Пиксели, пред-
ставленные нулём рисуются текущим цветом текста. Пиксели, представленные единицей рисуются теку-
щим цветом фона. Кроме того, может создавать однотонную кисть и кисть со штриховкой.
BOOL CreateDIBPatternBrush ( HGLOBAL hPackedDIB , UINT nUsage ) ;
BOOL CreateDIBPatternBrush ( const void* lpPackedDIB , UINT nUsage ) ;
Функция создает кисть на основе битового массива, который хранит изображение в независимом от
устройства виде (Device-Independent Bitmap – DIB).
BOOL CreateSysColorBrush ( int nIndex ) ;
Функция создает кисть со штриховкой на основе системного цвета.
Выжол Ю.А.
Лекция 14 Работа с графикой 18
ТОЧЕЧНЫЙ РИСУНОК. КЛАСС CBITMAP
Класс CBitmap инкапсулирует графический объект Windows – “точечный рисунок”. Точечный рису-
нок – это прямоугольная матрица целых чисел, каждое из которых кодирует цвет пикселя в прямоугольной
области. Точечный рисунок используется при создании кисти, может отображаться в форме или элементе
управления. Иерархия классов относительно класса CBitmap представлена на рисунке.
CObject
CGdiObject
CBitmap
Выжол Ю.А.
Лекция 14 Работа с графикой 19
Выжол Ю.А.