|
Wielu początkujących programistów zastanawia się jak wykonać przycisk w kształcie gwiazdy, który reaguje na kliknięcie tylko w rejonie tego kształtu. Do tego celu służą regiony. W Windowsie region jest kwadratem, polygonem(dowolnym kształtem) lub elipsą (lub kombinacją dwóch lub większej liczby tych kształtów), które mogą być wypełnione, pomalowane, odwrócone, obramowane i użyte do wykrywania kolizji (pozycji kursora). Aplikacja tworzy region poprzez wywołanie funkcji powiązanej ze specyficznym kształtem. Poniżej przedstawione są funkcje powiązane ze wszystkimi standardowymi kształtami: kwadrat: CreateRectRgn, CreateRectRgnIndirect kwadrat z zaokrąglonymi narożnikami: CreateRoundRectRgn elipsa: CreateEllipticRgn, CreateEllipticRgnIndirect polygon: CreatePolygonRgn, CreatePolyPolygonRgn Aplikacja łączy dwa regiony poprzez wywołanie funkcji CombineRgn. Istnieje pięć możliwości łączeń regionów: RGN_AND: skrzyżowane części dwóch regionów tworzą nowy region RGN_COPY: kopia pierwszego (z dwóch oryginalnych regionów) tworzy nowy region RGN_DIFF: część pierwszego regionu, która nie krzyżuje się z drugim, tworzy nowy region RGN_OR: dwa oryginalne regiony tworzą nowy region RGN_XOR: te części dwóch oryginalnych regionów, które się nie pokrywają, tworzą nowy region Poniższe ilustracje pokazują wynik połączenia regionów (kwadratowego i okrągłego) pięcioma możliwymi funkcjami: ![]() ![]() ![]() ![]() Przejdziemy do przykładów. Na początek stworzymy kwadrat, koło i narysujemy tekst. var x0, y0: Integer; rgn1, rgn2, rgn3: HRGN; begin x0 := 20; y0 := 20; // kwadrat rgn1 := CreateRectRgn(x0, y0, x0 + 130, y0 + 30); x0 := 200; y0 := 30; // koło rgn2 := CreateEllipticRgn(x0, y0, x0 + 60, y0 + 60); x0 := 70; y0 := 90; // tekst BeginPath(Canvas.Handle); Canvas.Brush.Style := bsClear; Canvas.Font.Name := 'Times New Roman'; Canvas.Font.Size := 90; Canvas.Font.Style := [fsBold]; Canvas.TextOut(260, 80, 'A'); EndPath(Canvas.Handle); rgn3 := PathToRegion(Canvas.Handle); end;Teraz stworzymy bardziej złożony region poprzez połączenie trzech regionów: var x0, y0 :integer; rgn0, rgn1, rgn2, rgn3:HRGN; begin rgn0 := CreateRectRgn(x0, y0, x0 + 130, y0 + 40); // utworzenie nowego regionu rgn1 := CreateRectRgn(x0, y0 + 80,x0 + 130, y0 + 100); // utworzenie trzech regionów które będą złączone rgn2 := CreateEllipticRgn(x0 + 5, y0 + 30, x0 + 30, y0 + 90); rgn3 := CreateEllipticRgn(x0 + 100, y0 + 30, x0 + 125, y0 + 90); CombineRgn(rgn0, rgn0, rgn1, RGN_OR); // połączenie ich w jeden region CombineRgn(rgn0, rgn0, rgn2, RGN_OR); CombineRgn(rgn0, rgn0, rgn3, RGN_OR); DeleteObject(rgn1); // usunięcie ich z pamięci DeleteObject(rgn2); DeleteObject(rgn3);Do tworzenia bardziej złożonych regionów służy także komenda CreatePolygonRgn. Do zmiany kształtu formy służy funkcja SetWindowRgn. Wykorzystamy obie te funkcje do stworzenia formy w kształcie pięcioramiennej gwiazdy: procedure TForm1.FormCreate(Sender: TObject); // tworzenie kształtu odbywa się podczas tworzenia formy var punkty: array[0..10] of TPoint; // tablica zawierająca wierzchołki, potrzebna do zainicjowania funkcji CreatePolygonRgn begin punkty[0] := Point(162,0); // współrzędne wierzchołków gwiazdy punkty[1] := Point(202,117); punkty[2] := Point(325,117); punkty[3] := Point(225,192); punkty[4] := Point(263,308); punkty[5] := Point(162,236); punkty[6] := Point(62,308); punkty[7] := Point(100,191); punkty[8] := Point(0,117); punkty[9] := Point(124,117); punkty[10] := Point(162,0); SetWindowRgn(Handle, CreatePolygonRgn(punkty, 11, WINDING), True); // utworzenie formy w kształcie gwiazdy end; ...powrót |