我在 Delphi 2007 中遇到了使用 TCustomControl 实现透明度的问题。 我已经将问题简化为以下代码。 当创建窗体时,控件的绘制顺序与其添加到窗体中的顺序相反。 但是,当调整窗体大小后,它们按正确的顺序绘制。 我做错了什么? 除第三方解决方案之外,是否有更合适的方法可供选择?
以下是我的示例项目,演示了 Delphi 2007 中的该问题。
以下是我的示例项目,演示了 Delphi 2007 中的该问题。
unit Main;
interface
uses
Forms, Classes, Controls, StdCtrls, Messages,
ExtCtrls;
type
// Example of a TWinControl derived control
TMyCustomControl = class(TCustomControl)
protected
procedure CreateParams(var params: TCreateParams); override;
procedure WMEraseBkGnd(var msg: TWMEraseBkGnd);
message WM_ERASEBKGND;
procedure Paint; override;
end;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
YellowBox: TMyCustomControl;
GreenBox: TMyCustomControl;
end;
var
Form1: TForm1;
implementation
uses
Windows, Graphics;
{$R *.dfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
self.OnPaint := FormPaint;
GreenBox := TMyCustomControl.Create(self);
GreenBox.Parent := self;
GreenBox.SetBounds(10,10,200,200);
GreenBox.color := clGreen;
YellowBox := TMyCustomControl.Create(self);
YellowBox.Parent := self;
YellowBox.SetBounds(100,100,200,200);
YellowBox.color := clYellow;
end;
// Paint bars on form background
procedure TForm1.FormPaint(Sender: TObject);
var
Idx: Integer;
begin
for Idx := 0 to ClientHeight div 8 do
begin
if Odd(Idx) then
Canvas.Brush.Color := clWhite
else
Canvas.Brush.Color := clSilver; // pale yellow
Canvas.FillRect(Rect(0, Idx * 8, ClientWidth, Idx * 8 + 8));
end;
end;
{ TMyCustomControl }
procedure TMyCustomControl.CreateParams(var params: TCreateParams);
begin
inherited;
params.ExStyle := params.ExStyle or WS_EX_TRANSPARENT;
end;
procedure TMyCustomControl.WMEraseBkGnd(var msg: TWMEraseBkGnd);
begin
SetBkMode (msg.DC, TRANSPARENT);
msg.result := 1;
end;
procedure TMyCustomControl.Paint;
begin
Canvas.Brush.Color := color;
Canvas.RoundRect(0,0,width,height,50,50);
end;
end.
TCustomTransparentControl
进行绘制(仅限此项,不需要使用CreateParams
或处理WM_ERASEBKGND
消息)。 - VictoriaWM_ERASEBKGND
消息的理由,而且我编写了许多具有自己100%纯绘画的自定义控件。我还做了一些透明的控件,而不必专门从TCustomTransparentControl
继承。尝试仅使用您的“Paint”过程,看看是否有帮助。不是说它们没用,但要从小处开始,逐步提高到事情开始失败的地步。 - Jerry DodgeWS_EX_TRANSPARENT
标志,而不是 z-order。与预期相反,兄弟窗口/控件不总是以从底部到顶部的顺序接收WM_PAINT
。保留视觉 z-order 的是更新区域 (WS_CLIPSIBLINGS
)。透明 控件不能使用更新区域,它总是覆盖非透明的兄弟。总之:透明控件不应该是兄弟。 - Sertac Akyuz