|
Как уже сказано ранее (Урок №4) графический интерфейс устройства (GDI) - подсистема Windows, которая отвечает за отображение графики (в том числе и текста, т.к. текст также прорисовывается) на устройствах отображения (дисплеях и принтерах). Не только Вы в своих программах будете использовать GDI, но и сама Windows применяет его для отображения элементов пользовательского интерфейса.
Программисты, привыкшие писать программы под DOS, очень часто пользовались возможностью выводить информацию прямо в видеопамять, минуя стандартные функции какой-то определенной среды программирования. Это часто работало значительно быстрее (даже на старых компьютерах типа AT286). Хотя в Windows-95 прямой вывод в видеопамять в принципе возможен (в отличие от NT, в которой это невозможно в принципе), делая это Вы не получите никаких преимуществ. Кроме того, в этом случае Ваша программа сможет работать только под Windows-3x/Windows-9x.
Физически все функции GDI находятся в файлах SYSTEM/GDI*.DLL, GDI*.EXE. Эти функции обращаются к драйверам устройств вывода (таким, как дисплей или принтер). Это позволяет использовать одни и те же функции рисования для вывода на различные устройства. Естественно, для каждого устройства (скажем, цветного ксерокса, подключенного к LPT-порту компьютера через специальный адаптер) потребуется установить свой драйвер (их обычно поставляет производитель данного устройства).
Типы функций GDI
- Функции, которые получают, создают, освобождают или уничтожают контекст устройства (напр. BeginPaint, GetDC, CreateDC и др.)
- Функции, которые получают информацию об устройстве (напр. GetTextMetrics).
- Функции рисования (напр. TextOut).
- Функции, которые устанавливают/получают атрибуты контекста устройства. Например, функция SetTextColor используется для того, чтобы установить определенный цвет текста, выводимого с помощью TextOut. Для всех функций Set... имеются аналогичные функции Get..., которые позволяют получить текущее значение конкретного атрибута.
- Функции, которые работают с объектами GDI. Речь идет вот о чем. Когда Вы хотите нарисовать, например, линию, сначала нужно создать логический объект - перо (напр. с помощью CreatePen). Затем нужно выбрать это перо в контекст устройства (подобно тому, как художник берет рукой карандаш требуемого цвета). Это делается с помощью вызова SelectObject. После того, как линия нарисована и логический объект (в данном случае перо) уже не нужен, он удаляется (с помощью DeleteObject).
Получение описателя контекста устройства
Хотя об этом уже шла речь ранее, здесь мы рассмотрим данный вопрос более подробно.
Дескриптор контекста устройства можно получить несколькими способами.
- При обработке сообщения WM_PAINT (здесь должна выполняться основная часть рисования, иначе Ваша программа будет сложной как для разработки, так и для понимания) всегда пользуйтесь парой функций:
hdc=BeginPaint(hWnd, &ps);
... здесь выполняется рисование ...
EndPaint(hWnd, &ps);
Переменная ps - это структура типа PAINTSTRUCT. Поле hdc этой структуры - это описатель контекста устройства, который возвращается функцией BeginPaint. Поэтому Вы можете не объявлять отдельную переменную hdc, а использовать вместо этого ps.hdc. Структура PAINTSTRUCT содержит внутри себя еще одну структуру - rcPaint (типа RECT), которая определяет прямоугольную область, требующую перерисовки. Получив описатель контекста устройства от функции BeginPaint, Вы сможете рисовать только в пределах этой области. Вызов функция BeginPaint делает этот регион действительным.
- Если Вам нужно рисовать при поступлении сообщения, отличного от WM_PAINT, получайте дескриптор контекста устройства следующим образом:
hdc=GetDC(hWnd);
... здесь выполняется рисование ...
ReleaseDC(hWnd, hdc);
При получении дескриптора контекста устройства данным способом Вы сможете рисовать во всей рабочей области окна. В отличие от BeginPaint функция GetDC не делает действительной рабочую область окна.
- Если Вам нужно рисовать во всей области окна, а не только в клиетской области, получайте hdc так:
hdc=GetWindowDC(hWnd);
... здесь выполняется рисование ...
ReleaseDC(hWnd, hdc);
Полученный таким образом дескриптор контекста устройства позволит рисовать не только в клиентской области, но и в области заголовка, меню, полос прокрутки и рамки окна. Функция GetWindowDC редко используется программистами. Можно, например использовать ее для того, чтобы перерисовать рамку окна (если, скажем Вы хотите сделать ее цветной). Желающие поэкспериментировать могут обрабатывать сообщение WM_NCPAINT, которое генерируется Windows тогда, когда нужно перерисовать неклиентскую область окна.
- Более общая функция для получения контекста устройства - CreateDC:
hdc=CreateDC(sDriver, sDevice, sOutput, pData);
... здесь выполняется рисование ...
DeleteDC(hdc);
Например, для получения дескриптора контекста всего дисплея можно сделать так:
hdc=CreateDC("DISPLAY", NULL, NULL, NULL);
- В некоторых случаях Вам достаточно только получить некоторую информацию о контексте устройства, и не надо ничего рисовать. В этих случаях получайте так называемый информационный контекст, например:
hdc=CreateIC("DISPALY", NULL, NULL, NULL);
... ...
DeleteDC(hdc);
Вы не сможете осуществлять вывод на устройство, используя информационный контекст.
- При работе с битовыми картами может быть полезно получить контекст памяти:
hdcMem=CreateCompatibleDC(hdc);
... ...
DeleteDC(hdcMem);
Об использовании битовых карт будет рассказано позднее.
- Вы можете создать контекст для метафайла. Метафайл - это набор вызовов функций GDI в двоичном виде. Метафайлы широко используются для передачи векторной графики через буфер обмена. В дальнейшем мы обсудим это более подробно.
Вы можете создать метафайл так:
hdcMeta=CreateMetaFile(sFileName);
... вызов функций GDI, ...
... которые рисуют в метафайле ...
hmf=CloseMetaFile(hdcMeta);
После получения контекста метафайла (hdcMeta), весь вывод графики будет осуществляться в метафайл. Когда Вы вызываете CloseMetaFile, описатель контекста метафайла (hdcMeta) становится недействительным.
|