Delphi TImage32 - 如果没有加载图片,如何使组件不可见?

Delphi TImage32 - how to make the component invisible if no picture is loaded?

如果将普通的 TImage 组件放置在窗体或面板上的其他组件上方 >> 只要未加载图片,它在运行时是不可见的。所以它下面的其他东西是可见的。

但是TImage32默认绘制一个灰色框。

如何在离开设置时使其不可见:.Visible:=True;如果没有加载图片?
(我仍然需要组件上的事件,比如 OnClick...)

是的,这是一个重复的问题,但是 solution-link from the previous topic 已经死了。 :(

虽然我仍然可以访问新闻组帖子,但我不知道主题 ID 与主题标题的关系(我只有这些)。然而,基于在新闻组中的搜索,我发现了几个提到 TImage32Ex 的地方。我想这个组件(不是核心库的一部分)在某种程度上是解决方案的一部分。

因此,虽然不再维护此组件的扩展包,但让我们更深入地了解它的作用。

首先,我必须说 TImage32 总是会将其缓冲区的内容绘制(复制)到显示器上。这意味着默认情况下该组件后面的任何图形都将被覆盖。

TImage32Ex 的技巧是获取 parents 内容并将其绘制到缓冲区中。

修改后的代码如下所示

var
  P: TPoint;
  SaveIndex: Integer;
begin
  SaveIndex := SaveDC(Buffer.Handle);
  try
    GetViewportOrgEx(Buffer.Handle, P);
    SetViewportOrgEx(Buffer.Handle, P.X - Left, P.Y - Top, nil);
    IntersectClipRect(Buffer.Handle, 0, 0, Parent.ClientWidth, Parent.ClientHeight);
    Parent.Perform(WM_ERASEBKGND, Buffer.Handle, 0);
    Parent.Perform(WM_PAINT, Buffer.Handle, 0);
  finally
    RestoreDC(Buffer.Handle, SaveIndex);
  end;
end;

以上代码将 parent 的内容绘制 (WM_PAINT) 到缓冲区中。

例如,如果你想使名为 PaintBox32 的 TPaintBox32 实例成为 transparent,只需将以下代码添加到 'PaintBuffer' 处理程序:

procedure TForm3.PaintBox32PaintBuffer(Sender: TObject);
var
  P: TPoint;
  SaveIndex: Integer;
begin
  SaveIndex := SaveDC(PaintBox32.Buffer.Handle);
  try
    GetViewportOrgEx(PaintBox32.Buffer.Handle, P);
    SetViewportOrgEx(PaintBox32.Buffer.Handle, P.X - PaintBox32.Left, P.Y - PaintBox32.Top, nil);
    IntersectClipRect(PaintBox32.Buffer.Handle, 0, 0, PaintBox32.Parent.ClientWidth, PaintBox32.Parent.ClientHeight);
    PaintBox32.Parent.Perform(WM_ERASEBKGND, PaintBox32.Buffer.Handle, 0);
    PaintBox32.Parent.Perform(WM_PAINT, PaintBox32.Buffer.Handle, 0);
  finally
    RestoreDC(PaintBox32.Buffer.Handle, SaveIndex);
  end;
end;

注意:虽然这基本有效,但它可能无法正确捕获 parent 的子控件。对于 TWinControl 后代尤其如此。虽然也有解决方案来涵盖这种情况,但要涵盖每个细节要复杂得多(例如,底层 TEdit 实例的闪烁光标)

我使用 timage 来遮盖进度条并赋予它形状。

我所做的是加载一个带有透明部分的 png,然后将其放在我的进度条上。

我认为这应该可以实现您的目标。在你的 timage 中放置一个透明的 png。

干杯, E.