如何制作一个透明控件?(100分)

  • 主题发起人 主题发起人 probor
  • 开始时间 开始时间
P

probor

Unregistered / Unconfirmed
GUEST, unregistred user!
比如TEdit,希望变成透明的。我用了一种方法,做出来的控件透明倒是透明的,
可是文本显示不出来,而且还不能响应鼠标事件.
请各位大侠指点一二,谢了先!
 
  有两种方法可做透明控件:一种是无背景的,一种是有背景的。无背景是指一个控件
不带有自己的背景,全部透明;有背景是指一个控件用 paint 将背景画上去。
  以 Edit 为例:做无背景的只需当 Create 时将csOpaque 从 ControlStyle 中去掉即可,
(注意:这种方法,Delphi 不能自动刷新,需用 ReCreateWnd 刷新);做有背景的只需
在 paint 的时候先将它背后的图像复制过来作背景,然后再画它的前景。

  透明的 Edit 控件可到这里下载: http://www.b-ischo.horizont-is.net/zips/bi_lib.zip
 
感谢Boat,但是还有点问题。Edit的ControlStyle中没有csOpaque,
另外,你提供的下载地址为什么我上不去呢?
 
这里有个控件的源代码,非常好用,可惜焦点在这个控件上时不透明,你可以试着改一下。
unit RbsWiredEdit;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

const
TWM_RbsInvalidate=WM_USER+1;

type
TRbsWiredEdit = class(TEdit)
private
{ Private declarations }
procedure RbsInvalidate(var Message:TMessage); message
TWM_RbsInvalidate;
procedure CNCTLCOLOREDIT(var Message:TWMCTLCOLOREDIT); message
CN_CTLCOLOREDIT;
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
procedure WMMove(var Message: TMessage); message WM_MOVE;

protected
{ Protected declarations }
FTransparent: boolean;
procedure CreateWnd; override;
procedure CreateParams(var Params: TCreateParams); override;
procedure DoExit; override;
procedure DoEnter; override;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
procedure Invalidate; override;

published
{ Published declarations }
end;

procedure Register;

implementation

constructor TRbsWiredEdit.Create(AOwner:TComponent);
begin
inherited create(AOwner);
ftransparent:=true;
end;

procedure TRbsWiredEdit.CreateWnd;
begin
inherited CreateWnd;
if fTransparent then
begin
SetWindowLong(Parent.Handle, GWL_STYLE,
GetWindowLong(Parent.Handle, GWL_STYLE) and not WS_CLIPCHILDREN);
end;
end;

procedure TRbsWiredEdit.RbsInvalidate(var Message:TMessage);
var r:TRect;
begin
if (Parent<>nil) and FTransparent then
begin
r:=ClientRect;
r.TopLeft:=Parent.ScreenToClient(ClientToScreen(r.TopLeft));
r.BottomRight:=Parent.ScreenToClient(ClientToScreen(r.BottomRight));
RedrawWindow(Handle,nil,0,RDW_FRAME+RDW_INVALIDATE);
end;
end;

procedure TRbsWiredEdit.CNCTLCOLOREDIT(var Message:TWMCTLCOLOREDIT);
begin
if FTransparent then
with Message do
begin
SetBkMode(ChildDC,Windows.TRANSPARENT);
Result:=GetStockObject(HOLLOW_BRUSH)
end
else inherited;
end;



procedure TRbsWiredEdit.WMEraseBkgnd(var Message:TWMERASEBKGND);
begin
if FTransparent and not (csDesigning in ComponentState) then
PostMessage(Handle,TWM_RbsInvalidate,0,0)
else inherited;
end;

procedure TRbsWiredEdit.WMMove(var message:TMessage);
begin
inherited;
if FTransparent then SendMessage(Handle,TWM_RbsInvalidate,0,0)
else Invalidate;
end;

procedure TRbsWiredEdit.CreateParams(var Params:TCreateParams);
begin
inherited CreateParams(Params);
if (CsDesigning in ComponentState) then exit;
with Params do
begin
ExStyle:=ExStyle or WS_EX_TRANSPARENT;
end;
end;

procedure TRbsWiredEdit.DoExit;
begin
inherited;
FTransparent:=true;
SetCursor(0);
RecreateWnd;
end;

procedure TRbsWiredEdit.DoEnter;
var exstyle,stdstyle:longint;
begin
inherited;
Ftransparent:=false;
StdStyle:= Windows.GetWindowLong(handle, GWL_EXSTYLE);
exStyle:= StdStyle and not WS_EX_TRANSPARENT;
Windows.SetWindowLong(handle, GWL_EXSTYLE, exStyle);
invalidate;
end;

procedure TRbsWiredEdit.Invalidate;
begin
if FTransparent then SendMessage(Handle,TWM_RbsInvalidate,0,0)
else inherited;
end;

procedure Register;
begin
RegisterComponents('Rombest', [TRbsWiredEdit]);
end;

end.
 
多人接受答案了。
 
哇,看来我没戏了。
 
后退
顶部