首页  编辑  

透明的ListBox

Tags: /超级猛料/VCL/Control.控件使用开发和第三方控件/自定义控件/   Date Created:

unit TransparentListBox;

(*

*

*  Written by Walter Irion (CIS 114254, 2455) after the THotSpot

*  sample component that Arne Sch?pers presented in the German

*  c't magazine (issue 6/1996, pp. 286 ff.).

*

*  TTransparentListBox is far from being a universal solution:

*  it does not prevent Windows' scrolling mechanism from

*  shifting the background along with scrolled listbox lines.

*  Moreover, the scroll bar remains hidden until the keyboard

*  is used to change the selection, and the scroll buttons

*  become visible only when clicked.

*

*  To break it short: TTransparentListBox is only suitable

*  for non-scrolling lists.

*

*  In fact it must be possible to write a listbox component

*  that handles scrolling correctly. But my essays to intercept

*  EM_LINESCROLL messages were fruitles, even though I tried

*  subclassing via WndProc.

*

*  A solution for transparent TEdit and TMemo controls is

*  introduced in issue 9/1996 of the c't magazine, again

*  by Arne Sch?pers. But these are outright monsters with

*  wrapper windows to receive notification messages as well

*  as so-called pane windows that cover the actual control's

*  client area and display its content.

*

*  Previous issues of the c't magazine can be ordered from:

*

*    c't-Kopierservice

*    Helstorfer Str. 7

*    30625 Hannover, Germany

*

*  They expect a crossed cheque amounting to DM 14,00

*  to be included with your order, but I don't know about

*  international orders.

*

*)

interface

uses

 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

 StdCtrls;

type

 TTransparentListBox = class(TListBox)

 private

   { Private declarations }

 protected

   { Protected declarations }

   procedure CreateParams(var Params: TCreateParams); override;

   procedure WMEraseBkgnd(var Msg: TWMEraseBkgnd); message WM_ERASEBKGND;

   procedure DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState);

     override;

 public

   { Public declarations }

   constructor Create(AOwner: TComponent); override;

   procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;

 published

   { Published declarations }

   property Style default lbOwnerDrawFixed;

   property Ctl3D default False;

   property BorderStyle default bsNone;

 end;

procedure Register;

implementation

constructor TTransparentListBox.Create(AOwner: TComponent);

begin

 inherited Create(AOwner);

 Ctl3D       := False;

 BorderStyle := bsNone;

 Style       := lbOwnerDrawFixed;  // changing it to lbStandard results

 // in loss of transparency

end;

procedure TTransparentListBox.CreateParams(var Params: TCreateParams);

begin

 inherited CreateParams(Params);

 Params.ExStyle := Params.ExStyle or WS_EX_TRANSPARENT;

end;

procedure TTransparentListBox.WMEraseBkgnd(var Msg: TWMEraseBkgnd);

begin

 Msg.Result := 1;           // Prevent background from getting erased

end;

procedure TTransparentListBox.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);

var

 tlbVisible: Boolean;

begin

 tlbVisible := (Parent <> nil) and IsWindowVisible(Handle);  // Check for

 visibility

 if tlbVisible then ShowWindow(Handle, SW_HIDE);             // Hide-Move-Show

 strategy...inherited SetBounds(ALeft, ATop, AWidth, AHeight);          // ... to prevent

 background...if tlbVisible then ShowWindow(Handle, SW_SHOW);             // ... from

 getting copied

end;

procedure TTransparentListBox.DrawItem(Index: Integer; Rect: TRect;

 State: TOwnerDrawState);

var

 FoundStyle: TBrushStyle;

 R: TRect;

begin

 FoundStyle := Canvas.Brush.Style;       // Remember the brush style

 R := Rect;                                     // Adapt coordinates of drawing

 rect...MapWindowPoints(Handle, Parent.Handle, R, 2);  // ... to parent's coordinate

 system

 InvalidateRect(Parent.Handle, @R, True);   // Tell parent to redraw the

 item Position

 Parent.Update;                             // Trigger instant redraw

 (required)

 if not (odSelected in State) then

 begin  // If an unselected line is being

   handled

   Canvas.Brush.Style := bsClear;  //   use a transparent background

 end

 else

 begin                          // otherwise, if the line needs to be

   highlighted,

   Canvas.Brush.Style := bsSolid;  //   some colour to the brush is

   essential

 end;

 inherited DrawItem(Index, Rect, State); // Do the regular drawing and give

 component users...

 // ... a chance to provide an

 OnDrawItem handler

 Canvas.Brush.Style := FoundStyle;  // Boy-scout rule No. 1: leave site as

 you found it

end;

procedure Register;

begin

 RegisterComponents('Samples', [TTransparentListBox]);

end;

end.