Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ответы ПВС(47).doc
Скачиваний:
6
Добавлен:
15.04.2019
Размер:
276.48 Кб
Скачать

22) Системные метрики Windows.

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

Метрики системных компонент Windows можно определить при помощи функции GetSystemMetrics, имеющей следующий прототип:

int WINAPI GetSystemMetrics(int nIndex);

Единственный параметр функции (nIndex) выбирает параметр, значение которого необходимо определить. Значение параметра возвращается функцией GetSystemMetrics.

Для определения компоненты Windows в файле windows.h имеются символические константы с префиксом SM_:

Имя константы

Описание

SM_CXBORDER

Ширина рамки для окна, размеры которого нельзя изменять

SM_CXCURSOR

Ширина курсора

SM_CXDLGFRAME

Ширина рамки окна, имеющего стиль WS_DLGFRAME

SM_CXDOUBLECLK

Ширина прямоугольника, внутри которого должны быть сделаны два щелчка мышью, для того чтобы они могли распознаваться как один двойной щелчок (double click). Эта константа определена только для Windows версии 3.1

SM_CXFRAME

Ширина рамки для окна, размеры которого можно изменять

SM_CXFULLSCREEN

Ширина внутренней поверхности окна, увеличенного до предела (maximised)

SM_CXHSCROLL

Ширина битового образа стрелки горизонтальной полосы просмотра

SM_CXHTHUMB

Ширина ползунка горизонтальной полосы просмотра

SM_CXICON

Ширина пиктограммы

SM_CXICONSPACING

Ширина прямоугольника, используемого для расположения пиктограммы с заголовком. Эта константа определена только для Windows версии 3.1

SM_CXMIN

Минимальная ширина окна

SM_CXMINTRACK

Минимальная ширина окна, которая может быть установлена при помощи мыши (Minimum tracking width of a window)

SM_CXSCREEN

Ширина экрана

SM_CXSIZE

Ширина полосы битового образа (bitmap) заголовка окна (title bar)

SM_CXVSCROLL

Ширина битового образа стрелки вертикальной полосы просмотра

SM_CYBORDER

Высота рамки для окна, размеры которого нельзя изменять

SM_CYCAPTION

Высота заголовка окна

SM_CYCURSOR

Высота курсора

SM_CYDLGFRAME

Высота рамки окна, имеющего стиль WS_DLGFRAME

SM_CYDOUBLECLK

Высота прямоугольника, внутри которого должны быть сделаны два щелчка мышью, для того чтобы они могли распознаваться как один двойной щелчок (double click). Эта константа определена только для Windows версии 3.1

SM_CYFRAME

Высота рамки для окна, размеры которого можно изменять

SM_CYFULLSCREEN

Высота внутренней поверхности окна, увеличенного до предела (maximised)

SM_CYHSCROLL

Высота битового образа стрелки горизонтальной полосы просмотра

SM_CYICON

Высота пиктограммы

SM_CYICONSPACING

Высота прямоугольника, используемого для расположения пиктограммы с заголовком. Эта константа определена только для Windows версии 3.1

SM_CYKANJIWINDOW

Высота окна Kanji

SM_CYMENU

Высота одной строки в полосе меню

SM_CYMIN

Минимальная высота окна

SM_CYMINTRACK

Минимальная высота окна, которая может быть установлена при помощи мыши (Minimum tracking width of a window)

SM_CYSCREEN

Высота экрана

SM_CYSIZE

Высота полосы битового образа заголовка окна

SM_CYVSCROLL

Высота битового образа стрелки вертикальной полосы просмотра

SM_CYVTHUMB

Высота ползунка горизонтальной полосы просмотра

SM_DBCSENABLED

Флаг использования символов, состоящих из двух байт (используется в тех языках, где для представления всех символов не хватает 8-разрядной сетки). Эта константа определена только для Windows версии 3.1

SM_DEBUG

Флаг отладочной версии Windows. Он не равен нулю, если работает отладочная версия Windows (поставляется вместе с Microsoft SDK или Microsoft Visual C++)

SM_MENUDROPALIGNMENT

Флаг типа выравнивания временного меню (pop-up menu). Если флаг равен нулю, левая сторона меню выравнена по левой стороне соответствующего элемента строки меню. В противном случае левая сторона меню выравнена по правой стороне соответствующего элемента строки меню. Эта константа определена только для Windows версии 3.1

SM_MOUSEPRESENT

Флаг не равен нулю, если компьютер оборудован мышью

SM_PENWINDOWS

Идентификатор библиотеки динамической загрузки DLL Pen Windows или 0, если Pen Windows не используется. Эта константа определена только для Windows версии 3.1

SM_RESERVED1

Зарезервировано

SM_RESERVED2

Зарезервировано

SM_RESERVED3

Зарезервировано

SM_RESERVED4

Зарезервировано

SM_SWAPBUTTON

Если флаг не равен нулю, действия левой и правой клавиши мыши поменялись местами, то есть вместо левой клавиши используется правая и наоборот, вместо правой - левая

23) Сообщение WM_SIZE посылается окну после того, как его размер изменился.

Синтаксис

WM_SIZE

fwSizeType = wParam; // флажок изменения размеров

nWidth = LOWORD(lParam); // ширина рабочей области

nHeight = HIWORD(lParam); // высота рабочей области

Параметры

fwSizeType

Значение wParam. Определяет тип запрошенного изменения размеров. Этот параметр может принимать одно из следующих значений:

SIZE_MAXHIDE - Сообщение посылается всем выскакивающим окнам, когда развернуто некоторое другое окно.

