Visit our Sponsor   Visit our Sponsor
delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
Have a look at your member-status

connecting people's knowledge


  - Recent ArticlesRSS feed for Recent Articles on delphi3000.com
  - List of All Articles
  - Top Viewed Articles
  - Articles (+Attachem.)
  - Articles Of Interest
  - Categories
  - Top Uploader
  - Search
  - Index

  - My Home
  - Submit an Article
  - My Articles
  - My Personal Data
  - My Bookmarks
  - Activities
  - Login/Logout

  - Sign Up
  - Why Sign Up
  - Newsletter

  - Press
  - Advertise

  - Contact
  - Feedback





Community
Borland
ClubeDelphi
Dr. Bob
UK-BUG
Delphi Meetings
Planeta Delphi







Startblatt.de






Share this article with friendsShare this article with friends
Rate this articleRate this article - to keep the quality of delphi3000.com !
Comment this article or read through previous comments (3)


TEdit that damn backgroundFormat this article printer-friendly!Bookmark function is only available for registered users!
Using WMEraseBkGnd to create a TEdit descendant that is transparent or has a background
Product:
Delphi 6.x (or higher)
Category:
Component Writing
Skill Level:
Scoring:
Last Update:
03/11/2003
Search Keys:
delphi delphi3000 article borland vcl code-snippet TEDIT Transparent Picture Background
Times Scored:
6
Visits:
5776
Uploader: Matt Harrison
Company:
Reference: www.zeta9.net
 
Question/Problem/Abstract:
TEdit is a fairly low level component utilizing the standard widows edit window.  How on earth do we get the background to be something other than a color.. Can we make it transparent or put a picture in.
I don't know if it works in versions previous to 6 but I can't see why it would not.
Answer:



This unit is a transparent TEdit descendant.  I wrote it for my new program Zeta9. www.zeta9.net

If you want to put your own background in instead of it being transparent change the else clause of the if Transparent in WMEraseBkGnd.

Matt.

unit Z9Edit;

interface

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

