A REAL SPINNER CONTROL FOR LIBERTY BASIC
(advanced level)
by Alyce Watson

Home

Remembering Logo
Turtle graphics tutorial
Scripting language tutorial
Changing window icons at runtime
A real spinner control
Tip Corner - Select Case
Hocus Focus
Illuminated Radiobuttons

A spinner, or updown control is a textbox with two small arrow buttons attached to one side. When a user presses the buttons, either by clicking on them with the mouse, or by pressing the up and down arrow keys on the keyboard, the value displayed in the textbox is incremented or decremented.

Pressing a regular push button only activates a routine once. To activate it again, the button must be released, then pressed again. This is not true of the arrow buttons on spinner controls. As long as the button is depressed, the value displayed in the textbox continues to change - it is incremented if the up arrow is being pressed, and decremented if the down arrow is being pressed.

Although it may sound as if this control would be complicated to create with API calls, and to use, it is actually quite simple. It does require a knowledge of the Windows API as used in Liberty BASIC, however, and that basic knowledge is assumed for this article.

Please note that this is for LB3 only. It is a good idea to include version checks in our programs to insure that the correct version of LB is used to run them:

if val(Version$)<3 then
     notice "Requires LB3."
     end
     end if

The function to create it is part of the common controls 32-bit DLL -- comctl32.dll. It is first necessary to initialize the DLL for use:

 calldll #comctl32, "InitCommonControls",re as void

The function is called "CreateUpDownControl". It requires several arguments. You must include the handle of the parent window, which is obtained with LB's HWND() function. It also requires the Instance Handle of the window, which is obtained with the GetWindowLongA function, using the _GWL_HINSTANCE flag.

 hwndParent = hwnd(#1)
 'get parent instance handle:
     CallDLL #user32, "GetWindowLongA",_
     hwndParent As long,_ 'window handle
     _GWL_HINSTANCE As long,_'want instance handle
     hInstance As long 'returns instance handle of window

The function arguments also include x, y, width and height values, which can all be set to 0, because our example gives the updown control a buddy textbox, and the control will be located and sized according to the buddy control. We'll need the handle of the buddy textbox as well:

 textbox #1.t, 50,40,60,26
     hText=hwnd(#1.t)

The function also allows us to set the upper limit value for the spinner as well as the lower limit. It also allows us to set the initial value to be displayed. The function returns a handle to the spinner (updown) control:

 x=0:y=0:wide=0:high=0:upr=100:lwr=0:pos=50
     calldll #comctl32, "CreateUpDownControl",_
     dwStyle as ulong,_ 'style
     x as long,_ 'x placement
     y as long,_ 'y placement
     wide as long,_ 'width
     high as long,_ 'height
     hwndParent as long,_ 'parent handle
     id as long,_ 'an ID number
     hInstance as long,_ 'parent instance handle
     hText as long,_ 'buddy control - a textbox handle
     upr as long,_ 'upper limit
     lwr as long,_ 'lower limit
     pos as long,_ 'initial value
     hSpinner as long 'handle of control


We haven't yet addressed an essential argument for the function. This is the style argument. All controls created by API must have a minimum style flag that includes the _WS_CHILD and _WS_VISIBLE window styles, so that the control is a child of the program window, and so that it is visible. It is also good to include the _WS_BORDER style so that the control has a nice appearance.

 dwStyle = _WS_CHILD or _WS_VISIBLE or _WS_BORDER 

There are other style bits that must be set for an updown spinnercontrol.

     
     UDS.SETBUDDYINT or UDS.ALIGNRIGHT or UDS.ARROWKEYS

Our demo uses the ones above. The UDS.SETBUDDYINT causes the buddy textbox to display the value continuously and automatically when the spinner is activated. The UDS.ALIGNRIGHT bit places the spinner on the right edge of the buddy textbox. The UDS.ARROWKEYS makes the spinner respond when the user presses the keyboard arrow keys.

Here are all of the possible UDS styles, along with their values and descriptions:


UDS.SETBUDDYINT = hexdec("2") Causes the up-down control to set the text of the buddy window (using the WM_SETTEXT message) when the position changes. The text consists of the position formatted as a decimal or hexadecimal string.

UDS.NOTHOUSANDS = hexdec("80") Does not insert a thousands separator between every three decimal digits.

UDS.HOTTRACK = hexdec("100") Causes the control to exhibit "hot tracking" behavior. That is, it highlights the UP ARROW and DOWN ARROW on the control as the pointer passes over them. This style requires Microsoft® Windows® 98 or Windows® 2000. If the system is running Windows® 95 or Windows NT® 4.0, the flag is ignored. To check whether hot tracking is enabled, call SystemParametersInfo.

UDS.HORZ = hexdec("40") Causes the up-down control's arrows to point left and right instead of up and down.

UDS.AUTOBUDDY = hexdec("10") Automatically selects the previous window in the z-order as the up-down control's buddy window.

UDS.ARROWKEYS = hexdec("20") Causes the up-down control to increment and decrement the position when the UP ARROW and DOWN ARROW keys are pressed.

UDS.ALIGNRIGHT = hexdec("4") Positions the up-down control next to the right edge of the buddy window. The width of the buddy window is decreased to accommodate the width of the up-down control.

UDS.ALIGNLEFT = hexdec("8") Positions the up-down control next to the left edge of the buddy window. The buddy window is moved to the right, and its width is decreased to accommodate the width of the up-down control.

UDS.WRAP = hexdec("1") Causes the position to "wrap" if it is incremented or decremented beyond the ending or beginning of the range.


The style bits as set in our demo:

 dwStyle = _WS_CHILD or _WS_VISIBLE or _WS_BORDER _
     or UDS.SETBUDDYINT or UDS.ALIGNRIGHT _
     or UDS.ARROWKEYS

When the program finishes, free the memory used by the control by destroying it with a call to DestroyWindow"

[quit]
     calldll #user32, "DestroyWindow",_
     hSpinner as long, re as long
     close #1:end

To discover the value chosen by the user, simply check the contents of the buddy textbox:

 #1.t "!contents? txt$"
     notice "Percent is ";txt$

Although it takes a few function calls to create the control, once it is created, it is very simple to get the buddy textbox contents with the Liberty BASIC "!contents? txt$" command to discover the value. If necessary, use the VAL() function to get a numeric value

answer = VAL(txt$)

Please see the attached file, updownspinner.bas for the complete demo program.


Home

Remembering Logo
Turtle graphics tutorial
Scripting language tutorial
Changing window icons at runtime
A real spinner control
Tip Corner - Select Case
Hocus Focus
Illuminated Radiobuttons