Программирование в Delphi. Трюки и эффекты - стр. 13
Рис. 1.8. «Дырки» в форме
На рис. 1.8 явно видно, как в «дырках» формы просвечивает одно из окон среды разработки Delphi. При этом, когда указатель находится над «дыркой», сообщения от мыши получают те окна, части которых видны в «дырке».
Программный код, приводящий к созданию формы столь необычного вида, приведен в листинге 1.17.
procedure TfrmHole.FormCreate(Sender: TObject);
var
rgn1, rgn2: HRGN; //"Регионы-дырки" в форме
formRgn: HRGN;
begin
//Создание региона для формы
formRgn:= CreateRectRgn(0, 0, Width – 1, Height – 1);
//Создание регионов для "дырок"
rgn1:= CreateEllipticRgn(10, 10, 100, 50);
rgn2:= CreateRoundRectRgn(10, 60, 200, 90, 10, 10);
//Создание "дырок" в регионе формы
CombineRgn(formRgn, formRgn, rgn1, RGN_XOR);
CombineRgn(formRgn, formRgn, rgn2, RGN_XOR);
SetWindowRgn(Handle, formRgn, True);
//Регионы для "дырок" больше не нужны
DeleteObject(rgn1);
DeleteObject(rgn2);
end;
Теперь пришла очередь рассмотреть более сложный, но и гораздо более интересный пример. Последовательное применение нескольких операций над регионами приводит к созданию формы, показанной на рис. 1.9 (белое пространство – «вырезанные» части формы).
Рис. 1.9. Сложная комбинация регионов
Описание процедуры, выполняющей операции над регионами, приведено в листинге 1.18.
procedure TfrmManyRgn.FormCreate(Sender: TObject);
var
r1, r2, r3, r4, r5, r6, r7: HRGN;
formRgn: HRGN;
butRgn: HRGN;
begin
//Создание регионов
r1:= CreateRoundRectRgn(100, 0, 700, 400, 40, 40);
r2:= CreateRectRgn(280, 0, 300, 399);
r3:= CreateRectRgn(500, 0, 520, 399);
r4:= CreateEllipticRgn(140, 40, 240, 140);
r5:= CreateEllipticRgn(0, 300, 200, 500);
r6:= CreateEllipticRgn(500, 40, 600, 140);
r7:= CreateEllipticRgn(540, 40, 640, 140);
//Комбинирование
//..разрезы в основном регионе
CombineRgn(r1, r1, r2, RGN_XOR);
CombineRgn(r1, r1, r3, RGN_XOR);
//..круглая "дырка" в левой стороне
CombineRgn(r1, r1, r4, RGN_XOR);
//..присоединение круга в левой нижней части
CombineRgn(r1, r1, r5, RGN_OR);
//..создание "дырки" в форме полумесяца
CombineRgn(r7, r7, r6, RGN_DIFF);
CombineRgn(r1, r1, r7, RGN_XOR);
formRgn:= CreateRectRgn(0, 0, 0, 0);
CombineRgn(formRgn, r1, 0, RGN_COPY);
DeleteObject(r1);
DeleteObject(r2);
DeleteObject(r3);
DeleteObject(r4);
DeleteObject(r5);
DeleteObject(r6);
DeleteObject(r7);
//Создание круглой кнопки закрытия
butRgn:= CreateEllipticRgn(50, 50, 150, 150);
SetWindowRgn(Button1.Handle, butRgn, False);
SetWindowRgn(Handle, formRgn, True);
end;
В этом листинге подписано, какие операции предназначены для создания каких элементов итогового региона. В операциях участвуют семь регионов. Расположение используемых в операциях регионов показано на рис. 1.10.