带有系统阴影的圆形表格

max*_*fax 11 forms delphi rounding shadow region

我试着这样做SetWindowRgn,但我做不到.

可以这样做(前2个角是圆形,窗口有阴影)就像这张照片?

在此输入图像描述

kob*_*bik 18

下面是如何使用阴影设置窗口区域的代码示例:(
注意:表单BorderStyle假定为bsNone,不可重新调整大小)

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;
Run Code Online (Sandbox Code Playgroud)

绘制自定义阴影的另一种方法是设置Window WS_EX_LAYERED并使用UpdateLayeredWindow

这是一个非常好的例子,它是如何完成的(源代码是用C++编写的,但很容易理解)

对于更复杂的形状,您可以使用PNG表单上的图像和Alpha Blend它.


编辑:

调整WS_POPUP窗口大小是一个痛苦的世界...你有几个选择:

请注意,在重新调整窗口区域大小时(例如OnResize事件),需要重新创建窗口区域.