Delphi:透明控件在上网本上变得不透明

时间:2009-04-17 14:57:59

标签: delphi vcl

由于某些原因,表单上的透明控件在某些计算机上变得不透明。我在“Acer Netbook”和“Thinkpad x600”上得到了报道。该应用程序是使用Delphi 2007构建的。

这就是它的样子: link

虽然看起来像这样: link

表单上的不透明控件是TLabels和TStaticTexts。

(我使用TStaticText控件来定义可点击区域,因为鼠标消息无法处理控件(如标签)转到WM_NCHITTEST处理程序。底部的“按钮”是黑色的,因为我不小心将其颜色设置为clNone,尽管它根本不可见。)

为什么会发生这种情况以及如何防止这种情况(除了将文本渲染到背景图像之外的其他方法)?

编辑:我设法在我的笔记本电脑上重现了这个问题,该笔记本电脑运行的是32位色的Windows XP,并使用经过认证的ATI驱动程序。

5 个答案:

答案 0 :(得分:9)

TLabel和表单之间是否存在TImage?如果是这种情况,则将表单的颜色设置为黑色。当您将TLabel设置为透明时,它会在其父项上绘制它,并且TImage不能具有子控件。实际上,它将表单的颜色呈现在标签上,因为表单是父表单。

另外两种可能的解决方法包括将图像直接涂在表格上(不使用TLabel),但我不知道这是否有效。另一种方法是创建自己的图像控件,它来自TWinControl(而不是TGraphicControl)并且可以包含子控件。 YMMV就这些解决方案而言。

我怀疑它在某些机器上不起作用的原因是底层的Windows API库是不同的。

答案 1 :(得分:3)

这与系统的品牌无关。按可能性顺序,检查这些(假设你在谈论Windows系统):

  • 透明度要求显示位深度为32.如果显示设置为16位颜色,则无法绘制透明控件。用户可修复,你不应该自动切换模式。

  • 视频驱动程序问题 - 确保用户拥有制造商推荐的视频驱动程序。如果那些失败,请尝试最新的。

  • 透明度(实际上是alpha-blending)仅在Windows 2000或更高版本上受支持 - 你确定它们没有运行旧版本吗?

如果您从用户那里获得更多数据会有很大帮助(或者如果您有这些数据,请发布。)我们在这里盲目拍摄,因为您甚至没有提及所使用的操作系统。

答案 2 :(得分:1)

如果TForm上有TImageTLabel,则存在透明度问题,有时候即使显示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;