【问题标题】:Setting multiple labels to transparent across 1.000 forms?将多个标签设置为跨 1.000 个表单透明?
【发布时间】:2011-09-01 20:45:56
【问题描述】:

我使用 Devexpress 对我的软件进行了蒙皮,发现标签不透明,导致它们具有灰色背景。

只有无穷无尽的表格,所以我想知道是否有办法自动完成这项任务(将标签设置为透明)。

我之前做过类似的事情,表单上的 Devexpress 控件具有 LookAndFeel.NativeStyle = True,我使用 Grep Search 将所有 dfm 表单上的替换为 False。然而,在标签的情况下,透明属性不存在。

谢谢。

【问题讨论】:

  • 您是否致力于在 IDE 中执行此操作,或者您是否愿意在运行时执行此操作?
  • 罗伯特,那太棒了——我的意思是在运行时。我能做些什么来达到这个结果?
  • 与其在设计时进行,不如在运行时更轻松地进行
  • 遍历表单中的所有控件,每当找到标签时,根据需要更改属性
  • +1 提出一个启发几个聪明解决方案的问题。

标签: delphi delphi-2010 delphi-7 delphi-xe


【解决方案1】:

您可以将BackColor 属性设置为Color.Transparent

【讨论】:

  • 好吧,我认为 OP 想要设置 Label.Transparent := True,但这里真正的问题是如何自动化更改
【解决方案2】:

以下应该有效:透明属性仅在值不是默认值时出现在 DFM 文件中。因此,您可以使用 Grep-Search 在“=TLabel”之后的下一行中插入“Transparent=TRUE”。这个我自己没试过,但是很容易尝试...

【讨论】:

    【解决方案3】:

    在设计时,您可以只解析所有 .dfm 然后添加

      Transparent = True
    

    紧随其后的一行

      object MyLabel : TLabel
    

    行。

    在运行时,您可以覆盖TCustomForm.DoCreateTCustomFrame.Create 方法,如下所示:

    type
      THookedForm = class(TCustomForm)
        procedure HookedDoCreate;
      end;
    
      THookedFrame = class(TCustomFrame)
        constructor Create(AOwner: TComponent); override;
      end;
    
    var
      PatchForm, OriginalForm: TPatchEvent;
      PatchPositionForm: PPatchEvent = nil;
      PatchFrame, OriginalFrame: TPatchEvent;
      PatchPositionFrame: PPatchEvent = nil;
    
    procedure PatchCreate;
    var ov: cardinal;
    begin
      // hook TForm:
      PatchPositionForm := PPatchEvent(@THookedForm.DoCreate);
      OriginalForm := PatchPositionForm^;
      PatchForm.Jump := $E9; // Jmp opcode
      PatchForm.Offset := PtrInt(@THookedForm.HookedDoCreate)-PtrInt(PatchPositionForm)-5;
      if not VirtualProtect(PatchPositionForm, 5, PAGE_EXECUTE_READWRITE, @ov) then
        RaiseLastOSError;
      PatchPositionForm^ := PatchForm; // enable Hook
      // hook TFrame:
      PatchPositionFrame := PPatchEvent(@TCustomFrame.Create);
      OriginalFrame := PatchPositionFrame^;
      PatchFrame.Jump := $E9; // Jmp opcode
      PatchFrame.Offset := PtrInt(@THookedFrame.Create)-PtrInt(PatchPositionFrame)-5;
      if not VirtualProtect(PatchPositionFrame, 5, PAGE_EXECUTE_READWRITE, @ov) then
        RaiseLastOSError;
      PatchPositionFrame^ := PatchFrame; // enable Hook
    end;
    
    { THookedForm }
    
    procedure THookedForm.HookedDoCreate;
    var i: integer;
    begin
      // enumerate all labels, then set Transparent := true
      for i := 0 to Components.Count-1 do
        if Components[i] is TLabel then
          TLabel(Components[i]).Transparent := true;
      DoCreate; // call initial code
    end;
    
    { THookedFrame }
    
    constructor THookedFrame.Create(AOwner: TComponent);
    var i: integer;
    begin
      // enumerate all labels, then set Transparent := true
      for i := 0 to Components.Count-1 do
        if Components[i] is TLabel then
          TLabel(Components[i]).Transparent := true;
      inherited Create(AOwner); // call normal constructor
    end;
    
    ....
    
    initialization
      PatchCreate;
    

    【讨论】:

    • @Warren 这是我的第一个解决方案。并且 OP 要求提供运行时解决方案,因此我给出了该请求的通用解决方案。
    • 这是一个很好的解决方案! :-) 阅读我的评论,我发现我没有任何意义。
    【解决方案4】:

    全局Screen 变量跟踪所有形式:

    procedure MakeLabelsTransparent(AParent: TWinControl);
    var
      I: Integer;
    begin
      with AParent do
        for I := 0 to ControlCount - 1 do
          if Controls[I] is TLabel then
            TLabel(Controls[I]).Transparent := True
          else if Controls[I] is TWinControl then
            MakeLabelsTransparent(TWinControl(Controls[I]));
    end;
    
    procedure TMainForm.ActiveFormChange(Sender: TObject);
    begin
      with Screen do
        if (ActiveCustomForm <> nil) and (ActiveCustomForm.Tag = 0) then
        begin
          MakeLabelsTransparent(ActiveCustomForm);
          ActiveCustomForm.Tag := 1;
        end;
    end;
    
    procedure TMainForm.FormCreate(Sender: TObject);
    begin
      Screen.OnActiveFormChange := ActiveFormChange;
    end;
    

    如果您必须对特定表单使用 Tag 属性,则省略此检查:它不会真的变得那么慢。

    【讨论】:

    • +1 巧妙,NGLN。我不知道如何使用 OnActiveFormChange。
    • 完美,可同时处理所有 MDI 表单,简直完美……谢谢。
    • 标签不必归其所在的形式所有。递归遍历 Controls 索引属性会更健壮。
    【解决方案5】:

    对于此类任务,GExperts 包含 设置组件属性 工具:

    此工具在后台等待 直到你编译一个项目。那么它 扫描当前项目的表格到 检查具有某些成分的 属性和改变那些 属性为定义的值。这 工具对于停用数据集很有用 或您之前的数据库连接 编译您的应用程序,但它可以 用于任何类似的情况 好吧。要激活扫描, 启用此旁边的复选框 GExperts 配置专家 屏幕。

    它也可用于设置尚未在 DFM 中的属性,并且只需要在 GExpert 配置中添加一个条目,然后重新编译。

    我刚刚对其进行了测试,它按预期工作。

    【讨论】:

    • 我推荐这个,因为有一天你可能想要一个不透明的标签,你可以设置不同的标签。
    • 绝对是第二好的解决方案。我对此一无所知。谢谢一百万。
    【解决方案6】:

    一个相关提示(我总是忘记使用这个方便的功能):

    1. 按照您想要的方式配置标签;
    2. 在表单上选择它;
    3. 转到Component/Create component template
    4. 然后您可以为模板命名:

    从那时起,模板将在您的工具面板中显示为一种新的组件类型,并具有您喜欢的设置。

    (是的,我知道这不会改变当前标签)

    【讨论】:

    • 很好,将在我的一个自定义组件上尝试这个,其默认设置是一成不变的
    • 虽然这并不能解决问题,但它真的很有用。我从来没有想过点击菜单“创建组件模板”。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    • 1970-01-01
    • 2012-07-03
    • 2016-12-08
    相关资源
    最近更新 更多