代码之家  ›  专栏  ›  技术社区  ›  Daniel Grillo

有没有办法让TradioButton透明化?

  •  2
  • Daniel Grillo  · 技术社区  · 16 年前

    我用的是Delphi2010

    6 回复  |  直到 15 年前
        1
  •  3
  •   Sertac Akyuz    16 年前

    我同意Andreas和Serg的观点,即启用主题时控件是透明的。

    我曾经试图使复选框在项目选项中未启用运行时主题,或使用操作系统选择经典主题时透明;结果并不完美。下面是应用于单选按钮的相同代码。

    很容易注意到的问题是,正如您从代码中猜到的,它有点闪烁,并且在双重缓冲时是不透明的。不容易发现的问题可以(有时)复制,方法是在包含控件的窗体前面放置一个不同的窗口,然后慢慢地将其移到一边,有时这会留下一些瑕疵。

    好吧,不管怎样,它在这里;

    type
      TMyRadioButton = class(TRadioButton)
      private
        procedure CnCtlColorStatic(var Msg: TWMCtlColorStatic); message CN_CTLCOLORSTATIC;
        procedure WmEraseBkgnd(var Msg: TWMEraseBkgnd); message WM_ERASEBKGND;
        procedure WmPaint(var Msg: TWMNCPaint); message WM_PAINT;
      protected
        procedure CreateParams(var Params: TCreateParams); override;
      end;
    
    implementation
    
    uses
      themes;
    
    procedure TMyRadioButton.CreateParams(var Params: TCreateParams);
    begin
      inherited CreateParams(Params);
      Params.ExStyle := Params.ExStyle or WS_EX_TRANSPARENT;
    end;
    
    procedure TMyRadioButton.WmPaint(var Msg: TWMNCPaint);
    begin
      if not (ThemeServices.ThemesEnabled or DoubleBuffered) then
        InvalidateRect(Handle, nil, True);
      inherited;
    end;
    
    procedure TMyRadioButton.WmEraseBkgnd(var Msg: TWMEraseBkgnd);
    var
      R: TRect;
    begin
      if not (ThemeServices.ThemesEnabled or DoubleBuffered)
           and (Parent <> nil) then begin
        R := Rect(Left, Top, Left + Width, Height + Top);
        InvalidateRect(Parent.Handle, @R, True);
        UpdateWindow(Parent.Handle);
        Msg.Result := 1;
      end else
        inherited;
    end;
    
    procedure TMyRadioButton.CnCtlColorStatic(var Msg: TWMCtlColorStatic);
    begin
      if not (ThemeServices.ThemesEnabled or DoubleBuffered) then begin
        SetBKMode(Msg.ChildDC, TRANSPARENT);
        Msg.Result := GetStockObject(NULL_BRUSH);
      end else
        inherited;
    end;
    
        2
  •  2
  •   Jørn E. Angeltveit    16 年前

    引用Remy Lebeau(团队B):

    tlabel是一个tgraphiccontrol 后代,因此必须 它自己手动绘制,因此可以 根据需要实现透明度。 Tcheckbox和TradioButton,在 另一方面,是TwinControl 包装标准Win32的后代 API控制,因此受 操作系统支持的任何功能 对他们来说(透明度不是 他们) https://forums.codegear.com/thread.jspa?threadID=24027&tstart=375

    您要么需要进行一些重覆盖,要么需要使用第三方组件…

        3
  •  1
  •   PA.    16 年前

    一个简单的技巧:将按钮颜色变为白色,将其缩小到最小尺寸,只使用按钮;然后在其后面放置一个透明标签。

    否则,要使按钮真正透明,您需要所有者绘制它。你可以在网上找到一些例子。

    我找到了一些关于响应wm'ctlcolor消息的信息。但我很快就试了一下,但还是没能让它正常工作。

        4
  •  1
  •   kludg    16 年前

    我在Delphi2009中试验了标准VCL TradioButton控件(我想Delphi2010是相同的)。

    如果在启用运行时主题的情况下编译项目(项目->选项->应用程序->启用运行时主题),则TradioButton控件是透明的,其“颜色”属性将被忽略。如果禁用运行时主题,则TradioButton控件不透明,其背景由其“color”属性定义。

    所以我假设标准VCL TradioButton(以及底层的Windows控件)是由Windows主题而不是控件本身透明的。您可以在应用程序级别关闭主题支持,在这种情况下,您将得到一个不透明的单选按钮。如果需要禁用运行时主题的透明RadioButton,请使用第三方自定义RadioButton(tcustomControl子代,而不是标准的Windows RadioButton包装器)

        5
  •  0
  •   mj2008    16 年前

    最简单的方法是购买像 Raize Components 这将为你做这件事,而且更多。raize特别允许您定制UI的许多方面。

        6
  •  0
  •   Im0rtality    16 年前

    http://www.torry.net/quicksearchd.php?String=transparent+radiobutton&Title=No 可能会有所帮助。这些都不是D2010或D2009,但我相信移植是可能的。