Шаг 43.
Графические инструменты в Delphi. Области

    На этом шаге мы рассмотрим такое понятие, как области.

    К сожалению, в класс 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.
Текст этого примера можно взять здесь.

    Ниже перечислены основные функции для работы с областями.
Таблица 1. Функции работы с областями
Функция Описание
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.


Рис.2. Вид приложения после щелчка по кнопке

    Текст этого примера можно взять здесь.


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

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

    На следующем шаге мы рассмотрим состав класса TPicture.




Предыдущий шаг Содержание Следующий шаг