На этом шаге мы рассмотрим такое понятие, как области.
К сожалению, в класс TCanvas (его свойства и методы) не включена еще одна изобразительная возможность Windows - области (Regions). Области - такие же графические объекты, как перо, кисть, шрифт. Они образуются с помощью комбинации простейших геометрических фигур - прямоугольников, многоугольников, эллипсов. Замечательной особенностью областей является возможность создания с их помощью непрямоугольных кнопок, цветовых областей, окон. На рисунке 1 приведен пример такой формы.
Рис.1. Внешний вид приложения
А вот как оно было создано:
program Project1; uses Forms, Unit1 in 'Unit1.pas' {Form1}, Windows; // Этот модуль экспортирует функции API. {$R *.RES} var Rgn: Cardinal; begin //Сначала создаем обычное окно. Application.CreateForm(TForm1, Form1); with Form1.Canvas, Form1 do begin //Теперь создаем в нем эллиптическую область Rgn := CreateEllipticRgn(0, 0, Width, Height); //и показываем ее вместо окна. SetWindowRgn(Handle, Rgn, True); end; Application.Run; end.
Ниже перечислены основные функции для работы с областями.
Функция | Описание |
---|---|
function CombineRgn (DestRgn, Rgn1, Rgn2: Cardinal; CombineMode: Integer): Integer; | Объединяет две области в одну: DestRgn - дескриптор результирующей области; Rgn1, Rgn2 - дескрипторы объединяемых областей; CombineMode - параметр, указывающий способ объединения; этот параметр, а также возвращаемое значение описаны ниже. |
function CreateEllipticRgn (X1, Yl, X2, Y2: Integer) : Cardinal; | Создает эллиптическую область. |
function CreatePolygonRgn (var Points; Count, PolyFillMode: Integer): Cardinal; | Создает область в виде многоугольника: Points - массив координат всех вершин многоугольника; Count - количество вершин; PolyFillMode - режим заполнения многоугольника (см. ниже). |
function CreateRectRgn (X1, Yl, X2, Y2: Integer): Cardinal; | Создает прямоугольную область. |
function CreateRoundRectRgn (Xl, Yl, X2, Y2, X3, Y3: Integer): Cardinal; | Создает область со скругленными углами. |
function EqualRgn (Rgnl,Rgn2: Cardibal): Bool; | Проверяет эквивалентность двух областей. |
function FillRgn (DC, Rgn, Brush: Cardinal): Bool; | Закрашивает область кистью: DC - дескриптор канвы окна; Rgn - дескриптор области; Brush - дескриптор кисти. |
function FrameRgn (DC, Rgn, Brush: Cardinal; Width, Height: Integer): Bool; | Обводит (но не заполняет) область кистью высотой Height и шириной Width пикселей. |
function InvertRgn (DC, Rgn: Cardinal): Bool; | Инвертирует все пиксели внутри области. |
function OffsetRgn (DC, Rgn: Cardinal; dX, dY: Integer): Integer; | Смещает область на dX по горизонтали и на dY по вертикали. |
function PaintRgn (DC, Rgn: Cardinal): Bool; | Закрашивает область текущей кистью. |
function PtInRegion (Rgn: Cardinal; X, Y: Integer):Bool; | Проверяет принадлежность точки (X,Y) области Rgn. |
function RectInRegion (Rgn: Cardinal; Rect: TRect):Bool; | Проверяет принадлежность прямоугольника Rect области Rgn. |
function SetWindowRgn (DC, Rgn: Cardinal; Redraw: Bool): Integer; | Показывает принадлежащую окну с канвой DC область Rgn вместо окна; Redraw - разрешает/запрещает перерисовку области. Все не вошедшие в область части окна не показываются (см. ниже). |
Параметр CombineMode в функции CombineRgn может принимать следующие значения:
Область DestRgn уже должна существовать и иметь размеры, достаточные для размещения объединенной области.
При обращении к функции CreatePolygonRgn параметр PolyFillMode может иметь значения: Alternate и Winding. В первом случае заполнение многоугольника идет последовательно между двумя близлежащими его сторонами: сначала между 1-й и 2-й, затем между 2-й и 3-й и т. д. В режиме Winding заполняется все внутреннее пространство области.
Во всех случаях Windows автоматически проводит линию между последней и первой точкой многоугольника, делая его замкнутым.
Проиллюстрируем использование некоторых конструкций на примере. Расположим на форме два компонента TPaintBox и кнопку TButton. Обработчик нажатия на кнопку будет следующим:
procedure TForm1.Button1Click(Sender: TObject); var Rgn1, Rgn2: Cardinal; const Points: array [1..5, 1..2] of Integer = ((91, 0), (160, 183), (0, 70), (183, 70), (23, 183)); begin Rgn1:= CreatePolygonRgn(Points, 5, Alternate); Rgn2:= CreatePolygonRgn(Points, 5, Winding); with PaintBox1.Canvas do begin Brush.Color := clBlack; FillRgn(Handle, Rgn1, Brush.Handle); end; with PaintBox2.Canvas do begin Brush.Color:= clBlack; FillRgn(Handle, Rgn2, Brush.Handle) ; end; end;
Рис.2. Вид приложения после щелчка по
кнопке
Текст этого примера можно взять здесь.
Функция SetWindowRgn, как уже отмечалось, поручает прорисовку окна самой Windows, при этом фактически прорисовывается не область, а лишь та часть окна, которая ограничена ею. Любые заливки области, ее очерчивание и объединение с другими областями игнорируются.
На следующем шаге мы рассмотрим состав класса TPicture.