SIZE_MAXIMIZED - Окно было развернуто.

SIZE_MAXSHOW - Сообщение посылается всем выскакивающим окнам, когда некоторое другое окно было восстановлено в его прежних размерах.

SIZE_MINIMIZED - Окно было свернуто(минимизировано).

SIZE_RESTORED - Окно было изменено, но ни одно значение SIZE_MINIMIZED ни SIZE_MAXIMIZED не применяется.

nWidth

Значение младшего слова lParam. Устанавливает новую ширину рабочей области.

nHeight

Значение старшего слова lParam. Устанавливает новую высоту рабочей области.

Возвращаемые значения

Если программа обрабатывает это сообщение, она должна возвратить ноль.

Замечания

Если функция SetScrollPos или MoveWindow вызвана для дочернего окна в результате сообщения WM_SIZE, параметр bRedraw должен отличаться от нуля, чтобы заставить окно быть перекрашенным. Хотя ширина и высота окна - 32-разрядные значения, параметры nWidth и nHeight сообщения WM_SIZE содержат только младшие 16 битов.

Сообщение WM_MOVE передается после того, когда окно будет перемещено.

Снтаксис

WM_MOVE

xPos = (int) LOWORD(lParam); // позиция по горизонтали

yPos = (int) HIWORD(lParam); // позиция по вертикали

Параметры

xPos

Значение младшего байта слова lParam. Устанавливает x-координату левого верхнего угла рабочей области окна.

yPos

Значение старшего слова lParam. Устанавливает y-координату левого верхнего угла рабочей области окна.

Возвращаемые значения-Если программа обрабатывает это сообщение, она должна возвратить ноль.

Замечания: xPos и yPos параметры даны в экранных координатах для перекрывающих и выскакивающих окон и в координатах пользователя - родителя для дочерних окон. Прикладная программа может использовать макрокоманду MAKEPOINTS, чтобы преобразовать параметр lParam для структуры POINTS.

Сообщение WM_SIZING посылается окну, у которого пользователь изменяет размеры. Обрабатывая это сообщение, прикладная программа может контролировать размер и позицию перетаскиваемого прямоугольника и, если необходимо, изменять его размер или позицию.

Синтаксис

fwSide = wParam; // край устанавливаемого по размеру окна

lprc = (LPRECT) lParam; // экранные координаты перетаскиваемого прямоугольника

Параметры:

fwSide

Значение wParam. Указывает, который край окна устанавливается по размеру. Этот параметр может быть комбинацией следующих значений:

WMSZ_BOTTOM - Нижний край

WMSZ_BOTTOMLEFT - Угол левой нижней части

WMSZ_BOTTOMRIGHT - Угол правой нижней части

WMSZ_LEFT - Левый край

WMSZ_RIGHT - Правый край

WMSZ_TOP - Верхний край

WMSZ_TOPLEFT - Угол левой верхней части

WMSZ_TOPRIGHT - Угол правой верхней части

lprc

Адрес структуры RECT с экранными координатами перетаскиваемого прямоугольника. Чтобы изменять размер или позицию перетаскивающегося прямоугольника, прикладная программа должна изменить члены этой структуры.

Возвращаемые значения--Прикладная программа должна возвратить ИСТИНА (TRUE), если она обрабатывает это сообщение.

24) Функция GetClientRect извлекает координаты рабочей области окна. Рабочие координаты определяют левый верхний и нижний правый углы рабочей области. Поскольку рабочие координаты определены относительно левого верхнего угла рабочей области окна, координаты левого верхнего угла - (0,0).

Синтаксис:

BOOL GetClientRect

(

HWND hWnd, // дескриптор окна

LPRECT lpRect // адрес структуры рабочих координат

);

Параметры:

hWnd

Идентифицирует окно, рабочие координаты которого должны быть возвращены.

lpRect

Указывает на структуру RECT, которая принимает рабочие координаты. Левые и верхние элементы - нулевые. Правые и нижние элементы содержат ширину и высоту окна.

Возвращаемые значения

Если функция завершается успешно, возвращаемое значение отлично от нуля. Если функция потерпит неудачу, возвращаемое значение нулевое. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Функция GetWindowRect отыскивает размеры рамки ограничивающей прямоугольник определяемого окна. Размеры даны в экранных координатах, которые расположены относительно левого верхнего угла экрана.

Синтаксис:

BOOL GetWindowRect

(

HWND hWnd, // дескриптор окна

LPRECT lpRect // адрес структуры для координат окна

);

Параметры:

hWnd

Идентифицирует окно.

lpRect

Указывает на структуру RECT которая принимает экранные координаты левых верхних и нижних правых углов окна.

Возвращаемые значения

Если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела неудачу, возвращаемое значение - ноль. Для получения подробной информации об ошибке вызовите функцию GetLastError.

25) стр80

26) стр 78(см 14)

27) стр 79нет

28) Всякий раз, когда пользователь перемещает мышь, щелкает по кнопке мыши или производит ввод с клавиатуры, драйвер устройства мыши или клавиатуры преобразуют ввод данных в сообщения и помещают их в системную очередь сообщений. Система удаляет сообщения от системной очереди по одному, проверяя их, чтобы установить окно назначения, а затем переправляет их в очереди сообщений потока, который создал окно назначения. Очередь сообщений потока принимает все сообщения мыши и клавиатуры для окон, созданных потоком. Поток удаляет сообщения из своей очереди и предписывает системе отправлять их в соответствующую оконную процедуру для обработки.

