2010. június 12., szombat

How to create a TRichEdit with a tiled background


Problem/Question/Abstract:

Does anyone know how to use a tiled picture as the background for a TRichEdit control?

Answer:

For a standard TRichEdit there seems to be no way to make it transparent or paint its background with a tiled bitmap. But there is a workaround if you're using the Win2000 operating system. There you can make your control transparent by setting the WS_EX_LAYERED constant to the window extended style and then calling the SetLayeredWindowAttributes Win API function.

The example listed below is a TRichEdit control with a DrawStyle property. Depending on its value, the control will have a transparent background or will draw itself with an alpha transparency.

{ ... }
type
  TDrawStyle = (ds_Transparent, ds_NotDistinctly, dsNormal);

  MyTransparentRichEdit = class(TRichEdit)
  protected
    FDrawStyle: TDrawStyle;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure CreateWnd; override;
    procedure SetDrawStyle(AValue: TDrawStyle);
  public
    constructor Create(AOwner: TComponent); override;
  published
    property DrawStyle: TDrawStyle read FDrawStyle write SetDrawStyle;
  end;

  { ... }

constructor MyTransparentRichEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FDrawStyle := dsNormal;
end;

procedure MyTransparentRichEdit.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  if not (csDesigning in ComponentState) then
  begin
    Params.Style := Params.Style or WS_POPUP;
    Params.ExStyle := Params.ExStyle + WS_EX_LAYERED;
  end;
end;

procedure MyTransparentRichEdit.CreateWnd;
var
  XPoint: TPoint;
begin
  if not (csDesigning in ComponentState) then
  begin
    XPoint := TWinControl(Owner).ClientToScreen(POINT(Left, Top));
    Left := XPoint.X;
    Top := XPoint.Y;
  end;
  inherited CreateWnd;
  case FDrawStyle of
    ds_Transparent:
      SetLayeredWindowAttributes(Handle, ColorToRGB(Color), 255, LWA_COLORKEY);
    ds_NotDistinctly:
      SetLayeredWindowAttributes(Handle, 0, 150, LWA_ALPHA);
  end;
end;

procedure MyTransparentRichEdit.SetDrawStyle(AValue: TDrawStyle);
begin
  if FDrawStyle <> AValue then
  begin
    FDrawStyle := AValue;
    RecreateWnd;
  end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése