麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

發掘ListBox的潛力(一):自動調整橫向滾動條寬度

2019-11-18 18:06:09
字體:
來源:轉載
供稿:網友
自繪ListBox的兩種效果》一文帖出之后,從反饋信息來看,大家對這種小技巧還是很認同。接下來我將繼續圍繞ListBox寫一系列的文章,進一步發掘ListBox的潛力,其中包括:自動調整橫向滾動條寬度、即時提示(Tips)、拖放插入點提示等,并在最后制作一個在滾動區內的ListBox組。

自動調整橫向滾動條寬度

  網上可以找到很多讓Listbox產生橫向滾動條的文章,其中的方法基本一樣,就是定義一個函數,遍歷Items取得最大的TextWidth值,然后發Listbox發消息LB_SETHORIZONTALEXTENT產生橫向滾動條。典型例子如下:

PRocedure SetWidth(Sender: TObject);
var
    i, w: Integer;
begin
    w := 0;
    with ListBox1 do begin
        for i:=0 to Items.Count -1 do begin
            if Canvas.TextWidth(Items[i]) > w then
                w := Canvas.TextWidth(Items[i]);
        end;
        SendMessage(Handle, LB_SETHORIZONTALEXTENT, w+4, 0);
    end;
end;
  以上代碼的確可用而且被廣泛使用,但它有一個很大的缺點:效率大低。因為每次在Listbox中追加、插入或刪除一個條目時,都要調用此函數重新計算橫向滾動條寬度,而遍歷所有項目和調用TextWidth都是很是很耗時的操作。如果用戶將條目從當前Listbox拖往另一個Listbox,那么用戶一個操作將有兩個Listbox必須重新計算橫向滾動條寬度,當Listbox內容有上百條的時候,你將明顯感覺反應遲緩。
  OK,現在換個思路。
  當追加或插入新條目時,只要判斷新內容的TextWidth是否大于滾動條寬度,如果是調整滾動條寬度即可。那么刪除呢?是的,遍歷是不可避免的,但并不是每次刪除都需要。可以定義一個變量記錄Listbox中TextWidth值最大的條目Index,只有刪除這個條目時才需要遍歷,其它時候完全可以不管它。
  還有一種情況必須考慮,用戶可能會改變屏幕字體,這時也必須重新計算橫向滾動條寬度。跟刪除操作一樣計算原最大條目的新TextWidth值即可。
  如果窗體上有多個Listbox,記錄每個Listbox的最大條目也是一件很麻煩的事,所以我把它封裝起來,下面給出完整代碼:

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.


上一篇:如何使程序在運行時自動注冊ActiveX控件

下一篇:CRC算法的實現

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

主站蜘蛛池模板: 黄色片网站在线免费观看 | 性高湖久久久久久久久aaaaa | 成人性视频欧美一区二区三区 | 黄色大片高清 | 国产精品成人av片免费看最爱 | 青草av.久久免费一区 | 亚洲最大的成人网 | 欧美成人一区二区三区 | 曰韩av在线 | 亚洲特黄 | 失禁高潮抽搐喷水h | 久久久久久中文字幕 | 久久吊 | 久久色网站 | 91精品国产日韩91久久久久久360 | 亚洲福利视 | 黄色大片在线观看 | 欧美18videos性处按摩 | 国产精品视频yy9299一区 | 欧美日本不卡 | 国产一区二区精品在线观看 | 综合网天天射 | 欧美成人免费 | 国产黄网 | 91色琪琪电影亚洲精品久久 | 亚洲αv | 深夜福利视频免费观看 | 成年人激情在线 | 久久成人视屏 | 久久中文免费 | 136福利视频 | 成人 在线| 成人三级电影网址 | 蜜桃视频观看麻豆 | 亚洲第一成网站 | 精品一区二区三区欧美 | 27xxoo无遮挡动态视频 | 中文字幕在线观看网址 | 国产99久久久国产精品 | 欧美日本中文字幕 | 精品国产一区二区三区天美传媒 |