-2

一个透明的 TListBox:

type
   TListBox = class(StdCtrls.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;



 constructor TListBox.Create(AOwner: TComponent);
begin
   inherited Create(AOwner);
   Ctl3D       := False;
   BorderStyle := bsNone;
   Style       := lbOwnerDrawFixed;
end;

procedure TListBox.CreateParams(var Params: TCreateParams);
begin
   inherited CreateParams(Params);
   Params.ExStyle := Params.ExStyle or WS_EX_TRANSPARENT;
end;

procedure TListBox.WMEraseBkgnd(var Msg: TWMEraseBkgnd);
begin
   Msg.Result := 1;    
end;

procedure TListBox.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
var
   tlbVisible: Boolean;
begin
   tlbVisible := (Parent <> nil) and IsWindowVisible(Handle);  
   if tlbVisible then ShowWindow(Handle, SW_HIDE);             
   inherited SetBounds(ALeft, ATop, AWidth, AHeight);        
   if tlbVisible then ShowWindow(Handle, SW_SHOW);           

end;

procedure TListBox.DrawItem(Index: Integer; Rect: TRect;
   State: TOwnerDrawState);
var
   FoundStyle: TBrushStyle;
   R: TRect;
begin
   FoundStyle := Canvas.Brush.Style;   
   R := Rect;     
   MapWindowPoints(Handle, Parent.Handle, R, 2);  
   InvalidateRect(Parent.Handle, @R, True);  
   item Position
   Parent.Update;    
   if not (odSelected in State) then
   begin  
     Canvas.Brush.Style := bsClear;  
   end
   else
   begin
     Canvas.Brush.Style := bsSolid;
   end;
   inherited DrawItem(Index, Rect, State);
   Canvas.Brush.Style := FoundStyle;
end;

我有我的 DrawItem:

procedure TMainForm.MenuDrawItem(Control: TWinControl; Index: integer;
  Rect: TRect; State: TOwnerDrawState);
var
  Sender: TListBox;
  R: TRect;
begin
  Sender := (Control as TListBox);
  if (odSelected in State) then
  begin
    Sender.Canvas.Font.Color := clWhite;
    Sender.Canvas.Font.Style := [fsBold];
    GradientFillCanvas(Sender.Canvas, $00C08000, $00FF8000, Rect, gdVertical);
  end
  else
  begin
    Sender.Canvas.Brush.Style := bsClear;
    Sender.Canvas.Font.Color := clblack;
  end;
  R := Rect;
  Sender.Canvas.Brush.Style := bsClear;

  MainMenuImageList.Draw(Sender.Canvas, 3, R.top + (R.Bottom - R.top - 48)
    div 2, Index, True);
  R.left := MainMenuImageList.width + 10;

  DrawText(Sender.Canvas.Handle, Sender.Items[Index],
    Length(Sender.Items[Index]), R, DT_SINGLELINE or DT_LEFT or DT_VCENTER or
    DT_END_ELLIPSIS);

  if odFocused in State then
    DrawFocusRect((Control as TListBox).Canvas.Handle, Rect);
end;

一个问题是 ListBox 不能正常工作,项目消失,闪烁......

我不能合并 2 个程序的代码而只留下一个(被覆盖的一个或我的):

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

或者

TMainForm.MenuDrawItem(Control: TWinControl; Index: integer; Rect: TRect; State: TOwnerDrawState);

我怎样才能让一切正常,列表框是透明的,项目被正确绘制?

4

1 回答 1

0

我不相信你可以制作一个透明的列表框,除非 Windows 通用控件明确支持该样式。拥有一个所有者绘制的项目可能允许您“不重新绘制项目”,但这不会像您所说的那样“工作正常”。这些项目消失并闪烁,因为您没有真正完整地绘制它们。

简短的回答:不,你不能。原始链接声称有效。您能否详细说明您在原始代码中发现的问题,也许有人可以提出解决方法?

于 2011-12-31T13:41:04.570 回答