Download text file
#if 0
    ----------------------------                      PowerBASIC v8.x
 ---|          DASoft          |------------------------------------------
    ----------------------------         Code           DATE: 2005-02-19
    | FILE NAME scrollbar1.bas |          by
    ----------------------------  Don Schullian, Jr.

              This code is released into the Public Domain
       ----------------------------------------------------------
        No guarantee as to the viability, accuracy, or safety of
         use of this code is implied, warranted, or guaranteed
       ----------------------------------------------------------
                         Use at your own risk!
       ----------------------------------------------------------
                  CONTACT AUTHOR AT d83@DASoftVSS.com
 -------------------------------------------------------------------------
#endif

#if 0
There are 3 scrollbars demonstrated in this bit of code. Each one has a
corresponding label that shows the current value. The CtrlID for each label
is stored in the USER DATA area as are the handle of the scrollbar control and
the pointer to the UDT used to store and control the data for the scrollbar.

By using the USER data area I am able to control all 3 scrollbars with the same
lines of code, have no STATIC variable in the CALLBACK FUNCTION, and the values
if the scrollbars is available to the calling routine. It would also be possible,
using this concept to create a callback for any and all scrollbars in a given
program.

So, on to the code:

If you're not familiar with the USER DATA area for controls and dialogs you may
want to read up on them in the help file. These LONG integers are exteremly handy
when you need to pass information to and from the callback. They save having many,
many GLOBAL variables in your code and can, as shown here, allow shorter code to
be used. Each of the 3 scrollbars and 4 buttons use these variables to supply
information to the callback function.

The scrollbars store
   USER 6 = the CtrlID for the label
   USER 7 = the Handle of the scrollbar control
   USER 8 = the pointer to the UDT
The buttons store
   USER 7 = the value to be set
   USER 8 = the CtrlID of the scrollbar

When you create a scrollbar you need to set some parameters. I've done this in
the mother routine. Note that the nMax element of the UDT is set here to the
maximum value I want returned. This value is changed and reset in the
%WM_INITDIALOG message of the callback. This is because the handler routine in
Windows computes the nPage value along with the nMax value and it is easier to
make this one change during setup than to constantly compute the difference in
the callback code and when the return dialog ends.

Regardless of where or how you deal with the nMax value the scrollbars need to
be initialized before they can be used.

So... have a look at the code and take it from there.

Don
www.DASoftVSS.com
basic@DASoftVSS.com
#endif

#COMPILE EXE
#INCLUDE "WIN32API.INC"

