Delphi - Lekerekített sarkú Image komponens

forráskód letöltése

Látványos megoldással szolgál egy olyan Image komponensre hasonlító megoldás, melyben a kép sarkai le vannak kerekítve. Ez a lekerekítés azonban nem csak a megjelenítendő képre vonatkozik, hanem magára a komponensre, így a lekerekített rész mögött valóban látható lesz a komponensünk mögötti terület. A mellékelt program megnyitása előtt a RoundImage.pas-ban lévő komponenst telepítse a Delphi alá.

A komponens használatához a Bitmap property-n keresztül adjunk meg egy BMP képet.
A Round property-ben adhatjuk meg a sarok lekerekítés mértékét.

A megvalósítás lényege abban áll, hogy a létrehozott új komponensre ráhúzunk egy új régiót, mely már nem téglalap alakú, hanem sarkai lekerekítettek. Ettől kezdve a teljes területére bármit is rajzolunk, az már az új régióból nem nyúlhat ki, így a kívánt hatást elértük.
Ezt a CreateWnd eljárás lefutásánál hozzuk létre, meghívva a SetLayout belső eljárásunkat.
procedure TRoundImage.CreateWnd;
begin
  inherited;
  SetLayout;
end;
Ebben létrehozunk egy új régiót a CreateRoundRectRgn hívásával, melynek első négy paraméterébe a befoglaló téglalap méretét adjuk át, ami természetesen egyezik a komponens területének méretével. Ezt követő két paraméter a vízszintes és függőleges mértékű lekerekítés szélességét, illetve magasságát adja meg, melyet a Round property-ből veszünk.
procedure TRoundImage.SetLayout;
var
  h: HRGN;
begin
  h:=CreateRoundRectRgn(0, 0, Width, Height, FRound, FRound);
  SetWindowRgn(Handle, h, true);
end;
Amikor a komponens méretét változtatjuk, akkor újra kell kreálnunk a régiót, hogy az megfeleljen az új méreteknek. Ehhez figyelnünk kell a WM_SIZE eseményt. Itt nincs más teendőnk, mint újra meghívni a SetLayout eljárást.
procedure TRoundImage.DoSize(var Message: TWMSize);
begin
  inherited;
  SetLayout;
end;
Amikor a komponens Paint eljárása kerül meghívásra, akkor kell kirajzolnunk a BMP-t. Ehhez a BitBlt függvény használatával egyszerűen kirajzoljuk a teljes képet.
procedure TRoundImage.Paint;
begin
  inherited;
  if not FBitmap.Empty then begin
    BitBlt(Canvas.Handle, 0, 0, FBitmap.Width, FBitmap.Height, FBitmap.Canvas.Handle, 0, 0,
        SRCCOPY);
  end;
end;