![]() |
The list box got a new faceKhaled Shagrouni, May 31, 2001 | ||
|
|
Are you tiered of the old same looking style of the ListBox control? Do you want something with a modern look and feel as found it in current commercial software? Here I am
continuing the series I started on how to give your common used controls a
better look and feel. See my previous articles: The code I presenting here targeting the ListBox control. If you are test-then-read person (like me) then go direct to the code listing , or just download the example project files: xlist.zip .
Little intro: Windows native implementation of the list box control doesn't change much in visual aspects since version 3.1 (except for 3D border and scroll bar, I guess), fortunately, Windows leaves the door open for us to introduce our own painting and override the default through OWNER-DRAW style. Borland made a good decision, since Delphi 1, to incorporate methods to deal with this style for most of the windows owner-draw controls. The goal: The code purpose is to provide a list box with appearance and behavior can be defined and controlled by us from within our application. The code tries to implement the following characteristics:
The method: The method is simple, and can be applied in many other controls: Whenever Windows need to paint a control, it will issue messages to the application, so the application can take the responsibility and provide its own implementation of drawing the control. The main information Windows send is the rectangle of the portion of control to be pained, and the corresponding item identity. For our case, the list box, we first set the property style of the list box to either lbOwnerDrawFixed, or lbOwnerDrawVariable, this will force Delphi to create the list box with the new style, and internally informs Windows about the procedure that will take care of the painting, so Windows can take it into account to send the needed information to this procedure whenever a control needs to be drawn. This procedure is the event handler that we will take care in onDrawItem event of the list box. Once we have the coordinates (rect) of the item on the control ‘s surface, we can apply any drawing methods on it by using Delphi canvas methods, or by a direct call to Windows API functions. Code layout: The code is not just an example or a how-to tip; my intention for the code is to be a workable solution that can be plugged into a real application without extra hassles. For this reason, you will see that the main procedures are independent to the form class, global variables are avoided, the procedures can be moved to other units (libraries, components,..) with less pain, plus taking care (as possible) to preserve reliability, and the general list box functionality. Beginners to Delphi can deal with the code as a black box, aside from their own event handlers, so they can feel safe while approaching the code. Any way, a more dictated work, with less restriction, can be done if we move this code to be a base for an independent component. To demonstrate the code we need a ListBox with few items, style property set to lbOwnerDrawVariabl and an image control with a small bmp picture. The code has four main procedures, each one will be called from within a list box respective event (except ListBoxRefresh ). Procedure: ListBoxDrawItem
Procedure: ListBoxMeasureItem
Procedure: ListBoxMouseMove
Procedure: ListBoxRefresh
Notes:
Hope you'll enjoy it.
Download the sample project: xlist.zip (15
KB)
|
| Delphi Papers |
Shagrouni 2001 Khaled Shagrouni khaled@shagrouni.com