Discover the potential of ListBox (1): Automatically adjust the horizontal scroll width

xiaoxiao2021-03-06  40

After the "two effects of self-painted ListBox", after the feedback information, everyone is still very recognized to this tip. Next I will continue to write a series of articles around ListBox, further explore the potential of Listbox, including: automatically adjust the horizontal scroll bar width, instant prompt (tips), drag and drop insertion point prompt, etc., and make one in the rolling area Listbox group. Automatically adjust the horizontal scroll bar width online, you can find a lot of articles that cause Listbox to generate a horizontal scroll bar. The method is basically, that is, define a function, traversing the maximum textWidth value, then sending the Listbox send message LB_SETHORIZONTALEXTENT generates a horizontal scroll bar. Typical examples are as follows:

Procedure setwidth; 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; the above code is indeed available and widely used, but it has a lot of disadvantages : The efficiency is low. Because each time you add, insert or delete an entry each time, call this function to recalculate the horizontal scroll bar width, and all items and calling textWidth are very time consuming. If the user will drag the entry from the current Listbox to another, the user will have two Listbox to recalculate the horizontal scroll bar width. When listbox has hundreds of people, you will obviously feel slowly. OK, now change your ideas. When adding or inserting new entries, as long as the textWidth of the new content is greater than the scroll bar width, if it is adjusted to the scroll bar width. So deleted? Yes, traversal is inevitable, but not every deletion needs. You can define an entry index that the TEXTWIDTH value in ListBox is required, and it needs to be traversed when you delete this entry, and you can completely do it. There is also a situation that must be considered that the user may change the screen font, and the horizontal scroll bar width must be recalculated. The new TextWidth value of the original maximum entry is calculated as the deletion operation. If there are multiple Listbox on the form, record the biggest entry of each ListBox is also a very troublesome thing, so I put it up, below the full code:

Unit kktlistbox; {============================================= ========================== Design By: Peng Guofei Date: http://kacarton.yeah.net/ blog : Http://blog.9cbs.net/nhconch email: Kacarton # sohu.com Articles for the author Original, please contact me before reprinting, please indicate the article, retain the author information, thank you for your support! ============================================================================================================================================================================================================= =======================} Interfaceuses 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; procedure CreateWnd; override; end; procedure Register; implementation {TkktListBox} constructor TkktListBox.Create (AOwner: TComponent);

begin inherited Create (AOwner); MaxLenItemIndex: = -1; FScrollWidth: = 0; end; procedure TkktListBox.CreateWnd; begin inherited CreateWnd; Canvas.Font: = Font; 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; if Message.WParam <= MaxLenItemIndex then MaxLenItemIndex : = MaxLenItemIndex 1; 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: size; begin inherited; if maxlenitemindex = -1 theen exit; // This is not using textWidth, but use the getTextExtentPoint32 function, if you are interested, you can track a TextWidth function, It ultimately call GetTexTextentPoint32 (Canvas.Handle, Pchar (IT) ems [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>

转载请注明原文地址:https://www.9cbs.com/read-77057.html

New Post(0)