За исключением сообщения WM_PAINT, система всегда помещает сообщения в конец очереди сообщений. Это гарантирует то, что окно принимает свои входящие сообщения в полном соответствии с принципом "первым пришел", "первым вышел" (FIFO). Однако сообщение WM_PAINT, сохраняется в очереди и пересылается оконной процедуре только тогда, когда очередь не содержит никаких других сообщений. Несколько сообщений WM_PAINT для того же самого окна объединяются в одно единственное сообщение WM_PAINT, объединяющее все неисправные части рабочей области экрана в единственную область. Объединение сообщений WM_PAINT сокращает число раз, когда окно должно перерисовать содержимое своей рабочей области.

Система помещает сообщение в очередь сообщений потока, при помощи заполнения структуры MSG, а затем копирует ее в очереди сообщений. Информация в MSG включает в себя: дескриптор окна, для которого предназначено сообщение, код сообщения, два параметра сообщения, время, когда сообщение было поставлено в очередь и позицию курсора мыши. Поток может поместить сообщение в своей собственной очереди сообщений или в очередь другого потока, используя функцию PostMessage или PostThreadMessage.

Прикладная программа может удалять сообщение из своей очереди, используя функцию GetMessage. Чтобы проверить сообщение без удаления его из очереди, приложение может использовать функцию PeekMessage. Эта функция заполняет структуру MSG информацией о сообщении.

После удаления сообщения из его очереди, прикладная программа может использовать функцию DispatchMessage , чтобы предписать системе отправить сообщение оконной процедуре для обработки. DispatchMessage берет указатель на структуру MSG , которая была заполнена предыдущим вызовом функции GetMessage или PeekMessage. DispatchMessage передает дескриптор окна, код сообщения и два параметра сообщения оконной процедуре, но функция не передает время, когда сообщение было помещено в очередь или позицию курсора мыши.

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

В отличие от GetMessage, функция PeekMessage не ждет, когда предыдущее помещенное в очередь сообщение возвратит значение.

29) /25?? Стр 80

30) стр 61.контекст устройства-это его интерфейс для определенного графического устройства.Способы получения (и, соответственно, освобождения) контекста отображения разные для контекстов разного типа. Можно выделить следующие типы контекста отображения:

  • общий контекст отображения (common display context);

  • контекст отображения для класса окна (class display context);

  • личный контекст отображения (private display context);

  • родительский контекст отображения (parent display context);

  • контекст отображения для окна (window display context);

  • контекст физического устройства (device context);

  • информационный контекст (information context);

  • контекст для памяти (memory device context);

  • контекст для метафайла (metafile context).

Каждый из перечисленных выше контекстов имеет свои особенности и свое назначение.

Общий контекст отображения

Для получения общего контекста отображения приложение должно вызвать функцию BeginPaint (при обработке сообщения WM_PAINT ) или GetDC (при обработке других сообщений). При этом перед регистрацией класса окна в поле стиля класса окна в структуре WNDCLASS не должны использоваться значения CS_OWNDC , CS_PARENTDC или CS_CLASSDC :

wc.style = 0;

Функция BeginPaint возвращает контекст отображения для окна hwnd:

HDC WINAPI BeginPaint(HWND hwnd, PAINTSTRUCT FAR* lpps);

Перед этим она подготавливает указанное окно для рисования, заполняя структуру типа PAINTSTRUCT (адрес которой передается через параметр lpps) информацией, которую можно использовать в процессе рисования.

Обычно обработчик сообщения WM_PAINT выглядит следующим образом:

PAINTSTRUCT ps;

HDC hdc;

........

case WM_PAINT:

{

// Получаем контекст отображения

hdc = BeginPaint(hwnd, &ps);

// После получения контекста отображения

// можно вызывать функции GDI

TextOut(hdc, 0, 0, (LPSTR)"String", 6);

.

.

// Освобождаем контекст отображения

EndPaint(hwnd, &ps);

break;

}

Функции BeginPaint и EndPaint можно использовать только внутри обработчика сообщения WM_PAINT. Если же приложению требуется рисовать во время обработки других сообщений, оно должно получить контекст отображения с помощью функции GetDC . После завершения процедуры рисования перед выходом из обработчика сообщения следует освободить полученный контекст отображения, вызвав функцию ReleaseDC .

Функция GetDC возвращает контекст отображения для окна с идентификатором hwnd:

HDC WINAPI GetDC(HWND hwnd);

Полученный таким образом контекст отображения можно использовать для рисования во внутренней области окна (window client region).

Функция ReleaseDC освобождает контекст отображения hdc, полученный для окна hwnd:

int WINAPI ReleaseDC(HWND hwnd, HDC hdc);

Каждый раз, когда приложение получает общий контекст отображения, его атрибуты принимают значения по умолчанию, перечисленные нами ранее. Если перед выполнением рисования приложение изменит атрибуты контекста отображения, вызвав соответствующие функции GDI, в следующий раз при получении общего контекста отображения эти атрибуты снова примут значения по умолчанию. Поэтому установка атрибутов должна выполняться каждый раз после получения общего контекста отображения. Такая процедура отнимает дополнительное время, но она необходима при использовании контекста отображения этого типа.

Контекст отображения для класса окна

Однако вы можете создать такой контекст отображения, который хранится отдельно в единственном экземпляре и используется всеми окнами, созданными на базе класса окна. При регистрации такого класса окна вы должны указать стиль CS_CLASSDC :

wc.style = CS_CLASSDC;

Все окна, созданные на базе класса, имеющего стиль CS_CLASSDC, будут использовать один общий контекст отображения.

