Области
К сожалению, в класс TCanvas не включена еще одна изобразительная возможность Windows - области (Regions). Области - такие же графические объекты, как перо, кисть, шрифт. Они образуются с помощью комбинации простейших геометрических фигур - прямоугольников, многоугольников, эллипсов. Замечательной особенностью областей является возможность создания с их помощью непрямоугольных кнопок, цветовых областей, окон. А вот как оно было создано:
uses Forms, Unit1 in 'Unitl.pas' {Formi}, Windows; // Этот модуль экспортирует функции API
{$R *.RES}
var Rgn: Cardinal; begin // Сначала создаем обычное окно: Application.CreateForm(Tform1, Form1); with Formi.Canvas, Formi do begin // Теперь создаем в нем эллиптическую область Rgn := CreateEllipticRgn(0, 0, Width, Height); // и показываем ее вместо окна SetWindowRgn(Handle, Rgn, True); end; Application.Run; end.
Ниже перечислены основные функции для работы с областями.
Работа с областями
Работа с областями function CombineRgn(DestRgn, Rgnl, Rgn2: Cardinal; Com-bineMode: Ineger): Integer; | Объединяет две области в одну: DestRgn - дескриптор результирующей области; Rgnl, Rgn2 -дескрипторы объединяемых областей; CombineMode - параметр, указывающий способ объединения; этот параметр, а также возвращаемое значение описаны ниже | function CreateEllipticRgn(XI, Yl, X2, Y2: Integer) : Cardinal; | Создает эллиптическую область | function CreatePoly-gonRgn(var Points; Count, PolyFillMode: Integer): Cardinal; | Создает область в виде многоугольника: Points - массив координат всех вершин многоугольника; Count - количество вершин; PolyFillMode -режим заполнения многоугольника (см. ниже) | function CreateRectRgn(XI, 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: Cardina; Redraw: Bool): Integer | Показывает принадлежащую окну с канвой DC область Rgn вместо окна; Redraw- разрешает/запрещает перерисовку области; все не вошедшие в область части окна не показываются (см. ниже) |
Параметр combineMode в функции combineRgn может значения:
rgn_and - включает в результат общие части областей; rgn_copy -копирует область Rgnl В DestRgn; RGN_DIFF - исключает изRgnl часть, принадлежащую Rgn2; rgn_or - объединяет области; rgn_xor -включает в результат только те части областей, которые не принадлежат им одновременно. Область DestRgn уже должна существовать и иметь размеры, достаточные для размещения объединенной области. При обращении к функции createPoiygonRgn параметр Poly FillMode может иметь значения: Alternate И Winding. В первом случае заполнение многоугольника идет последовательно между двумя близлежащими его сторонами: сначала между 1-й и 2-й, затем между 2-й и 3-й и т. д. В режиме winding заполняется все внутреннее пространство области.
Во всех случаях Windows автоматически проводит линию между последней и первой точкой многоугольника, делая его замкнутым.
unit Unit1; interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; tуре Tform1 = class (TForm) PaintBoxl: TPaintBox; PaintBox2: TPaintBox; Button1: TButton;
procedure ButtonlClick(Sender: TObject);
private { Private declarations }
public { Public declarations } end;
var Form1: Tform1;
implernentation
$R *.DFM)
procedure TFormI.ButtonlClick(Sender: TObject);
var Rgnl, Rgn2: Cardinal;
const Points: array [1..5, 1..2] of Integer = C(91, 0), (160, 183), (0, 70), (183, 70), (23, 183));
begin Rgn1 := CreatePolygonRgn(Points, 5, Alternate); Rgn2 := CreatePolygonRgn(Points, 5, Winding); with PaintBoxl.Canvas do begin Brush.Color := clBlack; FillRgn(Handle, Rgnl, Brush.Handle); end; with PaintBox2.Canvas do begin Brush.Color := clBlack; FillRgn(Handle, Rgn2, Brush.Handle) ; end; end;
end.
Обратите внимание: прорисовка и объединение областей доступны, только если области видны в окне (для создания предыдущего рисунка нельзя, например, использовать обработчик формы OnActivate).
Функция SetWindowRgn, как уже отмечалось, поручает прорисовку окна самой Windows, при этом фактически прорисовывается не область, а лишь та часть окна, которая ограничена ею. Любые заливки области, ее очерчивание и объединение с другими областями игнорируются.
1 2 3
8 8 8
| |