Horizontal Scrolling for Combo Boxes - JeffLuther.net

6 downloads 586 Views 68KB Size Report
My approach was to locate the list box control owned by the combo box and “ force” it to display a horizontal scroll ... in the combo box class) to set the horizontal ...
Pro

Centura

Horizontal Scrolling for Combo Boxes R.J. David Burke

G

etting horizontal scroll bars As discussed in the With Win32 it seems that Microsoft on a combo box should be a aforementioned article, the has stopped supporting horizontal no-brainer. From reading the WM_PARENTNOTIFY message is scroll bars for combo boxes. Not Win32 SDK, it seems that you simply used to obtain the “link” to the only does this article reveal a need to send a combo box’s list box (by storing the technique to get horizontal scroll CB_SETHORIZONTALEXTENT window handle). Then the bars for combo boxes, it also shows message to the combo box. However, WS_HSCROLL style is added to the how to calculate the pixel I couldn’t get this to work, and it list box. Later, you’ll call the dimensions for a text string. seems that others are having the SetHorizontalExtent method (defined same problem, as this has come up in the combo box class) to set the more than a few times in the newsgroups. (If anyone out horizontal extent size. A horizontal scroll bar will be displayed when the horizontal extent is there knows a simpler technique than that presented here, a score of developers—including myself—are interested.) greater than the width of the combo box’s list. By default the SetHorizontalExtent method is called A hunch paid off and I found a way to get horizontal on SAM_Create of the combo box. scroll bars onto combo boxes. Here’s the result of my perseverance.

Setting the horizontal extent Forcing the horizontal scroll bar My approach was to locate the list box control owned by the combo box and “force” it to display a horizontal scroll bar by changing the style settings of the list box itself. Locating the list box control is relatively easy, I just borrowed my code from “The Elusive SQLWindows Read Only Combo Box,” which appeared in the October 1998 issue of 32 Centura Pro. See Listing 1.

Just adding a horizontal scroll bar isn’t enough. The horizontal extent of the combo box’s list box needs to be set to engage the horizontal scroll bar. The SetHorizontalExtent function provides a fair amount of flexibility for setting the horizontal extent. I present the code in Listing 2.

Listing 1. Locating the combo box’s list box and changing its style. ◆ On WM_PARENTNOTIFY ◆ If NOT __bInit ◆ If SalNumberLow( wParam ) = WM_CREATE ◆ Set __hWndList = SalNumberToWindowHandle( lParam ) ◆ Call SalStrSetBufferLength( __sClassName, 256 ) ◆ Call GetClassNameA( __hWndList, __sClassName, 255 ) ◆ If SalStrScan( SalStrUpperX( __sClassName ), 'COMBOLBOX' ) > -1 ◆ Set __bInit = TRUE ◆ Call SetWindowLongA( __hWndList, GWL_STYLE, GetWindowLongA( __hWndList, GWL_STYLE ) | WS_HSCROLL ) ◆ On SAM_Create ◆ Call SetHorizontalExtent( 0 )

Listing 2. The SetHorizontalExtent method. ◆ Function: SetHorizontalExtent ◆ Description: ◆ Returns ◆ Parameters ◆ Number: p_nExtent ◆ Static Variables ◆ Local variables ◆ Number: nNumItems ◆ Number: nLeft ◆ Number: nTop ◆ Number: nRight ◆ Number: nBottom ◆ Number: n ◆ Number: hDC ◆ String: sItemText ◆ Number: nMaxWidth ◆ Number: nWidth ◆ Number: nHeight ◆ Actions ◆ If p_nExtent = 0

Continues on page 12

10

Centura Pro March 1999

http://www.ProPublishing.com

go to the front of the list, AddTail to go to the end, or use InsertBefore or InsertAfter with the OperationKey value to go to a position relative to another wizard. Wizards are always modal; all Builder windows are disabled before the wizard is launched and enabled after the wizard returns. DLL wizards are launched by loading the DLL and calling the specified start function (in DllFunctionStart). This function is passed one parameter, the window handle of Builder.

EXE wizards are launched with a command line that specifies the executable name, the title text of the wizard, the outline handle, and the window handle of Builder. The handles are string representations. If the title text is a multi-word value, each word is a parameter. For EXE wizards, you don’t normally have to be concerned with handling the command line arguments, you can just call IsLaunchedAsWizard (from cdkItem) on startup of your wizard application. CP R.J. David Burke is a Senior Consulting Engineer with Centura Software Corp. David can be contacted through the editorial staff of Centura Pro.

Horiztonal Scrolling . . . Continued from page 10 ◆ Set nNumItems = SalListQueryCount( hWndItem ) ◆ If nNumItems ◆ Set nMaxWidth = 0 ◆ Set hDC = GetDC( hWndItem ) ◆ Call SelectObject( hDC, SalSendMsg( hWndItem, WM_GETFONT, 0, 0 ) ) ◆ Set n = 0 ◆ While n < nNumItems ◆ Set sItemText = SalListQueryTextX( hWndItem, n ) ◆ Call GetTextExtentPoint32A( hDC, sItemText, SalStrLength( sItemText ), nWidth, nHeight ) ◆ If nWidth > nMaxWidth ◆ Set nMaxWidth = nWidth ◆ Set n = n + 1 ◆ Call ReleaseDC( hWndItem, hDC ) ◆ Set p_nExtent = nMaxWidth + 6 ! add a few of pixels for readability ◆ Else ◆ Call GetClientRect( hWndItem, nLeft, nTop, nRight, nBottom ) ◆ Set p_nExtent = nRight * 1.3 ◆ Call SalSendMsg( __hWndList, LB_SETHORIZONTALEXTENT, p_nExtent, 0 )

The function takes a single parameter that specifies the desired horizontal extent in pixels. In the simplest case the passed value is used to set the horizontal extent of the list box portion of the combo box. If a value of 0 is passed, the function uses the following algorithm to set the horizontal extent of the combo box’s list box. If there are no items in the list box, the GetClientRect is called to get the width of the list box. The horizontal extent is set to the width plus 30 percent in anticipation of future items exceeding the width. If there are items in the combo box, then each item is examined and the width of the longest item is used (plus some margin for readability) as the horizontal extent. The width of item text is dependent on the font being used. To determine this width I borrowed some more of my code, this time from one of my old uploads to the Gupta/Centura forum on CompuServe. The code is from my auto-sizing

12

Centura Pro March 1999

table window column class, upgraded for Win32. The GetTextExtentPoint32 function from the Windows API returns the height and width (in pixels) of a text string for a specified font. A font handle for the function can be extracted from a window control using the SelectObject function.

Using the cCmbHorizScroll class

Using the provided combo box class (see download instructions at the end of the article) is straightforward. If text items are declared in the List Initialization section of the item, then the inherited SAM_Create message handler that calls SetHorizontalExtent( 0 ) is fine. If you’re populating the combo box during the execution of the application, such as with a SalListPopulate, for example, then call SetHorizontalExtent after the population of the combo box is complete. Deriving new combo boxes from cCmbHorizScroll is also straightforward. The class can easily be used as a mix-in class in a combo box class hierarchy, or as a base class in its own right.

Happy Hacking Another handy technique for your SAL tool kit. In the immortal words of Arthur van Hoff, “Have fun!” CP Download HorizCmb.ZIP from this issue’s Table of Contents at www.propublishing.com or find it on this month’s Companion Disk.

http://www.ProPublishing.com