type
  TZ9Edit = class(TEdit)
  private
    { Private declarations }
    FAlignText: TAlignment;
    FTransparent: Boolean;
    FPainting: Boolean;
    procedure SetAlignText(Value: TAlignment);
    procedure SetTransparent(Value: Boolean);
  protected
    { Protected declarations }
    procedure RepaintWindow;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure Change; override;
    procedure SetParent(AParent: TWinControl); override;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure WMNCPaint (var Message: TMessage); message WM_NCPAINT;
    procedure WMEraseBkGnd(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
    procedure CNCtlColorEdit(var Message: TWMCtlColorEdit); message CN_CTLCOLOREDIT;
    procedure CNCtlColorStatic(var Message: TWMCtlColorStatic); message CN_CTLCOLORSTATIC;
    procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
    procedure WMMove(var Message: TWMMove); message WM_MOVE;
    procedure PaintParent(ACanvas: TCanvas);
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
    property Align;
    property AlignText: TAlignment read FAlignText write SetAlignText default taLeftJustify;
    property Transparent: Boolean read FTransparent write SetTransparent default false;

  end;

implementation

{ TZ9Edit }

uses
  Forms;

type
  TParentControl = class(TWinControl);

const
  BorderRec: array[TBorderStyle] of Integer = (1, -1);

constructor TZ9Edit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FAlignText := taLeftJustify;
  FTransparent := false;
  FPainting := false;
end;

destructor TZ9Edit.Destroy;
begin
  inherited Destroy;
end;

procedure TZ9Edit.SetAlignText(Value: TAlignment);
begin
  if FAlignText <> Value then
  begin
    FAlignText := Value;
    RecreateWnd;
    Invalidate;
  end;
end;


procedure TZ9Edit.SetTransparent(Value: Boolean);
begin
  if FTransparent <> Value then
  begin
    FTransparent := Value;
    Invalidate;
  end;
end;

procedure TZ9Edit.WMEraseBkGnd(var Message: TWMEraseBkGnd);
var
  DC: hDC;
  i: integer;
  p: TPoint;
  canvas : TCanvas;
begin
  if FTransparent and not(csDesigning in componentstate) then
  begin
    canvas := TCanvas.create;
    try
      canvas.handle := message.dc;
      PaintParent(Canvas);
    finally
      canvas.free;
    end;
  end
  else
  begin
    canvas := TCanvas.create;
    try
      canvas.handle := message.dc;
      canvas.brush.color := Color;
      canvas.brush.style := bsSolid;
      canvas.fillrect(clientrect);
    finally
      canvas.free;
    end;
  end;
end;

procedure TZ9Edit.WMPaint(var Message: TWMPaint);
begin
  inherited;
  if FTransparent then
    if not FPainting then RepaintWindow;
end;

procedure TZ9Edit.WMNCPaint(var Message: TMessage);
begin
  inherited;
end;

procedure TZ9Edit.CNCtlColorEdit(var Message: TWMCtlColorEdit);
begin
  inherited;
  if FTransparent then SetBkMode(Message.ChildDC, 1);
end;

procedure TZ9Edit.CNCtlColorStatic(var Message: TWMCtlColorStatic);
begin
  inherited;
  if FTransparent then SetBkMode(Message.ChildDC, 1);
end;

procedure TZ9Edit.CMParentColorChanged(var Message: TMessage);
begin
  inherited;
  if FTransparent then Invalidate;
end;

procedure TZ9Edit.WMSize(var Message: TWMSize);
var
  r : TRect;
begin
  inherited;
  r := ClientRect;
  InvalidateRect(handle,@r,false);
end;


procedure TZ9Edit.WMMove(var Message: TWMMove);
var
  r : TRect;
begin
  inherited;
  Invalidate;
  r := ClientRect;
  InvalidateRect(handle,@r,false);
end;

procedure TZ9Edit.RepaintWindow;
var
  DC: hDC;
  TmpBitmap, Bitmap: hBitmap;
begin
  if FTransparent then
  begin
    FPainting := true;
    HideCaret(Handle);
    DC := CreateCompatibleDC(GetDC(Handle));
    TmpBitmap := CreateCompatibleBitmap(GetDC(Handle), Succ(ClientWidth), Succ(ClientHeight));
    Bitmap := SelectObject(DC, TmpBitmap);
    PaintTo(DC, 0, 0);
    BitBlt(GetDC(Handle), BorderRec[BorderStyle] + BorderWidth, BorderRec[BorderStyle] + BorderWidth, ClientWidth, ClientHeight, DC, 1, 1, SRCCOPY);
    SelectObject(DC, Bitmap);
    DeleteDC(DC);
    ReleaseDC(Handle, GetDC(Handle));
    DeleteObject(TmpBitmap);
    ShowCaret(Handle);
    FPainting := false;
  end;
end;

procedure TZ9Edit.CreateParams(var Params: TCreateParams);
const
  Alignments: array [TAlignment] of DWord = (ES_LEFT, ES_RIGHT, ES_CENTER);
begin
  inherited CreateParams(Params);
  Params.Style := Params.Style or ES_MULTILINE or Alignments[FAlignText];
end;

procedure TZ9Edit.Change;
begin
  RepaintWindow;
  inherited Change;
end;

procedure TZ9Edit.SetParent(AParent: TWinControl);
begin
  inherited SetParent(AParent);
end;

procedure TZ9Edit.PaintParent(ACanvas: TCanvas);
var
  I, Count, X, Y, SaveIndex: integer;
  DC: cardinal;
  R, SelfR, CtlR: TRect;
  Control : TControl;
begin
  Control := Self;
  if Control.Parent = nil then Exit;
  Count := Control.Parent.ControlCount;
  DC := ACanvas.Handle;

  SelfR := Bounds(Control.Left, Control.Top, Control.Width, Control.Height);
  X := -Control.Left; Y := -Control.Top;
  // Copy parent control image
  SaveIndex := SaveDC(DC);
  SetViewportOrgEx(DC, X, Y, nil);
  IntersectClipRect(DC, 0, 0, Control.Parent.ClientWidth, Control.Parent.ClientHeight);
  TParentControl(Control.Parent).Perform(WM_ERASEBKGND,DC,0);
  TParentControl(Control.Parent).PaintWindow(DC);
  RestoreDC(DC, SaveIndex);

  //Copy images of graphic controls
  for I := 0 to Count - 1 do begin
    if (Control.Parent.Controls[I] <> nil) then
    begin
      if Control.Parent.Controls[I] = Control then break;

      with Control.Parent.Controls[I] do
      begin
        CtlR := Bounds(Left, Top, Width, Height);
        if Bool(IntersectRect(R, SelfR, CtlR)) and Visible then
        begin
          SaveIndex := SaveDC(DC);
          SetViewportOrgEx(DC, Left + X, Top + Y, nil);
          IntersectClipRect(DC, 0, 0, Width, Height);
          Perform(WM_ERASEBKGND,DC,0);
          Perform(WM_PAINT, integer(DC), 0);
          RestoreDC(DC, SaveIndex);
        end;
      end;
    end;
  end;
end;

end.





Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment
Cursor disappears while typing.
    Paul (Mar 19 2003 6:37AM)

Pretty nice.  If you could just prevent the flickering when risizing a form and fix the problem with the mouse cursor...

Mouse Cursor disappears while typing and stays missing.

then you have a perfectly transparent control.

It would then it may be possible to extend this to have the parent paint to a temp bitmap first, and then alphablend a color with it for a translucent look.

-Paul
Respond

RE: Cursor disappears while typing.
Matt Harrison (Mar 19 2003 9:49AM)

Hmmm.... Isn't the cursor disappearing standard on all edit boxxes in windows ?  It is in XP, when you move the mouse it comes back again.  It's so it doesn't obscure the edit box.  If it does not come back when you move the mouse let me know.  It works under XP what OS are yoou using ?

Yeah the flicker, I tried to get rid of that..... I just can't get the TEDIT (which is the standard windows control) to double buffer.  If anyone else knows how please let me know.
Respond

RE: flickering
Martin Kaip (May 23 2003 5:43PM)

i think you can get rid of it by just not using the WM_ERASEBKGND message. remove all the drawing code from this procedure and leave the procedure empty (do not delete the procedure, otherwise windows redraws the background, and you got flickering again).

put all the drawing routines into the paint-procedure. there you can draw all graphics in a way nothing has to be drawn twice, or you can use double-buffering with an invisible bitmap.

making it that way helped for most of my own components, even without using double-buffering there was no more flickering. but it should work for your component as well.
Respond














 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
M. Maes
 
   














 







     
  Copyright © 2000 - 2007 delphi3000.com - All rights reserved. Terms of use. || Privacy
delphi3000.com is a service by bluestep.com IT-Services GmbH (Vienna)