В отличие от общего контекста отображения, приложения, однажды получив контекст отображения для класса окна, могут не освобождать его. То есть для контекста этого типа после функций BeginPaint и GetDC можно не вызывать функции EndPaint и ReleaseDC. Если же приложение вызовет функцию EndPaint или ReleaseDC, они не будут ничего делать и сразу вернут управление. Для уменьшения вероятности ошибки мы рекомендуем вам всегда освобождать контекст отображения, даже если это и не требуется для данного типа контекста.

Несмотря на то, что для всех окон, созданных на базе класса стиля CS_CLASSDC, создается один контекст отображения, не следует думать, что приложение, однажды получив этот контекст, не должно получать его вновь при очередном вызове обработчика сообщения, выполняющего рисование.

Дело в том, что при получении контекста отображения для окна в нем устанавливаются атрибуты области ограничения и начало системы физических координат устройства отображения. Если на базе нашего класса создано несколько окон, при получении ими контекста отображения эти атрибуты "настраиваются" на окно, получившее контекст отображения. Но если на базе класса стиля CS_CLASSDC приложение создало только одно окно, оно может получить контекст отображения для класса окна один раз и не освобождать его.

Вы можете использовать его в тех случаях, когда по соображениям повышения производительности нежелательно выполнять настройку многочисленных атрибутов контекста отображения после каждого вызова функции BeginPaint или EndPaint. Эту настройку можно выполнить только один раз. Каждый раз, когда функция окна получает контекст отображения класса окна, в нем выполняется настройка только двух атрибутов - области ограничения и начала системы физических координат устройства вывода. Остальные атрибуты остаются без изменений и, следовательно, не требуют повторной настройки.

Личный контекст отображения

Указав в стиле класса окна значение CS_OWNDC , можно добиться того, что для каждого окна, созданного на базе такого класса, Windows создаст отдельную структуру контекста отображения:

wc.style = CS_OWNDC;

Личный контекст отображения можно, получив один раз, никогда не освобождать. Вы можете один раз настроить атрибуты контекста отображения сразу после получения самого контекста и использовать полученный контекст без изменений до завершения работы приложения.

Родительский контекст отображения

Родительский контекст отображения используется для дочерних окон. Он позволяет дочерним окнам "унаследовать" атрибуты контекста отображения у родительского окна, что во многих случаях упрощает процедуру настройки этих атрибутов. Например, дочернее окно может использовать для вывода текста тот же шрифт и цвета, что и родительское окно.

Для использования родительского контекста отображения в классе, на базе которого создается дочернее окно, перед регистрацией необходимо указать стиль CS_PARENTDC :

wc.style = CS_PARENTDC;

Контекст отображения для окна

Все описанные выше контексты отображения позволяют рисовать только во внутренней области окна (client region). С помощью функции GetWindowDC приложение может получить контекст отображения для окна , позволяющий рисовать в любом месте окна (в области заголовка окна, в области системного меню, рамки окна, кнопок изменения размера и т. п.).

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

Особенностью данного контекста является то, что в нем выбрана система координат, начало которой находится в левом верхнем углу окна (всего окна, а не его внутренней области).

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

Контекст физического устройства

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

В отличие от контекста отображения, контекст физического устройства не получается, а создается, для чего используется функция CreateDC :

HDC WINAPI CreateDC(

LPCSTR lpszDriver, // имя драйвера

LPCSTR lpszDevice, // имя устройства

LPCSTR lpszOutput, // имя файла или порта вывода

const void FAR* lpvInitData); // данные для инициализации

Параметр lpszDriver является указателем на строку символов, содержащую имя драйвера, обслуживающего физическое устройство. Имя драйвера совпадает с именем файла *.drv, содержащего сам драйвер и расположенного в системном каталоге Windows.

Имя устройства lpszDevice - это название самого устройства, описанное, например, в файле win.ini в разделе [devices].

Параметр lpszOutput указывает на структуру данных типа DEVMODE, используемую при инициализации устройства вывода. Если при работе с устройством нужно использовать параметры, установленные при помощи приложения Control Panel, параметр lpszOutput следует указать как NULL.

Более подробно вопросы работы с принтером будут рассмотрены в отдельной главе этого тома.

Контекст для устройства DISPLAY

В некоторых случаях требуется получить контекст отображения, позволяющий приложению рисовать в любом месте экрана дисплея. Такой контекст можно создать при помощи функции CreateDC, указав в качестве имени драйвера строку "DISPLAY ", а в качестве остальных параметров - значение NULL:

hdc = CreateDC("DISPLAY", NULL, NULL, NULL);

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

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

Есть еще два способа получения контекста для экрана.

Приложение может получить контекст отображения для всего экрана при помощи функции GetDC, указав в качестве параметра значение NULL:

hdc = GetDC(NULL);

Полученный таким образом контекст следует освободить после использования при помощи функции ReleaseDC, передав ей вместо идентификатора окна значение NULL:

ReleaseDC(NULL, hdc);

Еще один способ связан с использованием функции GetDCEx, описание которой будет приведено ниже.

Информационный контекст

Если приложению необходимо получить информацию об устройстве вывода (например, с помощью функции GetDeviceCaps) оно может создать вместо обычного информационный контекст . Информационный контекст нельзя использовать для рисования, однако он занимает меньше места в памяти.

Информационный контекст создается при помощи функции CreateIC , аналогичной по своим параметрам функции CreateDC:

HDC WINAPI CreateIC(

LPCSTR lpszDriver, // имя драйвера

LPCSTR lpszDevice, // имя устройства

LPCSTR lpszOutput, // имя файла или порта вывода

const void FAR* lpvInitData); // данные для инициализации

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

Контекст для памяти

В работе с битовыми изображениями bitmap часто используется такое "устройство вывода", как оперативная память. Приложение может полностью подготовить изображение в оперативной памяти, получив контекст для памяти , и затем быстро вывести готовое изображение на экран. Этот способ во многих случаях работает намного быстрее и приятнее для пользователя, чем формирование изображения непосредственно на экране.

Контекст для памяти создается совместимым с тем контекстом отображения, в котором будет выполняться вывод на физическое устройство. Для создания совместимого контекста используется функция CreateCompatibleDC :

HDC WINAPI CreateCompatibleDC(HDC hdc);

Созданный таким образом контекст памяти удаляется при помощи функции DeleteDC.

Использование контекста памяти будет подробно описано в главе, посвященной битовым изображениям bitmap.

Контекст для метафайла

Контекст для метафайла позволяет записывать команды GDI в файл и затем проигрывать такой файл на физическом устройстве вывода. Файл может находиться в памяти или на диске, в последнем случае его можно использовать для переноса графического изображения в другое приложение.

Для создания контекста метефайла используется функция CreateMetaFile :

HDC WINAPI CreateMetaFile(LPCSTR lpszFileName);

Параметр lpszFileName должен указывать на строку, содержащую путь к имени файла, в который будут записаны команды GDI, или NULL. В последнем случае создается метафайл в оперативной памяти.

После выполнения рисования в контексте метафайла следует закрыть метафайл, вызвав функцию CloseMetaFile :

HMETAFILE WINAPI CloseMetaFile(HDC hdc);

Эта функция закрывает метафайл для контекста hdc и возвращает идентификатор метафайла. Идентификатор закрытого метафайла использовать нельзя, так как он не содержит никакой полезной информации.

Что можно сделать с полученным идентификатором метафайла?

Можно скопировать метафайл в обычный дисковый файл, вызвав функцию CopyMetaFile :

HMETAFILE WINAPI CopyMetaFile(HMETAFILE hmf,

LPCSTR lpszFileName);

Параметр hmf определяет метафайл, параметр lpszFileName содержит путь к имени файла, в который будет записан метафайл .

Можно проиграть метафайл в контексте отображения или контексте устройства, вызвав функцию PlayMetaFile :

BOOL WINAPI PlayMetaFile(HDC hdc, HMETAFILE hmf);

Наконец, при помощи функции DeleteMetaFile можно удалить метафайл:

BOOL WINAPI DeleteMetaFile(HMETAFILE hmf);

Удаление метафайла с помощью функции DeleteMetaFile делает недействительным идентификатор метафайла hmf и освобождает оперативную память, занятую метафайлом. Если метафайл был создан как обычный дисковый файл, функция DeleteMetaFile не удаляет его с диска.

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

HMETAFILE WINAPI GetMetaFile(LPCSTR lpszFileName);

Функция GetDCEx

В программном интерфейсе операционной системы Windows версии 3.1 появилась функция GetDCEx , предоставляющая расширенные возможности для получения контекста отображения:

HDC WINAPI GetDCEx(register HWND hwnd,

HRGN hrgnClip, DWORD flags);

Функция возвращает идентификатор полученного контекста отображения или NULL при ошибке.

Параметр hwnd задает идентификатор окна, для которого необходимо получить контекст отображения.

С помощью параметра hrgnClip можно определить область ограничения вывода. Эта область может иметь произвольную форму и являться комбинацией нескольких областей ограничения. Использование областей ограничения будет подробно описано дальше в этой главе.

31) стр 148

32) ?

33) Функция InvalidateRect добавляет прямоугольник к обновляемому региону заданного окна. Обновляемый регион представляет часть рабочей области окна, которая должна быть перерисована.

Синтаксис

BOOL InvalidateRect(

HWND hWnd, // дескриптор окна

CONST RECT* lpRect, // координаты прямоугольника

BOOL bErase // состояние очистки

);

Параметры:

hWnd

[in] Дескриптор окна, обновляемый регион которого изменился. Если этот параметр - NULL, система делает недействительными и перерисовывает все окна, и отправляет сообщения WM_ERASEBKGND и WM_NCPAINT оконной процедуре перед тем, как возвращает значения функцией.

lpRect

[in] Указатель на структуру RECT, содержащую в себе координаты рабочей области прямоугольника, который будет добавлен к обновляемому региону. Если этот параметр - NULL, вся рабочая область добавляется к обновляемому региону.

bErase

[in] Устанавливает, должен ли фон внутри обновляемого региона быть стерт, когда обновляемый регион обрабатывается. Если этот параметр - TRUE, то фон стирается, когда вызывается функция BeginPaint. Если этот параметр - FALSE, фон остается неизменным.

Возвращаемые значения:

Если функция завершается успешно, возвращаемое значение - не нуль.Если функция завершается ошибкой, возвращаемое значение - нуль.

Функция UpdateWindow обновляет рабочую область заданного окна, отправляя сообщение WM_PAINT окну, если регион обновления окна не пуст. Функция отправляет сообщение WM_PAINT непосредственно оконной процедуре указанного окна, обходя очередь приложения. Если регион обновления пуст, никакое сообщение не отправляется.

Синтаксис

BOOL UpdateWindow(

HWND hWnd // дескриптор окна

);

Параметры:

hWnd

[in] Дескриптор обновляемого окна.

Возвращаемые значения

Если функция завершается успешно, возвращаемое значение - не нуль.Если функция завершается ошибкой, возвращаемое значение - нуль.

Вы можете сказать, что тоже самое можно сделать с помощью InvalidateRect(). А вот и не совсем так. Сообщение перерисовки посылается непосредственно в оконную процедуру минуя очередь сообщений, то есть обновление происходит сразу без задержки, которая может возникнуть в результате интенсивного ввода информации пользователем.

34) (стр 63). GDI — это интерфейс Windows для представления графических объектов и передачи их на устройства отображения, такие как мониторы и принтеры.

Для определения атрибутов текста и изображения, которые выводятся на экран или принтер, используется программный объект под названием «контекст устройства» (Device Context, DC). DC, как и большинство объектов GDI, инкапсулирует подробности реализации и данные в себе и к ним нельзя получить прямой доступ.

Для любого рисования нужен объект HDC (хэндл DC). При выводе на принтер HDC получается вызовом CreateDC, и на нем зовутся специальные функции для перехода на новую страницу печатаемого документа. При выводе на экран также можно использовать CreateDC, но это приведет к рисованию поверх всех окон вне их границ, потому обычно для рисования на экране используются вызовы GetDC и BeginPaint, принадлежащие уже не GDI, а USER, и возвращающие контекст, ссылающийся на регион отсечения окна.

Функционал:

  • вывод одними и теми же вызовами на экран, принтер, «экран в памяти» (доступный приложению по указателю и созданный им bitmap в памяти, также возможно выделение bitmapов в памяти видеокарты — CreateCompatibleBitmap — и рисование на них, такие битовые карты не доступны по указателю, но дальнейшая перерисовка с них на физический экран происходит очень быстро без нагрузки процессора и шины, и особенно быстро в случае Remote Desktop).

  • вывод в метафайл — запоминание последовательности команд рисования в файле, можно проиграть заново, векторный графический файл .wmf есть именно этот метафайл с небольшим дополнительным заголовком в начале.

  • вывод текста различными шрифтами

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

  • богатый набор операций векторной графики

  • все цвета в вызовах — всегда в RGB, независимо от системы цветов текущего устройства

35) последовательности действий:

  1. получение или создание контекста отображения;

  2. установка необходимых атрибутов в контексте отображения;

  3. выполнение операций рисования;

  4. освобождение или удаление контекста отображения.

Несмотря на все разнообразие способов создания объектов GDI, существует лишь один метод их удаления. Все объекты, созданные по методам CreateXXXX (CreatePen, CreateBrushIndirect, …) должны быть удалены методом DeleteObject. Для объектов, полученных по GetStockObject или CGdiObject::CreateStockObject вызывать DeleteObject необязательно, хотя ошибкой это не является.

Напр. BOOL DeleteObject (HGDIOBJ hgdiObj);

36)

37) Выбор встроенного шрифта

По умолчанию в контекст отображения при его создании выбирается системный шрифт, основным (и почти единственным) преимуществом которого является то, что он всегда доступен. Системный шрифт не является масштабируемым, содержит буквы переменной ширины, не имеющие засечек, для него используется кодировка ANSI.

Однако в некоторых случаях вам может понадобиться шрифт с фиксированной шириной букв, или шрифт в кодировке OEM. Вы можете получить идентификатор одного из встроенных шрифтов при помощи макрокоманды GetStockFont , описанной в файле windowsx.h:

#define GetStockFont(i) ((HFONT)GetStockObject(i))

После того как вы получили идентификатор шрифта, этот шрифт можно выбрать в контекст отображения макрокомандой SelectFont :

#define SelectFont(hdc, hfont) \

((HFONT)SelectObject((hdc), (HGDIOBJ)(HFONT)(hfont)))

Первый параметр этой макрокоманды определяет идентификатор контекста отображения, в который выбирается шрифт с идентификатором hfont. Она возвращает идентификатор шрифта, который был выбран в контекст отображения раньше, до вызова SelectFont.

Определение логического шрифта

Приложение может получить идентификатор шрифта, указав его параметры (такие как размеры символов, семейство шрифта, наклон относительно горизонтальной оси и т. п.) функции CreateFont . Эта функция имеет 14 параметров, поэтому не слишком удобна в использовании. Вместо нее лучше пользоваться функцией CreateFontIndirect :

HFONT WINAPI CreateFontIndirect(const LOGFONT FAR* lplf);

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

В качестве параметра функции CreateFontIndirect передается указатель на структуру типа LOGFONT , определенную в файле windows.h:

typedef struct tagLOGFONT

{

int lfHeight; //Высота шрифта в логических единицах. Если указано нулевое значение, выбирается шрифт размером в 12 пунктов (значение по умолчанию).

int lfWidth; // Ширина символов в логических единицах.Если указано нулевое значение, используется значение по умолчанию, которое зависит от высоты шрифта и отношения масштабов по осям

int lfEscapement; // Угол между базовой линией шрифта и координатной осью X в десятых долях градуса

int lfOrientation; // Это поле определяет ориентацию символов шрифта. операционная система Windows версии 3.1 игнорирует поле lfOrientation

int lfWeight; // Определяет жирность символов шрифта.( FW_DONTCARE-0, FW_NORMAL-400, FW_BOLD-700,до 1000)

BYTE lfItalic; //если не 0,то курсор

BYTE lfUnderline; // не равно нулю, запрашивается шрифт с подчеркиванием

BYTE lfStrikeOut;

BYTE lfCharSet;

BYTE lfOutPrecision;

BYTE lfClipPrecision;

BYTE lfQuality;

BYTE lfPitchAndFamily;

char lfFaceName[LF_FACESIZE];

} LOGFONT;

typedef LOGFONT* PLOGFONT;

typedef LOGFONT NEAR* NPLOGFONT;