%ID_SCROLLv = 2000 ' the 3 scrollbars need to be in sequential order so
%ID_SCROLLh = 2001 ' we can use a FOR/NEXT loop to manipulate them easily
%ID_SCROLL2 = 2002
'
'------------------------------------------------------------------------------
'
CALLBACK FUNCTION DlgCallback

  DIM  C    AS LOCAL LONG
  DIM  Ctrl AS LOCAL LONG
  DIM hCtrl AS LOCAL DWORD
  DIM tSB   AS LOCAL SCROLLINFO PTR

  SELECT CASE CBMSG
    CASE %WM_INITDIALOG : FOR Ctrl= %ID_SCROLLv TO %ID_SCROLL2            ' initialize the scrollbars
                            CONTROL GET USER CBHNDL, Ctrl, 7 TO hCtrl     ' get the control's handle
                            CONTROL GET USER CBHNDL, Ctrl, 8 TO tSB       ' get the pointer to the UDT
                            @tSB.nMax = @tSB.nMax + @tSB.nPage - 1        ' set the max with nPage computed
                            CONTROL SEND CBHNDL, Ctrl, %SBM_SETSCROLLINFO,%TRUE,tSB ' redraw & initialize scrollbar
                            @tSB.nMax  = @tSB.nMax - @tSB.nPage + 1       ' reset the max value
                            GOSUB UpdateLabel                             ' display current position
                          NEXT
    CASE %WM_COMMAND    : IF CBCTLMSG <> %BN_CLICKED THEN EXIT FUNCTION
                          CONTROL GET USER CBHNDL, CBCTL, 8 TO Ctrl       ' get the scrollbar's ctrlid
                          CONTROL GET USER CBHNDL, Ctrl,  8 TO tSB        ' get the pointer to the UDT
                          CONTROL GET USER CBHNDL, Ctrl,  7 TO hCtrl      ' get the handle of the ctrl
                          CONTROL GET USER CBHNDL, CBCTL, 7 TO @tSB.nPos  ' get the pre-set value
                          CONTROL SEND CBHNDL, Ctrl, %SBM_SETPOS, @tSB.nPos, %TRUE ' set new value & redraw
                          GOSUB UpdateLabel                               ' display current position
    CASE %WM_VSCROLL, _
         %WM_HSCROLL    : FOR Ctrl = %ID_SCROLLv TO %ID_SCROLL2           ' find which scrollbar was hit
                            CONTROL GET USER CBHNDL, Ctrl, 7 TO hCtrl     ' get the control's handle
                            IF hCtrl = CBLPARAM THEN                      ' if this one then
                              CONTROL GET USER CBHNDL, Ctrl, 8 TO tSB     '  get the UDT pointer
                              EXIT FOR                                    '  bailout of the loop
                            END IF
                          NEXT
                          IF hCtrl = 0 THEN EXIT FUNCTION                 ' this shouldn't be needed but.....
                          SELECT CASE LO(WORD,CBWPARAM)                   ' get the hot command
                            CASE %SB_LINEDOWN       : INCR @tSB.nPos
                            CASE %SB_PAGEDOWN       : @tSB.nPos = @tSB.nPos + @tSB.nPage
                            CASE %SB_LINEUP         : DECR @tSB.nPos
                            CASE %SB_PAGEUP         : @tSB.nPos = @tSB.nPos - @tSB.nPage
                            CASE %SB_THUMBPOSITION, _
                                 %SB_THUMBTRACK     : @tSB.nPos = HI(WORD,CBWPARAM)
                            CASE %SB_BOTTOM         : @tSB.nPos = @tSB.nMax
                            CASE %SB_TOP            : @tSB.nPos = 1
                            CASE %SB_ENDSCROLL      : EXIT FUNCTION
                          END SELECT
                          @tSB.nPos = MAX(@tSB.nMin, @tSB.nPos)                     ' can't be less than minimum
                          @tSB.nPos = MIN(@tSB.nMax, @tSB.nPos)                     ' can't be more than maximim
                          CONTROL SEND CBHNDL, Ctrl, %SBM_SETPOS, @tSB.nPos, %TRUE  ' Same as calling SetScrollPos (see above)
                          GOSUB UpdateLabel                                         ' display current position
                          FUNCTION = 1                                              ' send an 'I'm done' message to Windows
  END SELECT
  EXIT FUNCTION

  UpdateLabel:
    CONTROL GET USER CBHNDL, Ctrl, 6 TO C
    CONTROL SET TEXT CBHNDL, C   , FORMAT$(@tSB.nPos)
  RETURN

