2011-12-31 33 views
-2
製作一個透明的TListBox

A transparent TListBox:在Delphi

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; 

的一個問題是列表框不能正常工作,項目消失了,眨眼......

我無法合併2個程序的代碼,只留下一個(覆蓋一個或多個):

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

OR

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

我怎樣才能使一切正常,列表框是透明的,項目被正確地畫出來?

+1

請告訴您的操作系統和Delphi版本! – menjaraz 2011-12-31 07:14:40

+0

當項目滾動時,原始代碼是否保持透明? – 2012-01-03 02:07:52

回答

0

我不相信你可以創建一個透明的列表框,除非Windows公共控件明確支持該樣式。擁有一個所有者抽獎項目可能允許你「不重繪項目」,但這不會像你說的那樣「工作正常」。這些物品會消失眨眼,因爲你並沒有完全把它們畫完。

簡答:不,你不能。原始鏈接聲稱工作。你能詳細解釋你在原始代碼中發現的問題,也許有人可以提出一種解決方法嗎?