typedef LOGFONT FAR* LPLOGFONT;

Перед вызовом функции CreateFontIndirect вы должны заполнить структуру LOGFONT нужными значениями, определяющими параметры шрифта. В неиспользованные поля следует записать нулевые значения. Можно записать нулевые значения во все поля, однако это едва ли имеет смысл.

Выбор созданного шрифта в контекст отображения

Если вы заполнили все нужные поля в структуре LOGFONT и затем передали адрес структуры функции CreateFontIndirect, эта функция вернет идентификатор шрифта. Вы должны выбрать шрифт с этим идентификатором в контекст отображения с помощью макрокоманды SelectFont (точно так же, как для встроенных шрифтов):

hfontOldFont = SelectFont(hdc, hfont);

Как только в созданном шрифте отпадет необходимость, его следует удалить при помощи макрокоманды DeleteFont , предварительно выбрав в контекст отображения тот шрифт, который был выбран в него раньше:

#define DeleteFont(hfont) \

DeleteObject((HGDIOBJ)(HFONT)(hfont))

Функция ChooseFont

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

DLL-библиотека commdlg.dll содержит функцию ChooseFont , специально предназначенную для выбора одного из зарегистрированных в системе шрифтов. Эта функция выводит на экран диалоговую панель "Font", с помощью которой пользователь может выбрать шрифт, стиль шрифта, размер шрифта.

BOOL WINAPI ChooseColor(CHOOSEFONT FAR* lpcf);

Единственный параметр функции является указателем на структуру типа CHOOSEFONT. Эта структура, а также сама функция ChooseFont, определены в файле commdlg.h.

38)стр86. Оконная процедура окна, которое имеет фокус клавиатуры, принимает сообщения о нажатии клавиши, когда пользователь печатает на клавиатуре. Сообщения о нажатии клавиши - WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN и WM_SYSKEYUP. Типичная оконная процедура игнорирует все сообщения о нажатии клавиши кроме WM_KEYDOWN. Windows посылает сообщение WM_KEYDOWN, когда пользователь нажимает клавишу.

Когда оконная процедура принимает сообщение WM_KEYDOWN, она должна проверить код виртуальной клавиши, который сопровождает сообщение, чтобы установить, как обработать нажатие клавиши. Код виртуальной клавиши находится в параметре wParam сообщения. Как правило, приложение обрабатывает только нажатия клавиши, сгенерированные не символьными клавишами, включая функциональные клавиши, клавиши управления курсором, и клавиши специального назначения типа INS, DEL, HOME и END.

Счетчик повторений

Вы можете проверить счетчик повторений, чтобы определить, представляет ли сообщение нажатия клавиши больше чем одно нажатие. Система увеличивает счетчик, когда клавиатура генерирует сообщения WM_KEYDOWN или WM_SYSKEYDOWN быстрее, чем прикладная программа может обрабатывать их. Это часто происходит тогда, когда пользователь удерживает нажатой клавишу достаточно долго, чтобы запустить функцию автоматического повторения клавиатуры. Вместо заполнения системной очереди сообщениями, происходящими в результате нажатия клавиши, система объединяет сообщения в единственное сообщение нажатой клавиши и увеличивает счет повторений. Отпуск клавиши не может запустить функцию автоматического повторения, так что счет повторений для сообщений WM_KEYUP и WM_SYSKEYUP всегда устанавливается в 1.

Флажок предыдущего состояния клавиши

Флажок предыдущего состояния клавиши указывает, была ли клавиша, которая генерировала сообщение о нажатии, перед этим нажата или отпущена. Он будет 1, если клавиша в предыдущем состоянии была нажата и 0, если клавиша в предыдущем состоянии была отпущена. Вы можете использовать этот флажок, чтобы идентифицировать сообщения нажатия клавиши, сгенерированные автоматической функцией повторения клавиатуры. Этот флажок установлен в 1 для сообщений WM_KEYDOWN и WM_SYSKEYDOWN нажатия клавиши, сгенерированных автоматической функцией повторения. Он всегда устанавливается в 0 для сообщений WM_SYSKEYUP и WM_KEYUP.

Флажок переходного состояния

Флажок переходного состояния указывает, что генерировало сообщение нажатия клавиши - либо нажатие клавиши или отпуск её. Этот флажок всегда устанавливается в 0 для сообщений WM_SYSKEYDOWN и WM_KEYDOWN; он всегда устанавливается в 1 для сообщений WM_SYSKEYUP и WM_KEYUP.

39) стр87.

40) стр 89

41)стр. 91

42)тср 91 Операционная система позволяет поддерживать большое число национальных клавиатур, алфавит которых может значительно отличаться друг от друга. В связи с этим, нажатие одной и той же клавиши может означать нажатие разных символов, определяемых выбранным в данный момент драйвером клавиатуры. Данное преобразование выполняет функция TranslateMessage, которая преобразует аппаратные сообщения в символьные, используя при этом состояние управляющих клавиш и драйвер клавиатуры. Обычно это происходит в цикле обработки сообщений:

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

{TranslateMessage(&msg);

DispatchMessage(&msg);}

Функция TranslateMessage является своеобразным диспетчером сообщений. Если очередное сообщение, выбранное функцией GetMessage из очереди сообщений, является символьным, то TranslateMessage ставит в очередь сообщений к приложению еще одно сообщение – символьное. При этом, аппаратное сообщение продолжает свой путь в цикле обработки сообщений и попадает в оконную процедуру окна приложения через функцию DispatchMessage. Аналогично аппаратным сообщениям, существует четыре символьных сообщения:

Несистемные символьные сообщения WM_CHAR WM_DEADCHAR

