Explore the potential of ListBox (1): automatically adjust the horizontal scroll bar width

Source: Internet
Author: User

After posting the article "two effects of Self-painted ListBox", from the feedback, we still agree with this kind of tips. Next, I will continue to write a series of articles around ListBox to further explore the potential of ListBox, including automatic adjustment of horizontal scroll bar width, real-time tip (TIPS), drag-and-drop insertion tips, etc, create a ListBox group in the rolling area at the end.

Auto adjust horizontal scroll bar width

You can find a lot of articles on the Internet that let ListBox generate a horizontal scroll bar. The method is basically the same. It is to define a function, traverse items to obtain the maximum textwidth value, and then send a message to lb_sethorizontalextent to generate a horizontal scroll bar. A typical example is as follows:

ProcedureSetwidth (Sender: tobject );
VaR
I, W: integer;
Begin
W: = 0;
WithListbox1Do begin
ForI: = 0ToItems. Count-1Do begin
IfCanvas. textwidth (items [I])> WThen
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 major drawback: high efficiency. Every time you append, insert, or delete an entry in ListBox, you must call this function to recalculate the width of the horizontal scroll bar. It is very time-consuming to traverse all projects and call textwidth. If you drag an entry from the current ListBox to another ListBox, you must recalculate the width of the horizontal scroll bar for two listboxes in one operation. When there are hundreds of entries in the ListBox, you will obviously feel slow.
OK. Now let's change your mind.
When appending or inserting a new entry, you only need to determine whether the textwidth of the new content is greater than the scroll bar width. If it is to adjust the scroll bar width, you can. What about deletion? Yes, traversal is inevitable, but it is not required for each deletion. You can define the index of the entry with the maximum textwidth value in The ListBox variable record. Only the entry needs to be traversed when it is deleted, but it can be ignored in other cases.
In another case, the user may change the screen font, and the width of the horizontal scroll bar must be recalculated. Calculate the new textwidth value of the original maximum entry just like the delete operation.
If there are multiple listboxes on the form, it is also very troublesome to record the maximum entries of each ListBox, So I encapsulate it. The complete code is given below:

UnitKktlistbox;

{===================================================== ======================================
Design by: Peng Guohui
Date: 2004-12-24
Site: http://kacarton.yeah.net/
Blog: http://blog.csdn.net/nhconch
Email: kacarton # sohu.com

The article is original to the author. Please contact me before reprinting. for reprinting, please indicate the source of the article and retain the author information. Thank you for your support!
========================================================== =====================================}

Interface

Uses
Windows, messages, sysutils, classes, controls, stdctrls, commctrl;

Type
Tkktlistbox =Class(Tlistbox)
Private
Maxlenitemindex: integer;
Fscrollwidth: integer;
ProcedureLbaddstring (VaR message: Tmessage );MessageLb_addstring;
ProcedureLbinsertstring (VaR message: Tmessage );MessageLb_insertstring;
ProcedureLbdeletestring (VaR message: Tmessage );MessageLb_deletestring;
ProcedureCmfontchanged (VaR message: Tmessage );MessageCm_fontchanged;
ProcedureAdjuctscrollwidth (Message: Tmessage );
ProcedureResetscrollwidth;

Protected

Public
ConstructorCreate (aowner: tcomponent );Override;
ProcedureCreatewnd;Override;

End;

Procedure Register;

Implementation

{Tkktlistbox}

ConstructorTkktlistbox. Create (aowner: tcomponent );
Begin
InheritedCreate (aowner );
Maxlenitemindex: =-1;
Fscrollwidth: = 0;
End;

ProcedureTkktlistbox. createwnd;
Begin
Inherited
Createwnd;
Canvas. Font: = font;
End;

ProcedureTkktlistbox. lbaddstring (VaR message: Tmessage );
Begin
Inherited;
IfMessage. Result = lb_errThenExit;
Adjuctscrollwidth (Message );
End;

ProcedureTkktlistbox. lbinsertstring (VaR message: Tmessage );
Begin
Inherited;
IfMessage. Result = lb_errThenExit;
IfMessage. wparam <= maxlenitemindexThenMaxlenitemindex: = maxlenitemindex + 1;
Adjuctscrollwidth (Message );
End;

ProcedureTkktlistbox. lbdeletestring (VaR message: Tmessage );
Begin
Inherited;
IfMessage. Result = lb_errThenExit;
IfMessage. wparam = maxlenitemindexThenResetscrollwidth;
End;

ProcedureTkktlistbox. cmfontchanged (VaR message: Tmessage );
VaR
SZ: size;
Begin
Inherited;
IfMaxlenitemindex =-1ThenExit;
// Textwidth is not used here, but the gettextextentpoint32 function is used. If you are interested
// You can trace a textwidth function, which is implemented by calling gettextextentpoint32.
Gettextextentpoint32 (canvas. Handle, pchar (items [maxlenitemindex]), length (items [maxlenitemindex]), SZ );
Fscrollwidth: = Sz. cx + 4;
Perform (lb_sethorizontalextent, fscrollwidth, 0 );
End;

ProcedureTkktlistbox. adjuctscrollwidth (Message: Tmessage );
VaR
SZ: size;
Begin
Gettextextentpoint32 (canvas. Handle, pchar (message. lparam), strlen (pchar (message. lparam), SZ );
IfSZ. cx + 4> fscrollwidthThen Begin
Fscrollwidth: = Sz. cx + 4;
Perform (lb_sethorizontalextent, fscrollwidth, 0 );
Maxlenitemindex: = message. result;
End;
End;

ProcedureTkktlistbox. resetscrollwidth;
VaR
I, maxwidth: integer;
SZ: size;
Begin
Maxwidth: = 0;
I: = items. Count-1;
Maxlenitemindex: =-1;
WhileI> = 0Do begin
SZ. CX: = 0;
Gettextextentpoint32 (canvas. Handle, pchar (items [I]), length (items [I]), SZ );
IfSZ. cx + 4> maxwidthThen 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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.