【问题标题】:AlphaBlend in FireMonkeyFireMonkey 中的 AlphaBlend
【发布时间】:2014-01-09 01:04:31
【问题描述】:

如何在 FireMonkey 桌面应用程序中更改(表单的)AlphaBlend 值?嗯,它在 VCL 应用程序中可用,但我在 FireMonkey 中找不到。

截图:

【问题讨论】:

  • 检查Transparency(可能是useTransparancy)并使用Fill.Color和alpha通道值
  • 您是否要更改表单的透明度?能否提供一张想要的效果图?
  • 您正在寻找跨平台解决方案?还是仅适用于 Windows?
  • @RRUZ 不。我认为这也是不可能的。仅视窗

标签: delphi firemonkey alphablending delphi-xe5


【解决方案1】:

要使您的表单背景半透明,您应该将表单Transparency 属性设置为true 并使用Fill.Color$AAFFFFFF 一样的alpha 值(使用Fill.Kind = bkSolid)。 在这种情况下,表单边框变得不可见(至少在 Delphi XE2 中)

如果您需要将表单中的所有组件设置为半透明,则将TLayout 放置在带有Align = alContents 的表单上,并将其Opacity 属性设置为所需的值。

如果您需要像在 VCL 中那样具有 alpha 混合的半透明窗口,您可以使用与 getWindowLong/SetWindowLong 相同的方法(适用于 Windows 平台)。将transparency 设置回false 并在OnCreate 事件处理程序中使用这样的代码:

implementation
uses fmx.platform.win, winapi.windows;
{$R *.fmx}

procedure TMainForm.FormCreate(Sender: TObject);
var h : HWND;
    aStyle : integer;
    alphaValue : byte;
begin
    h := WindowHandleToPlatform(self.Handle).Wnd;
    AStyle := GetWindowLong(h, GWL_EXSTYLE);
    SetWindowLong(h, GWL_EXSTYLE, AStyle or WS_EX_LAYERED);


    AlphaValue := 125;
    SetLayeredWindowAttributes(h, 0, alphaValue, LWA_ALPHA);
end;

当然,您的所有组件也会变得透明。

【讨论】:

  • 谢谢。但最大的问题是表单边框。他们变得隐形!我该如何解决这个问题?
  • 好的,@RRUZ 已经发布了 VCL 的代码,我有点晚了:)
  • 不适合我...我使用 XE8 分配了表单的 Fill.Bitmap(启动画面)。 TransparencyTrueFill.Color#AAFFFFFF
【解决方案2】:

由于您只寻找 Windows 实现,因此您必须将 WS_EX_LAYERED 样式添加到表单中,然后使用 SetLayeredWindowAttributes 方法根据值或颜色设置 alpha 值。

使用插入器类检查此实现。

type
  TForm   = class(FMX.Forms.TForm)
  private
    FAlphaBlend: Boolean;
    FAlphaBlendValue: Byte;
    FTransparentColor: Boolean;
    FTransparentColorValue: TColor;
    procedure SetAlphaBlend(const Value: Boolean);
    procedure SetAlphaBlendValue(const Value: Byte);
    procedure SetLayeredAttribs;
    procedure SetTransparentColor(const Value: Boolean);
    procedure SetTransparentColorValue(const Value: TColor);
  protected
    property AlphaBlend: Boolean read FAlphaBlend write SetAlphaBlend  default False;
    property AlphaBlendValue: Byte read FAlphaBlendValue write SetAlphaBlendValue default 255;
    property TransparentColor: Boolean read FTransparentColor write SetTransparentColor default False;
    property TransparentColorValue: TColor read FTransparentColorValue write SetTransparentColorValue;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


var
  Form1: TForm1;

implementation

{$R *.fmx}

uses
 FMX.Platform.Win,
 Winapi.Windows,
 Vcl.Graphics;

type
  TSetLayeredWindowAttributes = function (Hwnd: THandle; crKey: COLORREF;
    bAlpha: Byte; dwFlags: DWORD): Boolean; stdcall;

var
  SetLayeredWindowAttributes: TSetLayeredWindowAttributes = nil;

procedure TForm1.FormCreate(Sender: TObject);
begin
   @SetLayeredWindowAttributes := GetProcAddress(GetModuleHandle(User32), 'SetLayeredWindowAttributes');
   AlphaBlend:=True;
   AlphaBlendValue:=200;
end;

{ TForm }

procedure TForm.SetAlphaBlend(const Value: Boolean);
begin
  if FAlphaBlend <> Value then
  begin
    FAlphaBlend := Value;
    SetLayeredAttribs;
  end;
end;

procedure TForm.SetAlphaBlendValue(const Value: Byte);
begin
  if FAlphaBlendValue <> Value then
  begin
    FAlphaBlendValue := Value;
    SetLayeredAttribs;
  end;
end;

procedure TForm.SetTransparentColor(const Value: Boolean);
begin
  if FTransparentColor <> Value then
  begin
    FTransparentColor := Value;
    SetLayeredAttribs;
  end;
end;

procedure TForm.SetTransparentColorValue(const Value: TColor);
begin
  if FTransparentColorValue <> Value then
  begin
    FTransparentColorValue := Value;
    SetLayeredAttribs;
  end;
end;

procedure TForm.SetLayeredAttribs;
const
  cUseAlpha: array [Boolean] of Integer = (0, LWA_ALPHA);
  cUseColorKey: array [Boolean] of Integer = (0, LWA_COLORKEY);
var
  AStyle: Integer;
begin
  if not (csDesigning in ComponentState) and
    (Assigned(SetLayeredWindowAttributes))  then
  begin

    AStyle := GetWindowLong( WindowHandleToPlatform(Handle).Wnd, GWL_EXSTYLE);
    if FAlphaBlend or FTransparentColor then
    begin
      if (AStyle and WS_EX_LAYERED) = 0 then
        SetWindowLong(WindowHandleToPlatform(Handle).Wnd, GWL_EXSTYLE, AStyle or WS_EX_LAYERED);
      SetLayeredWindowAttributes(WindowHandleToPlatform(Handle).Wnd, ColorToRGB(FTransparentColorValue), FAlphaBlendValue,
        cUseAlpha[FAlphaBlend] or cUseColorKey[FTransparentColor]);
    end
    else
    begin
      SetWindowLong(WindowHandleToPlatform(Handle).Wnd, GWL_EXSTYLE, AStyle and not WS_EX_LAYERED);
      RedrawWindow(WindowHandleToPlatform(Handle).Wnd, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ALLCHILDREN);
    end;
  end;
end;

【讨论】:

  • 您尝试过自己使用 ColorKey 吗?虽然使用 LWA_ALPHA 对我来说效果很好,但我无法让另一部分工作,传递 ColorKey(并定义 LWA_COLORKEY)似乎没有效果。
猜你喜欢
  • 2012-09-24
  • 2012-07-23
  • 2010-12-23
  • 1970-01-01
  • 2014-08-27
  • 2012-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多