我试图用SetWindowRgn,我不能.
可以这样做(顶部的两个角落是圆的,窗口有一个阴影)像这张照片?
解决方法
以下是如何使用阴影设置窗口区域的代码示例:
(注意:表单BorderStyle假定为bsnone,不可重新定义)
(注意:表单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,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,Right - Left + 1,Bottom - Top + 1,CORNER_SIZE,CORNER_SIZE);
- // exclude left-bottom corner
- ExcludeRectRgn(Rgn,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,Right - Left,Bottom - Top);
- end;
- // the operating system owns the region,delete the Rgn only SetWindowRgn fails
- if SetWindowRgn(Handle,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;
绘制自定义阴影的另一种方法是设置Window WS_EX_LAYERED并使用UpdateLayeredWindow
这是一个very good example的完成(来源是C,但很容易理解)
对于更复杂的形状,您可以在表单和Alpha Blend上使用PNG图像.
编辑:
调整WS_POPUP窗口大小是一个痛苦的世界…
你有几个选择:
>写一个WM_NCHITEST handler
>使用WM_Syscommand $F008调整大小(上面的链接)或$F012到move the Window.
>使用WS_EX_STATICEDGE
and WS_SIZEBOX
样式.
请注意,当您重新调整窗口区域(例如OnResize事件)时,需要重新创建窗口区域.