由于某些原因,表单上的透明控件在某些计算机上变得不透明。我在“Acer Netbook”和“Thinkpad x600”上得到了报道。该应用程序是使用Delphi 2007构建的。
这就是它的样子: link
虽然看起来像这样: link
表单上的不透明控件是TLabels和TStaticTexts。
(我使用TStaticText控件来定义可点击区域,因为鼠标消息无法处理控件(如标签)转到WM_NCHITTEST处理程序。底部的“按钮”是黑色的,因为我不小心将其颜色设置为clNone,尽管它根本不可见。)
为什么会发生这种情况以及如何防止这种情况(除了将文本渲染到背景图像之外的其他方法)?
编辑:我设法在我的笔记本电脑上重现了这个问题,该笔记本电脑运行的是32位色的Windows XP,并使用经过认证的ATI驱动程序。
答案 0 :(得分:9)
TLabel和表单之间是否存在TImage?如果是这种情况,则将表单的颜色设置为黑色。当您将TLabel设置为透明时,它会在其父项上绘制它,并且TImage不能具有子控件。实际上,它将表单的颜色呈现在标签上,因为表单是父表单。
另外两种可能的解决方法包括将图像直接涂在表格上(不使用TLabel),但我不知道这是否有效。另一种方法是创建自己的图像控件,它来自TWinControl(而不是TGraphicControl)并且可以包含子控件。 YMMV就这些解决方案而言。
我怀疑它在某些机器上不起作用的原因是底层的Windows API库是不同的。
答案 1 :(得分:3)
这与系统的品牌无关。按可能性顺序,检查这些(假设你在谈论Windows系统):
透明度要求显示位深度为32.如果显示设置为16位颜色,则无法绘制透明控件。用户可修复,你不应该自动切换模式。
视频驱动程序问题 - 确保用户拥有制造商推荐的视频驱动程序。如果那些失败,请尝试最新的。
透明度(实际上是alpha-blending)仅在Windows 2000或更高版本上受支持 - 你确定它们没有运行旧版本吗?
如果您从用户那里获得更多数据会有很大帮助(或者如果您有这些数据,请发布。)我们在这里盲目拍摄,因为您甚至没有提及所使用的操作系统。
答案 2 :(得分:1)
如果TForm
上有TImage
和TLabel
,则存在透明度问题,有时候即使显示TLabel.Transparent
属性,标签也不透明True
。
我使用VMWare和Windows XP / Windows 7重现了这个问题。为了实现这一点,我必须启用“Windows Classic”主题。 Windows 7具有Windows Aero主题,Windows Basic和Windows Classic主题。仅在启用“Windows Classic”主题时才会出现问题。 (Windows XP也有这个主题)。
TLabel
已有Transparent
属性,默认为True
。除非启用“Windows Classic”主题,否则标签是透明的。
在表单上放置新标签时,Transparent
属性显示为True
,但在对象检查器中未显示粗体。
要解决透明度问题,您只需切换标签的Transparent
属性:首先将其设置为False
,然后再返回True
。这会使标签的Transparent
属性显示为True
,但值将为粗体。或者只需修改.dfm
文件,然后将Transparent = True
添加到需要透明度的所有标签中。
这个问题对于Delphi 10.2 Tokyo来说是实际的。
答案 3 :(得分:0)
虽然不是一个完美的解决方案,但在处理透明度问题时效果会更好,根本就是不使用透明度,设置标签背景颜色以匹配背景颜色,然后使用align with margins属性并设置边距将标签放在表单上。对于下一个,关闭和最小化按钮,我会制作那些单独的图形以避免任何字体或DPI问题。
答案 4 :(得分:0)
我遇到了这个问题,这让我疯了。
我的应用程序使用TLabels而不是TButtons。在运行时,我创建TShapes,大小适合标签。我设置OnMouseEnter和OnMouseLeave事件来改变TShape的颜色。它在我测试的每台机器上工作正常,直到我遇到这个特殊的XP安装,我遇到了OP的问题。
我终于找到了一个有效的解决方案。
for i := 0 to frm.ComponentCount-1 do begin
if (frm.Components[i] is TLabel) and
(((TLabel(frm.Components[i]).Tag > 999) and
(Length(TLabel(frm.Components[i]).Caption) > 1) and (Assigned(TLabel(frm.Components[i]).OnClick))) or
(TLabel(frm.Components[i]).Caption = 'Close')) then
begin
//setting this to false here, then to true at the bottom eliminates the "opaquing" problem
TLabel(frm.Components[i]).Transparent := False;
ls := TShape.Create(frm);
ls.Name := 'ClickLabel' + IntToStr(i) + TWinControl(frm.Components[i]).Name;
ls.Parent := TWinControl(frm.Components[i]).Parent;
ls.Hint := TWinControl(frm.Components[i]).Hint;
ls.ShowHint := True;
ls.Top := TWinControl(frm.Components[i]).Top-4;
ls.Left := TWinControl(frm.Components[i]).Left-7;
ls.Width := TWinControl(frm.Components[i]).Width + 12;
ls.Height := TWinControl(frm.Components[i]).Height + 8;
ls.Shape := stRoundRect;
ls.BringToFront;
TWinControl(frm.Components[i]).BringToFront;
ls.Visible := TWinControl(frm.Components[i]).Visible;
ls.Tag := TWinControl(frm.Components[i]).Tag;
ls.OnMouseEnter := EvHandler.lblNavMouseEnter;
ls.OnMouseLeave := EvHandler.lblNavMouseLeave;
ls.Anchors := TLabel(frm.Components[i]).Anchors;
ls.Pen.Width := 2;
TLabel(frm.Components[i]).Transparent := True;
end;
end;