2012-02-13 25 views
11

Intenté hacer con SetWindowRgn, y no pude.Forma redondeada con System Shadow

¿Puede hacer eso (las 2 esquinas superiores son redondeadas, la ventana tiene una sombra) como en esta imagen?

enter image description here

+2

Qué versión está utilizando, si hay estilos XE2 VCL – VibeeshanRC

+0

¿Cuál es su sistema operativo? – menjaraz

+0

¿No es este el comportamiento predeterminado en Windows 7? –

Respuesta

16

Aquí es un ejemplo de código de cómo establecer la zona de ventana con la sombra:
(Notas: El Formulario BorderStyle supone que bsNone, no re-importante)

type 
TForm1 = class(TForm) 
    procedure FormCreate(Sender: TObject); 
private 
    procedure CreateFlatRoundRgn; 
protected 
    procedure CreateParams(var Params: TCreateParams); override; 
public 
end; 

var 
    Form1: TForm1; 

implementation 

{$R *.DFM} 

procedure ExcludeRectRgn(var Rgn: HRGN; LeftRect, TopRect, RightRect, BottomRect: Integer); 
var 
    RgnEx: HRGN; 
begin 
    RgnEx := CreateRectRgn(LeftRect, TopRect, RightRect, BottomRect); 
    CombineRgn(Rgn, Rgn, RgnEx, RGN_OR); 
    DeleteObject(RgnEx); 
end; 

procedure TForm1.CreateFlatRoundRgn; 
const 
    CORNER_SIZE = 6; 
var 
    Rgn: HRGN; 
begin 
    with BoundsRect do 
    begin 
    Rgn := CreateRoundRectRgn(0, 0, Right - Left + 1, Bottom - Top + 1, CORNER_SIZE, CORNER_SIZE); 
    // exclude left-bottom corner 
    ExcludeRectRgn(Rgn, 0, Bottom - Top - CORNER_SIZE div 2, CORNER_SIZE div 2, Bottom - Top + 1); 
    // exclude right-bottom corner 
    ExcludeRectRgn(Rgn, Right - Left - CORNER_SIZE div 2, Bottom - Top - CORNER_SIZE div 2, Right - Left , Bottom - Top); 
    end; 
    // the operating system owns the region, delete the Rgn only SetWindowRgn fails 
    if SetWindowRgn(Handle, Rgn, True) = 0 then 
    DeleteObject(Rgn); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    BorderStyle := bsNone; 
    CreateFlatRoundRgn; 
end; 

procedure TForm1.CreateParams(var Params: TCreateParams); 
const 
    CS_DROPSHADOW = $00020000; 
begin 
    inherited CreateParams(Params); 
    with Params do 
    begin 
    Style := WS_POPUP; 
    WindowClass.Style := WindowClass.Style or CS_DROPSHADOW; 
    end; 
end; 

Otro manera de dibujar una sombra personalizada sería establecer Ventana WS_EX_LAYERED y usar UpdateLayeredWindow

Aquí hay un very good example o f cómo se hace (las fuentes están en C++ pero son muy fáciles de entender)

Para formas más complicadas puede usar una imagen PNG en el formulario y Alpha Blend.


EDIT:

Cambiar el tamaño de una ventana WS_POPUP es un mundo de dolor ... Usted tiene algunas opciones:

NOTA que necesita para volver a crear la región de la ventana cuando se vuelva a clasificar según el tamaño (por ejemplo OnResize evento).

+0

kobik, gracias! ¿Podemos hacer un formulario redimensionable? – maxfax

+0

@maxfax, ver edición. – kobik