2012-02-13 19 views
11

Ho provato a fare con SetWindowRgn e non ho potuto.Modulo arrotondato con System Shadow

Può farlo (i 2 angoli superiori sono arrotondati, la finestra ha un'ombra) come in questa immagine?

enter image description here

+2

Quale versione si utilizza, se ci sono stili XE2 VCL – VibeeshanRC

+0

Qual è il tuo sistema operativo? – menjaraz

+0

Non è questo il comportamento predefinito su Windows 7? –

risposta

16

Ecco un esempio di codice di come impostare la regione della finestra con ombra:
(Note: Forma BorderStyle presume essere bsNone, non ri-considerevole)

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; 

Un'altra modo per disegnare un'ombra personalizzata sarebbe impostare WS_EX_LAYERED e utilizzare UpdateLayeredWindow

Ecco un very good example o f come è fatto (le fonti sono in C++ ma molto facili da capire)

Per forme più complicate è possibile utilizzare un'immagine PNG nel modulo e Alpha Blend it.


EDIT:

Ridimensionamento di una finestra WS_POPUP è un mondo di dolore ... Hai alcune opzioni:

NOTA che è necessario ricreare la regione della finestra quando si ri-taglia IT (per esempio OnResize evento).

+0

kobik, grazie !!! Possiamo rendere un modulo ridimensionabile? – maxfax

+0

@maxfax, vedi modifica. – kobik