2

我有一个 TCard(TGraphicControl 组件),它有一个属性背景(TPicture)

我希望能够使背景变暗或变暗。因此,如果我可以在游戏中玩牌,那么它是正常的。如果我不能在游戏中玩牌,那么它会变暗。我尝试过Tcard.enabled :=false像你一样放置一个按钮,但它不会使其变暗或使图像/背景变暗。

我也找不到 TPicture 的 alphablend 属性,因为我认为这可能会有所帮助。

我需要什么属性或组件来获得这种效果?

4

1 回答 1

9

处理已启用

按照您的示例,启用状态TButton由 Windows 绘制。对于您自己的控件,应自己绘制禁用状态的视觉反映。在被覆盖的Paint例程中,这仅仅意味着:

if Enabled then
  // draw enabled
else
  // draw disabled;

VCL 负责处理属性的更改,因为它在消息Enabled上调用 Invalidate 。CM_ENABLEDCHANGED

绘图变暗

最简单的解决方案是绘制所有必须绘制的alphablend

procedure TCard.Paint;
var
  Tmp: TBitmap;
  BlendFunc: TBlendFunction;
begin
  if Enabled then
    InternalPaint(Canvas)
  else
  begin
    Tmp := TBitmap.Create;
    try
      Tmp.SetSize(Width, Height);
      InternalPaint(Tmp.Canvas);
      BlendFunc.BlendOp := AC_SRC_OVER;
      BlendFunc.BlendFlags := 0;
      BlendFunc.SourceConstantAlpha := 80;
      BlendFunc.AlphaFormat := 0;
      WinApi.Windows.AlphaBlend(Canvas.Handle, 0, 0, Width, Height,
        Tmp.Canvas.Handle, 0, 0, Width, Height, BlendFunc);
    finally
      Tmp.Free;
    end;
  end;
end;

其中InternalPaint例程执行您现在正在执行的所有操作,例如:

procedure TCard.InternalPaint(ACanvas: TCanvas);
var
  R: TRect;
begin
  R := ClientRect;
  ACanvas.Brush.Color := clGray;
  ACanvas.Rectangle(R);
  InflateRect(R, -7, -7);
  if (FPicture.Graphic <> nil) and (not FPicture.Graphic.Empty) then
    ACanvas.StretchDraw(R, FPicture.Graphic);
end;

所有这一切都带来以下结果:

截屏

SourceConstantAlpha因子 (max 255) 表示临时位图与目标表面混合的程度。Canvas 的默认颜色是 Parent 的颜色(假设你不干扰擦除背景或其他东西),clBtnFace如上图所示。如果该目的地全为白色,则位图将淡化为白色。如果您想要混合颜色或变暗效果,请在 AlphaBlend 之前添加以下两行:

  Canvas.Brush.Color := clBlack; //or clMaroon
  Canvas.FillRect(ClientRect);

截图 2

于 2013-11-05T12:28:43.513 回答