【问题标题】:VCL component Opacity/transparenceVCL 组件不透明度/透明度
【发布时间】:2013-06-05 13:07:24
【问题描述】:

是否可以制作例如 20% 透明的 TMemo 或其他 vcl 组件?像 TButton 还是 TEdit?

在搜索解决方案时,我发现了这个:

From Here,然后我想,如果我在表单上绘制图像(OnPaint)然后将AlphaBlend设置为ON,我可以实现这个效果但是没有成功,当整个表单透明时,主要需要的效果没有达到,没有备忘录后面的图片。

我想要达到的效果:(在photoshop中完成)

这可能吗?如果是,如何? (我不要求任何人提供完整的 src 代码,如果可能的话,只要求文章或小例子,或方向,无论我能理解的方式)

请注意。


我找到了解决方案,在带有图像背景的表单上创建字母混合表单,然后在添加的表单上添加备忘录并将其与客户端对齐,这不是最好的方法,但它工作正常:

procedure TForm1.Button1Click(Sender: TObject);
var
 MM : TMyMemo; frm : TForm;
begin
 frm := TForm.Create(Form1);
 frm.BorderStyle := bsNone;
 frm.AlphaBlend := true;
 frm.AlphaBlendValue := 150;
 frm.Left     := Form1.Left + 90;
 frm.Top      := Form1.Top + 90;
 frm.Width    := 300;
 frm.Height   := 300;
 frm.Position := poDesigned;
 frm.Visible := true;

 MM             := TMyMemo.Create(frm);
 MM.Parent      := frm;
 MM.BorderStyle := bsNone;
 MM.ParentColor := False;
 MM.Align       := alClient;
 MM.Color       := clBlack;
 MM.Font.Color  := clWhite;
 MM.Font.Name   := 'Sylfaen';
 MM.Font.Size   := 11;
 MM.Visible     := True;

 frme := True;
end;

但还有一个问题,当我按下备忘录时,背景表单失去焦点,当我将新表单的父级设置为Form1时,上述问题已解决但透明效果消失了(窗口仍然透明但你可以通过bg看到没有可见背景的窗口)我该如何解决这个问题?

【问题讨论】:

  • 如果 TMemo 是从 TWinControl 派生的,那么它具有 .Handle: HWND 属性。也许您可以将它与 Win32 GDI API 一起使用来强制 TMemo alpha 混合。但是,这可能会产生意想不到的副作用或兼容性要求。
  • 以上主题是如何制作的?有什么想法吗?
  • 阅读编辑后的问题

标签: delphi user-interface vcl vcl-styles


【解决方案1】:

我认为这个问题经常被问到(也许不是在这里,但我以前见过很多次)。奇怪的是,答案几乎从来没有出现过,虽然它就在那里,隐藏在所有讨论这个问题的人之间。也许这里的问题将有助于改进未来的搜索过程,仅仅是因为它是stackoverflow :-)

无论如何,这是我去年找到的答案(见下面的代码)。不是我的,但对我有用 - 链接到 author。本质上,该代码为 WM_ERASEBACKGROUND 消息定义了一个带有自定义事件处理程序的派生 Richedit。

unit TransparentRichEdit;

{ Component made by Proger_XP | http://Proger.i-Forge.net }

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, StdCtrls, ComCtrls, Graphics;

type
  TTransparentRichEdit = class (TRichEdit)
  protected
    FCanvas: TCanvas;
    FBackground: TPicture;

    procedure CreateWnd; override;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;

    procedure SetBackground(const Value: TPicture);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Background: TPicture read FBackground write SetBackground;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Miscellaneous', [TTransparentRichEdit]);
end;

{ TTransparentRichEdit }

constructor TTransparentRichEdit.Create(AOwner: TComponent);
begin
  inherited;
  FCanvas := TCanvas.Create;
  FBackground := TPicture.Create;
end;

destructor TTransparentRichEdit.Destroy;
begin
  FBackground.Free;
  FCanvas.Free;
  inherited;
end;

procedure TTransparentRichEdit.CreateWnd;
begin
  inherited;
  SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_TRANSPARENT);
end;

procedure TTransparentRichEdit.WMEraseBkgnd(var Message: TWMEraseBkgnd);
var
  UpdateRect: TRect;
  Rgn: HRGN;
  ToBeErased: Boolean;
  Mem: TBitmap;
begin
  ToBeErased:= false;
  Mem := TBitmap.Create;
  try
    Mem.Width := ClientWidth;
    Mem.Height := ClientHeight;

    FCanvas.Handle := Message.DC;
    Message.Result := 1;

    if not GetUpdateRect(Handle, UpdateRect, ToBeErased) then
      UpdateRect := Rect(0, 0, ClientWidth, ClientHeight);
    with UpdateRect do
      Rgn := CreateRectRgn(Left, Top, Right, Bottom);
    SelectClipRgn(FCanvas.Handle, Rgn);

    FCanvas.Draw(0, 0, FBackground.Graphic);
  finally
    Mem.Free;
  end;
end;

 procedure TTransparentRichEdit.SetBackground(const Value: TPicture);
 begin
   FBackground.Assign(Value);
   Repaint;
 end;

 end.

【讨论】:

  • 忘了说,这种方法也应该适用于 TMemo 等。
  • 我不想让bg完全透明,我想让它60-70%左右,这就是问题所在。
  • @user2200585,你应该看看普通表单处理透明度的方式,也就是 AlphaBlend。
猜你喜欢
  • 2014-01-05
  • 1970-01-01
  • 2012-03-05
  • 2020-07-12
  • 2012-03-28
  • 2016-11-02
  • 2017-01-11
  • 2021-11-01
  • 2015-03-31
相关资源
最近更新 更多