Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция_4(моя).doc
Скачиваний:
8
Добавлен:
18.08.2019
Размер:
442.37 Кб
Скачать

Операции контекста устройства

1) Приложение контекстом устройства может выполнить ниже перечисленные операции:

2) Перечислить существующие графические объекты.

3) Выбрать новый графический объект.

4) Удалить существующие графические объекты.

5) Сохранить текущие графические объекты, их атрибуты и графические режимы.

6) Восстановить предварительно сохраненные графические объекты, их атрибуты и графические режимы.

Кроме того, приложение может использовать контекст устройства, чтобы:

1) Выяснить, как транслируется графический вывод данных.

2) Отменить длинные операции рисования (начатый потоком в многопоточном приложении).

3) Возвратить в исходное положение специфическое состояние принтера.

Режимы отображения.

Большинство функций, работающих с оконными координатами, определяют координаты относительно начала рабочей области окна, то есть от левего верхнего угла.

Единицы, в которых измеряются координаты, зависят от режима отображения (mapping mode), установленного для данного окна. Единицы измерения, зависящие от режима отображения, называют логическими единицами, а координаты в этом случае называют логическими координатами.

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

Идентификаторы, применяемые для обозначения режимов отображения.

Для установки текущего режима отображения используется функция SetMappingMode(), которая имеет следующий прототип:

WINGDIAPI int WINAPI SetMapMode(HDC, int);

Аргумент HDC – хэндл контекста устройства, для которого устанавливается данный режим.

Аргумент int – определяет задаваемый режим отображения. При создании окна по умолчанию устанавливается режим MM_TEXT, то есть все координаты исчисляются в пикселах.

Отображаем картинку в окне:

#include <windows.h>

LRESULT CALLBACK PaintWndProc(HWND,UINT,UINT,LONG);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

{

HWND hMainWnd;

char szClassName[] = "MyClass";

MSG msg;

WNDCLASSEX wc;

// Заполняем структуру класса окна

wc.cbSize = sizeof(wc);

wc.style = CS_HREDRAW | CS_VREDRAW;

wc.lpfnWndProc = PaintWndProc;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = hInstance;

wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);

wc.lpszMenuName = NULL;

wc.lpszClassName = szClassName;

wc.hIconSm = LoadIcon(NULL, IDI_INFORMATION);

// Регистрируем класс окна

if (!RegisterClassEx(&wc)) {

MessageBox(NULL, "Cannot register class", "Error", MB_OK);

return 0;

}

hMainWnd=CreateWindow(szClassName,"Должно быть фото...",

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT,CW_USEDEFAULT,

CW_USEDEFAULT,CW_USEDEFAULT,

NULL,NULL,

hInstance,NULL);

if (!hMainWnd)

{

MessageBox(NULL,"Не могу создать окно","Error",MB_OK);

return 0;

}

// Показываем наше окно

ShowWindow(hMainWnd,nCmdShow);

UpdateWindow(hMainWnd);

// Создаём цикл сообщений

while (GetMessage(&msg,NULL,0,0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return msg.wParam;

}

// Создаём оконную процедуру

LRESULT CALLBACK PaintWndProc(HWND hWnd,UINT Message,

UINT wParam,LONG lParam)

{

HDC hDC,hCompatibleDC;

PAINTSTRUCT PaintStruct;

HANDLE hBitmap,hOldBitmap;

RECT Rect;

BITMAP Bitmap;

switch(Message)

{

case WM_PAINT:

// Получаем контекст устройства

hDC=BeginPaint(hWnd,&PaintStruct);

// Загружаем bitmap, который будет отображаться в окне

hBitmap=LoadImage(NULL, "Foto118.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

// Получаем размерность загруженного bitmapа

GetObject(hBitmap,sizeof(BITMAP),&Bitmap);

// Создаём совместимый с контекстом окна контекст в памяти

hCompatibleDC=CreateCompatibleDC(hDC);

// Делаем загруженный из файла bitmap текущим в совместимом контексте

hOldBitmap=SelectObject(hCompatibleDC,hBitmap);

// Определяем размер рабочей области окна

GetClientRect(hWnd,&Rect);

// Копируем bitmap с совместимого на основной контекст с масштабированием

StretchBlt(hDC,0,0,Rect.right,Rect.bottom,hCompatibleDC,0,0,Bitmap.bmWidth,Bitmap.bmHeight,SRCCOPY);

// Делаем старый bitmap текущим

SelectObject(hCompatibleDC,hOldBitmap);

// Удаляем загруженный с диска bitmap

DeleteObject(hBitmap);

// Удаляем совместимый контекст

DeleteDC(hCompatibleDC);

// Освобождаем основной контекст, завершая перерисовку рабочей области окна

EndPaint(hWnd,&PaintStruct);

return 0;

case WM_DESTROY:

PostQuitMessage(0);

return 0;

}

return DefWindowProc(hWnd,Message,wParam,lParam);

}

Для отображения рисунка Foto125.bmp необходимо, чтобы этот файл находился в текущей директории Debug. Можно также указать адрес файла с изображением, если он находится не в текущей директории, например так:

D:\\Задания\\WinAPI\\Graf\\Debug

Функция WinMain() стандартна. В оконной функции PaintWndProc() обрабатывается сообщение WM_PAINT следующим образом:

1) Получаем хэндл контекста устройства посредством вызова функции BeginPaint(hWnd,&PaintStruct), где

hWnd – окно для которого получаем контекст отображения;

&PaintStruct – параметр, через который передаётся адрес структуры типа PAINTSTRUCT.

2) Получаем хэндл bitmap’а, который должен отображаться в окне вызывая функцию LoadImage(). Данная функция позволяет загружать графические образы как из ресурсов, записанных в исполняемом файле, так и из файлов, содержащих только изображения. Функция позволяет также управлять параметрами отображения и загрузки образа.