END FUNCTION
'
'------------------------------------------------------------------------------
'
FUNCTION PBMAIN

  DIM hdlg   AS LOCAL LONG
  DIM tSB(2) AS LOCAL SCROLLINFO
  DIM  Txt   AS LOCAL STRING

  DIALOG NEW 0, "SCROLLBAR Test",,, 200, 100, %WS_SYSMENU OR %WS_CAPTION TO hDlg

  CONTROL ADD BUTTON, hDlg, 1001, "Set Min", 135,  5, 50, 13
  CONTROL SET USER    hDlg, 1001, 7, 1
  CONTROL SET USER    hDlg, 1001, 8, %ID_SCROLLv

  CONTROL ADD BUTTON, hDlg, 1002, "Set Max", 135, 20, 50, 13
  CONTROL SET USER    hDlg, 1002, 7, 100
  CONTROL SET USER    hDlg, 1002, 8, %ID_SCROLLv

  CONTROL ADD BUTTON, hDlg, 1003, "Set Min",   5, 75, 50, 13
  CONTROL SET USER    hDlg, 1003, 7, 1
  CONTROL SET USER    hDlg, 1003, 8, %ID_SCROLLh

  CONTROL ADD BUTTON, hDlg, 1004, "Set Max",  60, 75, 50, 13
  CONTROL SET USER    hDlg, 1004, 7, 200
  CONTROL SET USER    hDlg, 1004, 8, %ID_SCROLLh

  CONTROL ADD LABEL , hDlg, 1005, ""       , 135, 35, 50, 13, %WS_CHILD Or %WS_VISIBLE Or %WS_BORDER Or %SS_CENTER Or %SS_CENTERIMAGE, %WS_EX_LEFT Or %WS_EX_LTRREADING
  CONTROL SET COLOR   hDlg, 1005, %BLACK, %WHITE

  CONTROL ADD LABEL , hDlg, 1006, ""       , 115, 75, 50, 13, %WS_CHILD Or %WS_VISIBLE Or %WS_BORDER Or %SS_CENTER Or %SS_CENTERIMAGE, %WS_EX_LEFT Or %WS_EX_LTRREADING
  CONTROL SET COLOR   hDlg, 1006, %BLACK, %WHITE

  CONTROL ADD LABEL , hDlg, 1007, ""       ,   5,  5, 15, 13, %WS_CHILD Or %WS_VISIBLE Or %WS_BORDER Or %SS_CENTER Or %SS_CENTERIMAGE, %WS_EX_LEFT Or %WS_EX_LTRREADING
  CONTROL SET COLOR   hDlg, 1007, %BLACK, %WHITE

  CONTROL ADD SCROLLBAR, hDlg, %ID_SCROLLv, "", 190, 0, 10, 100, %SBS_VERT OR %SBS_RIGHTALIGN
  tSB(0).cbSize = SIZEOF(SCROLLINFO)   ' size of UDT
  tSB(0).fMask  = %SIF_ALL             ' Sets nPage, nPos, nMin, and nMax
  tSB(0).nMin   =   1                  ' 1st position
  tSB(0).nMax   = 100                  ' Last position + nPage - 1
  tSB(0).nPage  =  10                  ' size of cursor block
  tSB(0).nPos   =  50                  ' starting position
  CONTROL SET USER hDlg, %ID_SCROLLv, 6, 1005
  CONTROL SET USER hDlg, %ID_SCROLLv, 7, GetDlgItem(hDlg,%ID_SCROLLv)
  CONTROL SET USER hDlg, %ID_SCROLLv, 8, VARPTR(tSB(0))

  CONTROL ADD SCROLLBAR, hDlg, %ID_SCROLLh, "", 0, 90, 190, 10, %SBS_HORZ OR %SBS_BOTTOMALIGN
  tSB(1).cbSize = SIZEOF(SCROLLINFO)   ' size of UDT
  tSB(1).fMask  = %SIF_ALL             ' Sets nPage, nPos, nMin, and nMax
  tSB(1).nMin   =   1                  ' 1st position
  tSB(1).nMax   = 200                  ' Last position + nPage - 1
  tSB(1).nPage  =  10                  ' size of cursor block
  tSB(1).nPos   = 100                  ' starting position
  CONTROL SET USER hDlg, %ID_SCROLLh, 6, 1006
  CONTROL SET USER hDlg, %ID_SCROLLh, 7, GetDlgItem(hDlg,%ID_SCROLLh)
  CONTROL SET USER hDlg, %ID_SCROLLh, 8, VARPTR(tSB(1))

  CONTROL ADD SCROLLBAR, hDlg, %ID_SCROLL2, "", 20, 5, 20, 13, %SBS_VERT
  tSB(2).cbSize = SIZEOF(SCROLLINFO)   ' size of UDT
  tSB(2).fMask  = %SIF_ALL             ' Sets nPage, nPos, nMin, and nMax
  tSB(2).nMin   =   1                  ' 1st position
  tSB(2).nMax   =  15                  ' Last position + nPage - 1
  tSB(2).nPage  =   1                  ' size of cursor block
  tSB(2).nPos   =   1                  ' starting position
  CONTROL SET USER hDlg, %ID_SCROLL2, 6, 1007
  CONTROL SET USER hDlg, %ID_SCROLL2, 7, GetDlgItem(hDlg,%ID_SCROLL2)
  CONTROL SET USER hDlg, %ID_SCROLL2, 8, VARPTR(tSB(2))

  DIALOG SHOW MODAL hDlg CALL DlgCallback

  Txt = "Vert Scrollbar" & STR$(tSB(0).nPos) & $CRLF & _
        "Horz Scrollbar" & STR$(tSB(1).nPos) & $CRLF & _
        "Scrollbar2"     & STR$(tSB(2).nPos)
  MSGBOX Txt, %MB_OK, "Results"

END FUNCTION