unit kktListBox; {======================================================================== DESIGN BY : 彭國輝 DATE: 2004-12-24 SITE: http://kacarton.yeah.net/ BLOG: http://blog.csdn.net/nhconch EMAIL: kacarton#sohu.com 文章為作者原創,轉載前請先與本人聯系,轉載請注明文章出處、保留作者信息,謝謝支持! =========================================================================}
interface uses Windows, Messages, SysUtils, Classes, Controls, StdCtrls, Commctrl; type TkktListBox = class(TListBox) private MaxLenItemIndex: Integer; FScrollWidth: Integer; procedure LBAddString(var Message: TMessage); message LB_ADDSTRING; procedure LBInsertString(var Message: TMessage); message LB_INSERTSTRING; procedure LBDeleteString(var Message: TMessage); message LB_DELETESTRING; procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED; procedure AdjuctScrollWidth(Message: TMessage); procedure ResetScrollWidth; protected public constructor Create(AOwner: TComponent); override; end; procedure Register; implementation { TkktListBox } constructor TkktListBox.Create(AOwner: TComponent); begin inherited Create(AOwner); MaxLenItemIndex := -1; FScrollWidth := 0; end; procedure TkktListBox.LBAddString(var Message: TMessage); begin inherited; if Message.Result = LB_ERR then Exit; AdjuctScrollWidth(Message); end; procedure TkktListBox.LBInsertString(var Message: TMessage); begin inherited; if Message.Result = LB_ERR then Exit; AdjuctScrollWidth(Message); end; procedure TkktListBox.LBDeleteString(var Message: TMessage); begin inherited; if Message.Result = LB_ERR then Exit; if Message.WParam = MaxLenItemIndex then ResetScrollWidth; end; procedure TkktListBox.CMFontChanged(var Message: TMessage); var sz: SIZE; begin inherited; if MaxLenItemIndex = -1 then Exit; //這里沒有使用TextWidth,而是用GetTextExtentPoint32函數,如果你有興趣的話 //可以跟蹤一個TextWidth函數,它最終是調用GetTextExtentPoint32實現的 GetTextExtentPoint32(Canvas.Handle, PChar(Items[MaxLenItemIndex]), Length(Items[MaxLenItemIndex]), sz); FScrollWidth := sz.cx + 4; Perform(LB_SETHORIZONTALEXTENT, FScrollWidth, 0); end; procedure TkktListBox.AdjuctScrollWidth(Message: TMessage); var sz: SIZE; begin GetTextExtentPoint32(Canvas.Handle, PChar(Message.LParam), StrLen(PChar(Message.LParam)), sz); if sz.cx + 4 > FScrollWidth then begin FScrollWidth := sz.cx + 4; Perform(LB_SETHORIZONTALEXTENT, FScrollWidth, 0); MaxLenItemIndex := Message.Result; end; end; procedure TkktListBox.ResetScrollWidth; var i, MaxWidth: Integer; sz: SIZE; begin MaxWidth := 0; i := Items.Count - 1; MaxLenItemIndex := -1; while i>=0 do begin sz.cx := 0; GetTextExtentPoint32(Canvas.Handle, PChar(Items[i]), Length(Items[i]), sz); if sz.cx + 4 > MaxWidth then begin MaxWidth := sz.cx + 4; MaxLenItemIndex := i; end; Dec(i); end; FScrollWidth := MaxWidth; Perform(LB_SETHORIZONTALEXTENT, FScrollWidth, 0); end; procedure Register; begin RegisterComponents('Kacarton', [TkktListBox]); end; end. |