Эта функция имеет следующий прототип:

LoadImage(HINSTANCE hInst, LPCSTR lpszName, UINT bmImage, int w, int t, UINT fuLoad)

Аргумент hInst – хэндл программы. Если вместо хэндла программы указан NULL, то объект является предопределённым, то есть хранится в глубинах системы. В противном случае объект загружается откуда-то снаружи.

Аргумент lpszName – определяет загружаемый объект.

Аргумент fuLoad – содержит флаги, определяющие режим загрузки объекта. Если этот флаг установлен, то загрузка происходит из внешнего файла. Среди флагов есть занчение LR_LOADFROMFILE. От значения первого и последнего аргументов зависит как будет интерпретирован второй аргумент. Взаимодействие этих трёх аргументов объясняется в таблице.

fuLoad (флаг LR_LOADFROMFILE)

hInst

lpszName

Не установлен

NULL

Идентификатор предопределённого объекта

Не установлен

Не NULL

Имя ресурса

Установлен

NULL

Имя файла, в котором содержится bitmap

Установлен

Не NULL

Имя файла, в котором содержится bitmap

Третий аргумент bmImage – тип образа, он может принимать значения IMAGE_BITMAP, IMAGE_CURSOR, IMAGE_ICON, IMAGE_ENHMETAFILE.

Четвёртый аргумент и пятый (w, t) указывают ширину и высоту иконки или курсора.

Флаги, определяющие параметры загрузки образа в память начинаются с букв LR и могут принимать следующие значения табл. 8:

Функция LoadImage() возвращает хэндл загруженного битмапа или NULL.

3) Получаем совместимый контекст в памяти с помощью функции CreateCompatibleDC(). Единственный аргумент этой функции – хэндл контекста (hDC), для которого создаётся совместимый контекст.

4) Делаем загруженный из файла bitmap текущим в совместимом контексте с помощью функции SelectObject(). Аргумент hCompatibleDC – хэндл контекста, в котором замещается текущий элемент. Второй – хэндл элемента, которым замещается текущий элемент (хэндл загруженного битмапа). То есть эта функция возвращает хэндл замещённого элемента и в последствии с этим элементом могут также производиться манипуляции.

5) Копируем bitmap с совместимого на основной контекст с масштабированием. Для копирования битмапа с одного контекста на другой используется функция StretchBlt(). Эта функция в файле wingdi.h описана следующим образом:

StretchBlt(HDC, int, int, int, int, HDC, int, int, int, int, DWORD);

Первые пять аргументов описывают тот прямоугольник на экране, в который будет вписан битмап (на рис. Он обозначен светло-серым цветом). Ту часть битмапа, которая будет вписана в прямоугольник на экране (на рисунке – пересекающаяся часть светло-серого и тёмно-серого прямоугольников), описывают следующие пят аргументов. И последний одиннадцатый аргумент – код растровой операции, описывает каким образом пиксели одного битмапа будут взаимодействовать с пикселами другого битмапа. Обратимся к рисунку.

Рисунок.

Предположим, что в регионе, обозначенном на рис. светло-серым цветом нужно отобразить битмап (обозначен на рисунке тёмно-серым цветом) или часть битмапа при необходимости сжав или растянув его.

Первый и шестой аргументы функции – хэндлы окна (hDC) и совместимого контекста (hCompatibleDC) соответственно. Второй (nXOriginDest) и третий (nYOriginDest) аргументы содержат смещение верхнего левого угла прямойгольника, в который будет вписываться битмап, относительно левой и верхней сторон рабочей области окна (так как мы при создании окна не меняли режим отображения, то текущий режим является установленным по умолчанию). Четвертый (nWidthDest) и пятый (nHeightDest) аргументы – ширина и высота этого прямоугольника. Седьмой (nXOriginSrc) и восьмой (nYOriginSrc) аналогичны второму и третьему аргументам. Девятый (nWidthSrc) и десятый (nHeightSrc) аргументы содержат ширину и высоту отображаемой части битмапа. Изменяя положение прямоугольников друг относительно друга, а также относительно окна, меняя их размеры, можно отобразить на экране любую часть или целый битмап.

Для того чтобы совместить битмап с рабочей областью окна необходимо, чтобы второй и третий аргумент функции StretchBlt были равны нулю. Четвёртый и пятый аргумент должны быть равны ширине и высоте рабочей области (ширину и высоту рабочей области можно получить с помощью функции GetClientRect(hWnd,&Rect)). Седьмой и восьмой аргументы равны нулю, девятый и десятый аргументы должны содержать ширину и высоту битмапа, которые можно получить, обратившись к функции GetObject.

Одиннадцатый аргумент функции StretchBlt() – это код растровой операции, то есть это код, который определяет, как при операции будут взаимодействовать биты, определяющие заливку и изображение совместимого контекста с изображением на действительном контексте.

6) Удаляем совместимый контекст;

7) Удаляем объект;

8) Удаляем контекст устройства.

17

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]