还有别人写的一个透明panel,参考一下。 unit Glass;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;type TGlassStyle = ( gsBlackness, gsDstInvert, gsMergeCopy, gsMergePaint, gsNotSrcCopy, gsNotSrcErase, gsPatCopy, gsPatInvert, gsPatPaint, gsSrcAnd, gsSrcCopy, gsSrcErase, gsSrcInvert, gsSrcPaint, gsWhiteness); TGlass = class(TCustomControl) private FColor: TColor; FStyle: TGlassStyle; FOnPaint: TNotifyEvent; procedure SetColor(Value: TColor); procedure SetStyle(Value: TGlassStyle); procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED; procedure WMEraseBkgnd(var Message: TMessage); message WM_ERASEBKGND; procedure WMWindowPosChanging(var Message: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING; protected Buffer: TBitmap; procedure CreateParams(var Params: TCreateParams); override; procedure Paint; override; procedure Resize; override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; property Canvas; published property Align; property Anchors; property AutoSize; property BiDiMode; property BorderWidth; property Color: TColor read FColor write SetColor; property Ctl3D; property Enabled; property Style: TGlassStyle read FStyle write SetStyle default gsSrcAnd; property Visible; property OnClick; property OnDblClick; property OnEnter; property OnExit; property OnMouseDown; property OnMouseMove; property OnMouseUp; property OnResize; property OnPaint: TNotifyEvent read FOnPaint write FOnPaint; end;procedure Register;implementationprocedure Register; begin RegisterComponents('Croco', [TGlass]); end;function GlassStyleToInt(gs: TGlassStyle): LongInt; begin case gs of gsBlackness : Result := cmBlackness; gsDstInvert : Result := cmDstInvert; gsMergeCopy : Result := cmMergeCopy; gsMergePaint : Result := cmMergePaint; gsNotSrcCopy : Result := cmNotSrcCopy; gsNotSrcErase: Result := cmNotSrcErase; gsPatCopy : Result := cmPatCopy; gsPatInvert : Result := cmPatInvert; gsPatPaint : Result := cmPatPaint; gsSrcAnd : Result := cmSrcAnd; gsSrcCopy : Result := cmSrcCopy; gsSrcErase : Result := cmSrcErase; gsSrcInvert : Result := cmSrcInvert; gsSrcPaint : Result := cmSrcPaint; gsWhiteness : Result := cmWhiteness; else Assert(True, 'Error parameter in function GlassStyleToInt'); end; end;constructor TGlass.Create(AOwner: TComponent); begin inherited Create(AOwner); Buffer := TBitmap.Create; ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents, csDoubleClicks, csReplicatable]; Width := 100; Height := 100; FStyle := gsSrcAnd; ParentCtl3d := False; Ctl3D := False; ParentColor := False; FColor := clWhite; end;destructor TGlass.Destroy; begin Buffer.Free; inherited Destroy; end;procedure TGlass.Paint; var R: TRect; rop: LongInt; begin R := Rect(0, 0, Width, Height); Buffer.Width := Width; Buffer.Height := Height; Buffer.Canvas.Brush.Style := bsSolid; Buffer.Canvas.Brush.Color := FColor; Buffer.Canvas.FillRect(Rect(0, 0, Width, Height)); rop := GlassStyleToInt(FStyle); StretchBlt(Buffer.Canvas.Handle, 0, 0, Width, Height, Canvas.Handle, 0, 0, Width, Height, rop); if Ctl3D then DrawEdge(Buffer.Canvas.Handle, R, BDR_RAISEDINNER, BF_RECT); Buffer.Canvas.Pen.Mode := pmCopy; Buffer.Canvas.Pen.Style := psSolid; Canvas.Draw(0, 0, Buffer); if Assigned(FOnPaint) then FOnPaint(Self); end; procedure TGlass.SetColor(Value: TColor); begin if Value <> FColor then begin FColor := Value; RecreateWnd; end; end;procedure TGlass.CreateParams(var Params: TCreateParams); begin inherited CreateParams(Params); Params.ExStyle := Params.ExStyle + WS_EX_TRANSPARENT; end;procedure TGlass.WMWindowPosChanging(var Message: TWMWindowPosChanging); begin Invalidate; inherited; end;procedure TGlass.WMEraseBkgnd(var Message: TMessage); begin Message.Result := 0; end;procedure TGlass.Resize; begin Invalidate; inherited; end;procedure TGlass.CMCtl3DChanged(var Message: TMessage); begin inherited; RecreateWnd; end;procedure TGlass.SetStyle(Value: TGlassStyle); begin if Value <> FStyle then begin FStyle := Value; RecreateWnd; end; end;end.
procedure TCustomPanel.CreateParams(var Params: TCreateParams); const BorderStyles: array[TBorderStyle] of DWORD = (0, WS_BORDER); begin inherited CreateParams(Params); with Params do begin Style := Style or BorderStyles[FBorderStyle]; if NewStyleControls and Ctl3D and (FBorderStyle = bsSingle) then begin Style := Style and not WS_BORDER; ExStyle := ExStyle or WS_EX_CLIENTEDGE; Params.ExStyle := Params.ExStyle + WS_EX_TRANSPARENT; end; WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW); end; end; 在panle的上级类,加上这个 就可以了 Params.ExStyle := Params.ExStyle + WS_EX_TRANSPARENT;
http://kmok.cn
Form不能实现完全透明. 但TWinControl类控件(比如Panel, Edit....)
可以. 为了实现透明, Window Styles 中有两个非常关键的标志
一个是ExStyle里的WS_EX_TRANSPARENT. 另一个是Style中的WS_CLIPCHILDREN.
如果设置了WS_EX_TRANSPARENT标志, 那么该window在刷新时的背景将不会由
系统清成默认底色, 而是复制上底层的图象. 所以要实现透明/半透明, 必须设置该
标志. 设置了该标记, 然后再截取WM_ERASEBKGND消息, 什么都不做直接返回1
就可以实现透明效果.
然而要实现真正的透明/半透明, 还有一个关键标志很多人都会忽略, 那就是WS_CLIPCHILDREN
如果某个window具备这个标志(默认的), 那么当它刷新时, 它将不刷新它的子窗口
所覆盖的区域, 因此, 某个panel要实现透明的话, 必须将这个panel的parent的WS_CLIPCHILDREN
标志去除. 不然的话, 你的panel移动或者panel遮住的地方的改动都不会体现出来.
这也就是为什么Panel能实现透明/半透明而form无法做到的根本原因. 因为panel是
一个子窗口, 我们只要简单用SetWindowLong就可以修改Parent窗口的Style. 不幸
的是, SetWindowLong只能修改本进程内某个window的Style, 无法修改别的进程
Panel和它的Parent肯定是一个进程中的, 所以能够修改而实现透明效果, 但form的
Parent是Desktop, 不属于一个进程, 无法修改它的Style, 因此哪怕你设置了Form
的Style 为WS_EX_TRANSPARENT并且截取了WM_ERASEBKGND消息, 你也
无法得到Desktop上被Form遮住的部分, 只能得到一块白色区域. 究其原因, 就是
Desktop Window的WS_CLIPCHILDREN在作怪.
unit Glass;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls;type
TGlassStyle = (
gsBlackness, gsDstInvert, gsMergeCopy, gsMergePaint, gsNotSrcCopy,
gsNotSrcErase, gsPatCopy, gsPatInvert, gsPatPaint, gsSrcAnd,
gsSrcCopy, gsSrcErase, gsSrcInvert, gsSrcPaint, gsWhiteness); TGlass = class(TCustomControl)
private
FColor: TColor;
FStyle: TGlassStyle;
FOnPaint: TNotifyEvent; procedure SetColor(Value: TColor);
procedure SetStyle(Value: TGlassStyle);
procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED;
procedure WMEraseBkgnd(var Message: TMessage); message WM_ERASEBKGND;
procedure WMWindowPosChanging(var Message: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING;
protected
Buffer: TBitmap; procedure CreateParams(var Params: TCreateParams); override;
procedure Paint; override;
procedure Resize; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Canvas;
published
property Align;
property Anchors;
property AutoSize;
property BiDiMode;
property BorderWidth;
property Color: TColor read FColor write SetColor;
property Ctl3D;
property Enabled;
property Style: TGlassStyle read FStyle write SetStyle default gsSrcAnd;
property Visible; property OnClick;
property OnDblClick;
property OnEnter;
property OnExit;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnResize;
property OnPaint: TNotifyEvent read FOnPaint write FOnPaint;
end;procedure Register;implementationprocedure Register;
begin
RegisterComponents('Croco', [TGlass]);
end;function GlassStyleToInt(gs: TGlassStyle): LongInt;
begin
case gs of
gsBlackness : Result := cmBlackness;
gsDstInvert : Result := cmDstInvert;
gsMergeCopy : Result := cmMergeCopy;
gsMergePaint : Result := cmMergePaint;
gsNotSrcCopy : Result := cmNotSrcCopy;
gsNotSrcErase: Result := cmNotSrcErase;
gsPatCopy : Result := cmPatCopy;
gsPatInvert : Result := cmPatInvert;
gsPatPaint : Result := cmPatPaint;
gsSrcAnd : Result := cmSrcAnd;
gsSrcCopy : Result := cmSrcCopy;
gsSrcErase : Result := cmSrcErase;
gsSrcInvert : Result := cmSrcInvert;
gsSrcPaint : Result := cmSrcPaint;
gsWhiteness : Result := cmWhiteness;
else Assert(True, 'Error parameter in function GlassStyleToInt');
end;
end;constructor TGlass.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Buffer := TBitmap.Create; ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents,
csDoubleClicks, csReplicatable];
Width := 100;
Height := 100;
FStyle := gsSrcAnd;
ParentCtl3d := False;
Ctl3D := False;
ParentColor := False;
FColor := clWhite;
end;destructor TGlass.Destroy;
begin
Buffer.Free;
inherited Destroy;
end;procedure TGlass.Paint;
var
R: TRect;
rop: LongInt;
begin
R := Rect(0, 0, Width, Height);
Buffer.Width := Width;
Buffer.Height := Height;
Buffer.Canvas.Brush.Style := bsSolid;
Buffer.Canvas.Brush.Color := FColor;
Buffer.Canvas.FillRect(Rect(0, 0, Width, Height));
rop := GlassStyleToInt(FStyle);
StretchBlt(Buffer.Canvas.Handle, 0, 0, Width, Height,
Canvas.Handle, 0, 0, Width, Height, rop);
if Ctl3D then DrawEdge(Buffer.Canvas.Handle, R, BDR_RAISEDINNER, BF_RECT);
Buffer.Canvas.Pen.Mode := pmCopy;
Buffer.Canvas.Pen.Style := psSolid;
Canvas.Draw(0, 0, Buffer);
if Assigned(FOnPaint) then FOnPaint(Self);
end;
procedure TGlass.SetColor(Value: TColor);
begin
if Value <> FColor then
begin
FColor := Value;
RecreateWnd;
end;
end;procedure TGlass.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params); Params.ExStyle := Params.ExStyle + WS_EX_TRANSPARENT;
end;procedure TGlass.WMWindowPosChanging(var Message: TWMWindowPosChanging);
begin
Invalidate; inherited;
end;procedure TGlass.WMEraseBkgnd(var Message: TMessage);
begin
Message.Result := 0;
end;procedure TGlass.Resize;
begin
Invalidate; inherited;
end;procedure TGlass.CMCtl3DChanged(var Message: TMessage);
begin
inherited; RecreateWnd;
end;procedure TGlass.SetStyle(Value: TGlassStyle);
begin
if Value <> FStyle then
begin
FStyle := Value;
RecreateWnd;
end;
end;end.
const
BorderStyles: array[TBorderStyle] of DWORD = (0, WS_BORDER);
begin
inherited CreateParams(Params);
with Params do
begin
Style := Style or BorderStyles[FBorderStyle];
if NewStyleControls and Ctl3D and (FBorderStyle = bsSingle) then
begin
Style := Style and not WS_BORDER;
ExStyle := ExStyle or WS_EX_CLIENTEDGE;
Params.ExStyle := Params.ExStyle + WS_EX_TRANSPARENT; end;
WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW); end;
end;
在panle的上级类,加上这个 就可以了
Params.ExStyle := Params.ExStyle + WS_EX_TRANSPARENT;
Params.ExStyle := Params.ExStyle + WS_EX_TRANSPARENT;这句话怎么用??谢谢!
ExStyle := ExStyle or WS_EX_TRANSPARENT;就这么用就行