Системные символьные сообщения WM_SYSCHAR WM_DEADCHAR

43)стр 91 функция TranslateMessage

44)=42??

45)стр 92

46) При регистрации класса окна мы задавали форму курсора следующим способом:

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

Второй параметр функции LoadCursor в нашем случае выбирает одну из предопределенных форм курсора, а именно стандартный курсор в виде стрелки. Возможные значения для выбора предопределенных форм курсора представлены ниже.

Символическое имя Описание

IDC_ARROW Стандартный курсор в виде стрелки

IDC_CROSS Курсор в виде перекрещивающихся линий

IDC_IBEAM Текстовый курсор в виде буквы "I"

IDC_ICON Пустая пиктограмма

IDC_SIZE Курсор в виде четырех стрелок, указывающих в разных направлениях

IDC_SIZENESW Двойная стрелка, указывающая в северо-восточном и юго-западном направлении

IDC_SIZENS Двойная стрелка, указывающая в севером и южном направлении

IDC_SIZENWSE Двойная стрелка, указывающая в северо-западном и юго-восточном направлении

IDC_SIZEWE Двойная стрелка, указывающая в восточном и западном направлении

IDC_UPARROW Вертикальная стрелка

IDC_WAIT Курсор в виде песочных часов

вы можете создать курсор произвольной формы с помощью такого средства, как Borland Resource Workshop или Microsoft SDK. В этом случае вы должны нарисовать курсор в виде небольшой картинки, состоящей из отдельных точек. Эта картинка создается специальным графическим редактором и сохраняется в файле с расширением .cur. Затем файл подключается к ресурсам приложения, которые записываются в исполняемый exe-файл. Каждый ресурс в файле имеет свой идентификатор. Вы можете изменить форму курсора, если укажете идентификатор ресурса, соответствующего новому изображению курсора.

Для того чтобы можно было изменить форму курсора, прежде всего надо загрузить новый курсор при помощи функции LoadCursor, которая входит в программный интерфейс Windows:

HCURSOR WINAPI LoadCursor(HINSTANCE hinst,

LPCSTR lpszCursor);

Для загрузки нового курсора из ресурсов приложения в качестве первого параметра (hinst) необходимо указать идентификатор приложения, полученный через параметры функции WinMain. Второй параметр (lpszCursor) при этом должен указывать на идентификатор ресурса.

Если же в качестве первого параметра указать значение NULL, для загрузки курсора можно использовать перечисленные выше символические имена с префиксом IDC_. Именно так мы и поступаем при регистрации класса окна:

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

Функция LoadCursor возвращает идентификатор загруженного курсора или NULL при ошибке.

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

HCURSOR WINAPI SetCursor(HCURSOR hcur);

Параметр hcur функции SetCursor должен указывать идентификатор нового курсора, подготовленный при помощи функции LoadCursor. Если указать параметр как NULL, изображение курсора исчезнет с экрана.

Для того чтобы выключить изображение курсора мыши или вновь включить его, используют функцию ShowCursor:

int WINAPI ShowCursor(BOOL fShow);

Функция управляет содержимым счетчика, который используется для определения момента включения или выключения изображения курсора мыши. Первоначально содержимое счетчика равно нулю. Этот счетчик увеличивается, когда необходимо включить курсор, и уменьшается при выключении курсора. Если счетчик больше или равен нулю, курсор мыши находится во включенном (видимом) состоянии.

Для включения курсора в качестве параметра fShow функции следует передать значение TRUE, для выключения - FALSE.

Возвращаемое функцией ShowCursor значение равно новому содержимому счетчика.

Наблюдая за работой стандартных приложений Windows, вы можете заметить, что часто на время выполнения длительных операций курсор принимает форму песочных часов. Как правило, все такие операции выполняются во время обработки какого-либо одного сообщения. Перед началом выполнения операции вы можете вызвать функцию LoadCursor с параметром IDC_WAIT, а затем вернуть прежнюю форму, вызвав эту же функцию еще раз. Дополнительно на время выполнения операции обработчик сообщения должен захватить мышь, вызвав функцию SetCapture. В этом случае вы не сможете с помощью мыши переключиться на другое приложение и прервать таким образом ход длительной операции. После выполнения операции следует освободить мышь, вызвав функцию ReleaseCapture.

Ваше приложение может установить курсор мыши в новое положение или определить текущие координаты курсора.

Для установки курсора мыши в новое положение следует вызвать функцию SetCursorPos:

void WINAPI SetCursorPos(int x, int y);

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

Для определения текущих экранных координат курсора мыши необходимо использовать функцию GetCursorPos:

void WINAPI GetCursorPos(POINT FAR* lppt);

Эта функция записывает в поля x и y структуры типа POINT соответственно горизонтальную и вертикальную координату курсора мыши.

Существует редко используемая возможность ограничения перемещения курсора прямоугольной областью. Для ограничения свободы перемещения курсора следует использовать функцию ClipCursor:

void WINAPI ClipCursor(const RECT FAR* lprc);

В качестве параметра lprc функции передается указатель на структуру типа RECT, в которой указываются координаты области ограничения. Как только необходимость в ограничении пропадет, следует освободить движение мыши, вызвав функцию ClipCursor с параметром NULL.

Программный интерфейс Windows версии 3.1 содержит функцию GetClipCursor, с помощью которой можно определить расположение и размер области, ограничивающей движение курсора:

void WINAPI GetClipCursor(RECT FAR* lprc);

В качестве параметра lprc функции передается указатель на структуру типа RECT, в которую будут записаны координаты области ограничения.