LAB5 (Методические указания к лабораторным работам)
Описание файла
Файл "LAB5" внутри архива находится в папке "Методические указания к лабораторным работам". Документ из архива "Методические указания к лабораторным работам", который расположен в категории "". Всё это находится в предмете "программирование в среде windows" из 4 семестр, которые можно найти в файловом архиве МГТУ им. Н.Э.Баумана. Не смотря на прямую связь этого архива с МГТУ им. Н.Э.Баумана, его также можно найти и в других разделах. Архив можно найти в разделе "книги и методические указания", в предмете "программирование в среде windows" в общих файлах.
Онлайн просмотр документа "LAB5"
Текст из документа "LAB5"
Лабораторная работа 5.
Формирование изображение декартовых осей.
Для выполнения работы необходима следующая информация:
-числовые значения, определяющие начало и конец оси X,
-числовые значения, определяющие начало и конец оси Y,
- точка на оси X, через которую следует провести ось,
- точка на осиY, через которую следует провести ось,
Всего 6 чисел: 3 числа по оси X и 3 числа по оси Y.
Для изображения на экране геометрических объектов (а в нашей задаче - это декартовы оси) используют масштаб. Под масштабом понимается отношение двух соответствующих друг другу величин, определенных в одних единицах измерения. В математике использование физических единиц измерения не имеет решающего значения. В графических построениях на экране монитора оперируют единицей измерения в 1 пиксель. Масштаб математических величин, точнее, их графических интерпретаций, можно выражать по отношению к пикселю.
Здесь:
масштаб m показывает, сколько пикселей будет использовано для изображения отрезка единичной длины,
ww – ширина окна,
xw – координата левой границы окна,
xb – координата начала линии,
xe - координата конца линии,
δ – отступ от границы окна,
a,b – границы интервала.
Обратная масштабу величина р = 1/m показывает длину математического подынтервала, который соответствует интервалу между двумя соседними пикселями. Итак, только что масштаб был выбран как отношение числа пикселей к безразмерной математической единице. Возможны другие способы выбора масштаба, например напряжение в вольтах, необходимое для отклонения луча на экране монитора на 1 см.
Преобразование координат
Приложение, вызывая для рисования функции GDI, указывает логические координаты. Перед выводом GDI преобразует их в физические с использованием следующих формул:
В этих формулах используются следующие обозначения.
Переменные xWindow и yWindow обозначают, соответственно, логические координаты по оси X и Y. Физические координаты обозначаются как xViewport и yViewport. Таким образом, логические координаты (xWindow,yWindow) преобразуются в физические координаты (xViewport,yViewport).
С помощью переменных xViewOrg и yViewOrg можно изменить расположение начала физических координат. По умолчанию в контексте отображения значения атрибутов, соответствующих этим переменным, равны 0. Приложение может сместить начало координат, изменив значения переменных xViewOrg и yViewOrg.
Для перемещения начала логической системы координат приложение может изменить значения переменных xWinOrg и yWinOrg, которые также определены как атрибуты контекста отображения. По умолчанию в этих переменных находятся нулевые значения.
Переменные xViewExt, yViewExt, xWinExt и yWinExt (вернее, их отношения) задают масштаб, который используется в процессе преобразования координат. Этот масштаб зависит от установленного режима отображения. Приложения могут изменить его только в режимах MM_ISOTROPIC и MM_ANISOTROPIC , для остальных режимов отображения используются фиксированные значения.
Обратные преобразования (из логических координат в физические) выполняются с использованием следующих формул:
Для выполнения подобных вычислений удобна функция MulDiv, определенная в программном интерфейсе Windows:
int WINAPI MulDiv(
int nMultiplicand, // множимое
int nMultiplier, // множитель
int nDivisor); // делитель
Эта функция выполняет умножение 16-разрядного параметра nMultiplicand на 16-разрядный параметр nMultiplier, а затем делит полученное 32-разрядное произведение на 16-разрядный параметр nDivisor. В случае переполнения или при нулевом значении делителя функция возвращает отрицательное значение 32768.
Однако есть специальные функции, предназначенные для преобразования логических координат в физические и физических в логические. Это функции LPtoDP и DPtoLP.
Функция LPtoDP выполняет преобразование логических координат в физические , причем одновременно можно преобразовать несколько пар координат, что ускоряет работу приложения за счет сокращения количества вызовов функции:
BOOL WINAPI LPtoDP(
HDC hdc, // идентификатор контекста отображения
POINT FAR* lppt, // указатель на массив структур POINT
int cPoints); // размер массива структур POINT
Параметр hdc указывает контекст отображения, для которого требуется выполнить преобразования. В процессе преобразования используются атрибуты контекста, такие как смещение и масштаб осей координат.
Через параметр lppt передается указатель на массив структур POINT, в котором находятся преобразуемые координаты. Размер массива определяется значением параметра cPoints. Структура POINT определена в файле windows.h следующим образом:
typedef struct tagPOINT
{
int x;
int y;
} POINT;
После успешного выполнения преобразования функция возвращает значение TRUE. При возникновении ошибки возвращается FALSE.
Обратное преобразование (физических координат в логические ) выполняется функцией DPtoLP : BOOL WINAPI DPtoLP(
HDC hdc, // идентификатор контекста отображения
POINT FAR* lppt, // указатель на массив структур POINT
int cPoints); // размер массива структур POINT
Назначение параметров функции DPtoLP и возвращаемое ей значение аналогично назначению параметров и возвращаемому значению функции LPtoDP.
Есть еще две функции, предназначенные для преобразования координат - ClientToScreen и ScreenToClient.
Функция ClientToScreen выполняет преобразование координат в системе координат, связанной с внутренней областью окна, в экранные координаты:
void WINAPI ClientToScreen(HWND hwnd, POINT FAR* lppt);
Параметр hwnd содержит идентификатор окна, для которого выполняется преобразование.
Параметр lppt содержит указатель на структуру типа POINT, в которую перед вызовом функции следует записать преобразуемые координаты.
Функция ScreenToClient имеет аналогичные параметры, но выполняет обратное преобразование:
void WINAPI ScreenToClient(HWND hwnd, POINT FAR* lppt);
Обработка сообщения WM_PAINT
Окно должно быть способно перерисовать свою внутреннюю поверхность или любую его часть в любой момент времени при получении сообщения WM_PAINT.
Сообщение WM_PAINT передается функции окна, если стала видна область окна, скрытая раньше другими окнами, если вы изменили размер окна или выполнили операцию свертки (пролистывания) изображения в окне. Приложение может передать функции окна сообщение WM_PAINT явным образом, вызывая функции UpdateWindow, InvalidateRect или InvalidateRgn.
Иногда операционная система Windows может сама восстановить содержимое окна, не посылая сообщение WM_PAINT. Например, при перемещении курсора мыши или пиктограммы свернутого приложения Windows самостоятельно восстанавливает содержимое окна. Если же Windows не может восстановить окно, функция окна получает сообщение WM_PAINT и перерисовывает окно самостоятельно.
Перед тем как записать сообщение WM_PAINT в очередь приложения, Windows посылает функции окна сообщение WM_ERASEBKGND. Если функция окна не обрабатывает сообщение WM_ERASEBKGND, передавая его функции DefWindowProc, последняя в ответ на это сообщение закрашивает внутреннюю область окна с использованием кисти, указанной в классе окна (при регистрации класса окна). Поэтому, если функция окна нарисует что-либо в окне во время обработки других сообщений, отличных от WM_PAINT, после прихода первого же сообщения WM_PAINT нарисованное изображение будет закрашено.
В этом случае, когда по логике работы приложения требуется изменить содержимое окна не во время обработки сообщения WM_PAINT, а в любом другом месте, приложения приложение должно сообщить Windows, что необходимо перерисовать часть окна или все окно. При этом в очередь приложения будет записано сообщение WM_PAINT, обработка которого приведет к нужному вам результату. Можно указать Windows, что был изменен прямоугольный участок окна или область произвольной формы, например эллипс или многоугольник. Для этого предназначены функции InvalidateRect и InvalidateRgn, которые мы рассмотрим позже.
Как функция окна может определить область окна, подлежащую обновлению при обработке сообщения WM_PAINT?
Для ответа на этот вопрос вспомним о втором параметре функции BeginPaint, который является указателем на структуру PAINTSTRUCT:
HDC BeginPaint(HWND hwnd, PAINTSTRUCT FAR * lpps);
Структура PAINTSTRUCT определена в файле windows.h следующим образом:
typedef struct tagPAINTSTRUCT
{
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[16];
} PAINTSTRUCT;
Поле hdc после вызова функции BeginPaint будет содержать идентификатор контекста отображения (тот же самый, что и возвращаемый самой функцией BeginPaint).
Начальные координаты и размер области, подлежащей обновлению в процессе обработки сообщения WM_PAINT, передаются через поле rcPaint. Это поле представляет собой структуру типа RECT, описывающую прямоугольную область:
typedef struct tagRECT
{
int left;
int top;
int right;
int bottom;
} RECT;
Поля left, top, right и bottom задают координаты области следующим образом:
Поле | Описание |
left | x-координата верхнего левого угла области |
top | y-координата верхнего левого угла области |
right | x-координата правого нижнего угла области |
bottom | y-координата правого нижнего угла области |
Координаты задаются в единицах измерения, называемых пикселами. Пикселы - это маленькие точки, из которых строится изображение. Приложение может определить размер любого своего окна или размер используемого шрифта при помощи специальных функций, которые мы рассмотрим позже.
Поле fErase структуры PAINTSTRUCT определяет необходимость стирания фона окна в области, подлежащей обновлению. Если это поле установлено в состояние TRUE, функция BeginPaint посылает функции окна сообщение WM_ERASEBKGND.
Как правило, сообщение WM_ERASEBKGND передается функции DefWindowProc, которая при получении этого сообщения перерисовывает фон соответствующей области окна (используя кисть, определенную при регистрации класса окна). Если поле fErase содержит значение FALSE, фон окна не изменяется.
Остальные поля структуры PAINTSTRUCT используются Windows, приложение не должно изменять их содержимое.
Если окно содержит несколько областей, подлежащих обновлению, приложение получает только одно сообщение WM_PAINT, в котором определена область, охватывающая все указанные выше области.
Рассмотрим некоторые функции, имеющие отношение к сообщению WM_PAINT.
Функция UpdateWindow имеет следующий прототип:
void UpdateWindow(HWND hwnd);
Эта функция посылает сообщение WM_PAINT функции окна, идентификатор которого задан в качестве параметра hwnd. Сообщение посылается в обход очереди сообщений приложения, и только в том случае, если для окна существует непустая область обновления. Если в окне обновлять нечего, сообщение WM_PAINT не посылается.
При помощи функции InvalidateRect вы можете объявить любую область окна как требующую обновления. Прототип функции:
void InvalidateRect(HWND hwnd, LPRECT lprc, BOOL fErase);
Первый параметр (hwnd) функции является идентификатором окна, для которого выполняется операция. Второй параметр (lprc) - дальний указатель на структуру типа RECT, определяющую прямоугольную область, подлежащую обновлению. Третий параметр (fErase) определяет необходимость стирания фона окна. Если этот параметр задан как TRUE, фон окна подлежит стиранию (см. поле fErase структуры PAINTSTRUCT).
Функция ValidateRect удаляет прямоугольную область из списка областей, подлежащих обновлению. Она имеет следующий прототип: