В приведенном ниже обработчике события FormCreate создается окно в форме эллипса с тремя кнопками такой же формы (листинг 1.10).
Листинг 1.10. Окно и кнопки в форме эллипсовprocedure TfrmElliptic.FormCreate(Sender: TObject);
var
formRgn, but1Rgn, but2Rgn, but3Rgn: HRGN;
begin
//Создаем регионы кнопок
but1Rgn:= CreateEllipticRgn(0, 0, Button1.Width1, Button1.Height1);
SetWindowRgn(Button1.Handle, but1Rgn, False);
but2Rgn:= CreateEllipticRgn(0, 0, Button2.Width1, Button2.Height1);
SetWindowRgn(Button2.Handle, but2Rgn, False);
but3Rgn:= CreateEllipticRgn(0, 0, Button3.Width1, Button3.Height1);
SetWindowRgn(Button3.Handle, but3Rgn, False);
//Регион для окна
formRgn:= CreateEllipticRgn(0, 0, Width1, Height1);
SetWindowRgn(Handle, formRgn, True);
end;
Ширина и высота эллипсов в приведенном примере равна, соответственно, ширине и высоте тех окон, для которых создаются регионы. При необходимости это можно изменить, например, если требуется, чтобы все кнопки были одной величины независимо от размера, установленного во время проектирования формы.
Результат выполнения кода листинга 1.10 можно увидеть на рис. 1.5.
Рис. 1.5. Окно и кнопки в форме эллипсов
Далее рассмотрим не менее интересный (возможно, даже более полезный на практике) пример округление углов формы и кнопок на ней, то есть применение области отсечения в форме прямоугольника с округленными углами. Ниже приведен код реализации соответствующего обработчика события FormCreate (листинг 1.11).
Листинг 1.11. Окно и кнопки с округленными краямиprocedure TfrmRoundRect.FormCreate(Sender: TObject);
var
formRgn, but1Rgn, but2Rgn, but3Rgn: HRGN;
begin
//Создаем регионы для кнопок
but1Rgn:= CreateRoundRectRgn(0, 0, Button1.Width1, Button1.Height1,
Button1.Width div 5, Button1.Height div 5);
SetWindowRgn(Button1.Handle, but1Rgn, False);
but2Rgn:= CreateRoundRectRgn(0, 0, Button2.Width1, Button2.Height1,
Button2.Width div 5, Button2.Height div 5);
SetWindowRgn(Button2.Handle, but2Rgn, False);
but3Rgn:= CreateRoundRectRgn(0, 0, Button3.Width1, Button3.Height1,
Button3.Width div 5, Button3.Height div 5);
SetWindowRgn(Button3.Handle, but3Rgn, False);
//Регион для окна
formRgn:= CreateRoundRectRgn(0, 0, Width1, Height1,
Width div 5, Height div 5);
SetWindowRgn(Handle, formRgn, False);
end;
В листинге 1.11 размеры округляющих эллипсов вычисляются в расчете из размеров конкретного окна (20 % от его ширины и 20 % от высоты). Это смотрится не всегда красиво. В качестве альтернативы для ширины и высоты скругляющих эллипсов можно использовать фиксированные небольшие значения.
Результат выполнения кода листинга 1.11 можно увидеть на рис. 1.6.
Рис. 1.6. Окно и кнопки с округленными краями
Теперь самый интересный из предусмотренных примеров создание окна и кнопок в форме многоугольников, а именно: окна в форме звезды, кнопок в форме треугольника, пяти и шестиугольника (рис. 1.7).
Рис. 1.7. Окно и кнопки в форме многоугольников
Код создания регионов для областей отсечения данного примера приведен в листинге 1.12.
Листинг 1.12. Окно и кнопки в форме многоугольниковprocedure TfrmPoly.FormCreate(Sender: TObject);
var
points: array [0..5] of TPoint;
formRgn, but1Rgn, but2Rgn, but3Rgn: HRGN;
begin
//Создаем регионы для окна и кнопок
//..шестиугольная кнопка
Make6Angle(Button1.Width, Button1.Height, points);
but1Rgn:= CreatePolygonRgn(points, 6, WINDING);
SetWindowRgn(Button1.Handle, but1Rgn, False);
//..треугольная кнопка
Make3Angle(Button2.Width, Button2.Height, points);
but2Rgn:= CreatePolygonRgn(points, 3, WINDING);
SetWindowRgn(Button2.Handle, but2Rgn, False);
//..пятиугольная кнопка
Make5Angle(Button3.Width, Button3.Height, points);
but3Rgn:= CreatePolygonRgn(points, 5, WINDING);
SetWindowRgn(Button3.Handle, but3Rgn, False);
//..форма в виде звезды
MakeStar(Width, Height, points);
formRgn:= CreatePolygonRgn(points, 5, WINDING);
SetWindowRgn(Handle, formRgn, False);
end;
Особенностью создания регионов в приведенном листинге является использование дополнительных процедур для заполнения массива points координатами точек-вершин многоугольников определенного вида. Все эти процедуры принимают, помимо ссылки на сам массив points, ширину и высоту прямоугольника, в который должен быть вписан многоугольник. Описание процедуры создания треугольника приведено в листинге 1.13.
Листинг 1.13. Создание треугольникаprocedure Make3Angle(width, height: Integer; var points: array of TPoint);
begin
points[0].X:= 0;
points[0].Y:= height 1;
points[1].X:= width div 2;
points[1].Y:= 0;
points[2].X:= width 1;
points[2].Y:= height 1;
end;
В листинге 1.14 приведено описание процедуры создания шестиугольника.
Листинг 1.14. Создание шестиугольникаprocedure Make6Angle(width, height: Integer; var points: array of TPoint);
begin
points[0].X:= 0;
points[0].Y:= height div 2;
points[1].X:= width div 3;
points[1].Y:= 0;
points[2].X:= 2 * (width div 3);
points[2].Y:= 0;
points[3].X:= width 1;
points[3].Y:= height div 2;
points[4].X:= 2 * (width div 3);
points[4].Y:= height 1;
points[5].X:= width div 3;