再问关于TCustomControl控件的透明问题?(200分)

  • 主题发起人 meckyhan
  • 开始时间
M

meckyhan

Unregistered / Unconfirmed
GUEST, unregistred user!
我以TCustomControl为基类开发一个控件,在新控件中有一个Timage对象和一个TLabel对象,
这两个对象都可以通过设置Transparent属性来使其透明,我现在的目的是想让怎个控件都透明,
就必须让TCustomControl也透明,我该如何做,先前有位朋友提出用截取WM_ERASEBKGND 消息,
令Brush.Sytle := bsClear;的方法,但我试了好象不行,哪位有更好的办法?
 
重载 CreateWnd 方法。有必要吗?
 
不要处理背景即可。代码如下:
procedure Tyoucontrol.WindowProc(var Message: TMessage);
begin
case Message.Msg of
WM_ERASEBKGND: Message.Result := 1;
else inherited windowproc(message);
end;
end;
 
两条路:
1. 重载CreateParams方法, ExStyle加上WS_EX_TRANSPARENT标记. 同时重载SetParent方法, 在里面去掉Parent的WS_CLIPCHILDREN标记(用SetWindowLong)。然后在WM_ERASEBKGND消息里什么都不做就返回1(绝对不要Inherited原来的消息句柄), 或者设置Brush.Style=bsClear
优点: 可以实现所有被覆盖的东西都透明显示出来。 缺点, 刷新时闪烁非常厉害。 而且有时会刷新不正确, 即它上面有窗口移过时, 部分上面窗口的图像会残留在你的控件界面中。
2. 在WM_ERASBKGND消息中建立一个后台bitmap, 调整bitmap.canvas.handle(即一个DC)的坐标(用SetWindowOrgEx), 然后调用parent.PaintHandler方法, 将后台bitmap.canvas.handle传入。
优点: 处理简单,速度快。 缺点, 只能显示被覆盖背景和Control控件(如Label, Image...)和WinControl(如Panel, Edit...)的边框, 而不能显示WinControl中的具体内容。

理论上可行的还有一种方法: 即win2000提供的透明窗。 不过不是简单的那种, 而是需要一个pf32bit的mask的那种, 将不透明的部分(你的控件中的其他控件显示的地方)用mask标出。
 
顶部