How to Set Tab Stops in a Visual Basic List BoxLast reviewed: August 1, 1996Article ID: Q71067 |
The information in this article applies to:
SUMMARYVisual Basic version 3.0 has intrinsic multiple-column list boxes. You create the multiple columns by dividing the linear list of items into columns, based on the size of the list box. However, this can lead to overlapped columns if the length of the items in the list exceed the area allocated automatically by the list box. NOTE: This is different than setting the Columns property of the list box, which merely determines whether a list box scrolls vertically or horizontally. This article contains information on using the Windows API to create a multiple-column list box by setting the tab stops of the list box, thus creating the multiple-column effect. The related topics of dialog box units, dialog box base units, and providing a horizontal scroll bar on a list box are also covered.
MORE INFORMATIONFor a complete example of this method used in a more generic manner, please see the following article in the Microsoft Knowledge Base:
ARTICLE-ID: Q115712 TITLE : How to Fill a List Box from a Snapshot GenericallyTo create the multiple-column effect in list boxes, you must use the Windows API SendMessage function. If you use the argument LB_SETTABSTOPS as the second parameter to SendMessage, it will set the tab stops you want for the multicolumn effect based on the other arguments to the function. The SendMessage function requires the following parameters to set tab stops:
SendMessage (hWnd%, LB_SETTABSTOPS, wParam%, lparam&)where
wParam% is an integer that specifies the number of tab stops. lParam& is a long pointer to the first member of an array of integers containing the tab-stop position in dialog box units.For this to work, the values in the tab-stop array must be cumulative. For example, if you want to set three consecutive tabs every 50 units, you need to load the tab-stop array with 50, 100, and 150. The tabs work the same as typewriter tabs: once a tab stop is overrun, a tab character moves the cursor to the next tab stop. If the tab-stop list is overrun (that is, if the current position is greater than the last tab-stop value), the default tab value of 8 characters is used.
Dialog Box Units and Dialog Box Base UnitsTab stops in a list box are specified in dialog box units, not pixels or character position. Essentially, a dialog box unit is used by Windows to size a control based on the average character width of the current system font. This average character width is called the dialog box base unit, and 1 dialog box base unit equals 4 dialog box units (1:4 ratio). When setting tab stops in the list box, however, dialog box units are based on the average character width, in pixels, of the currently selected font for the list box. Thus, you have to calculate the average character width of the current font in the list box before you can set its tab stops. The average character width is based on the average width of the upper- and lower-case characters of the alphabet; therefore, it can be calculated in the sample code as follows:
' First set the form's font properties to match the list box. Me.FontName = list1.FontName Me.FontSize = list1.FontSize Me.FontBold = list1.FontBold Me.FontItalic = list1.FontItalic Me.FontStrikethru = list1.FontStrikethru Me.FontUnderline = list1.FontUnderline ' Make use of the form's TextWidth function to calculate the average ' character width of the alphabet. Visual Basic uses Twips and the ' SendMessage API needs pixels, so use "screen.TwipsPerPixelX" to ' convert. ' The following code is used to return the dialog box unit ' equivalent to one character: alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" AvgCharWidth = (Me.TextWidth(alphabet) / 52) / screen.TwipsPerPixelX ' Calculate the dialog box unit for the list box. ListBoxDialogBoxUnit = AvgCharWidth \ 4You now have a way to relate dialog box units to pixel position. So to set a tab stop at a specific pixel position, take the number of pixels, divide by the average character width (gives us the number of dialog box base units) and multiply by 4 to give us the dialog box units. In code, this looks like the following:
TabStop1 = (Me.TextWidth("Hello")/screen.TwipsPerPixelX \ AvgCharWidth)*4NOTE: The example code assumes that the form's scale mode is the default Twips. If the scale mode is set to pixels, then the division by screen.TwipsPerPixelX is extraneous and should be removed. Also note that you could use the TextWidth method of a picture control if you didn't want to change the font properties of the form.
Providing a Horizontal Scroll BarWhen you use SendMessage to set tab stops, the Visual Basic list box does not automatically provide the horizontal scroll bar. To set the horizontal extent of the list box, use the API SendMessage with the LB_SETHORIZONTALEXTENT message. First, calculate the size, in pixels, of the scrolling region (based on the largest row entered into the list box). If you specify the horizontal extent to be larger than the width of the list box, a horizontal scroll bar is displayed. The message LB_SETHORIZONTALEXTENT expects the extent to be specified in pixels. Because the tab-stop array holds dialog box units, which represent 4 times the number of average character spaces, to get that value converted back into pixels, perform the inverse operation.
' For simplicity, assume container scale mode of pixels. num_chars = Me.TextWidth("Total Character String") \ AvgCharWidth ListBoxDialogBoxUnits = num_chars * 4So the inverse operation is:
num_pixels = (ListBoxDialogBoxUnits \ 4) * AvgCharWidth Step-by-Step Instructions for Creating the Program
tabstops(2) = tabstops(1) + ((Me.TextWidth(s(2)) /screen.TwipsPerPixelX + WhiteSpace) \ AvgCharWidth) * 4
' This third value isn't necessary for the tab stops, but it is used ' to set the extent of the horizontal scrolling area. tabstops(3) = tabstops(2) + ((Me.TextWidth(s(3)) /screen.TwipsPerPixelX + WhiteSpace) \ AvgCharWidth) * 4
' Set the tab stops for the list box in dialog box units. retL = SendMessage(list1.hWnd, LB_SETTABSTOPS, 3, tabstops(1)) ' Set the horizontal extent to the last tab stop. ' Because the tab-stop array holds dialog box units (which represent ' 4 times the number of characters), to get that value converted ' into pixels, perform the inverse operation. retL = SendMessage(list1.hWnd, LB_SETHORIZONTALEXTENT, (tabstops(3)\ 4) * AvgCharWidth, 0&)
' Tell the list box to refresh its display. list1.Refresh ' Restore form's property values. Me.FontName = hold_fontname Me.FontSize = hold_fontsize Me.FontBold = hold_fontbold Me.FontItalic = hold_fontitalic Me.FontStrikethru = hold_fontstrikethru Me.FontUnderline = hold_fontunderline End Sub
|
Additional reference words: 2.00 3.00
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |