User Tools

Site Tools


changing_20the_20step_20size_20of_20an_20up-down_20control

Changing the step size of an up-down control

by Richard Russell, July 2014

When you create an up-down control you can easily choose the minimum and maximum values, and the direction in which it changes (i.e. whether clicking on the up arrow increases or decreases the value). However you cannot choose the step size: each click always changes the value by either +1 or -1 (or zero if the limit has been reached).

To modify the behaviour of the up-down control requires a small piece of assembler code. The simplest option is to change the step size to a value other than one; the code example below demonstrates setting it to five:

        REM!WC
        UDN_DELTAPOS = -722
        WM_NOTIFY = 78
        ES_NUMBER = 8192
        UDM_SETRANGE = 1125
 
        INSTALL @lib$+"WINLIB2"
        dlg% = FN_newdialog("test1",100,100,100,100,8,200)
 
        PROC_editbox(dlg%,"50",101,10,10,50,10,ES_NUMBER)
        PROC_dlgctrl(dlg%,"",102,0,0,0,0,&50000096,"msctls_updown32")
 
        PROC_showdialog(dlg%)
        PROCsetdelta(!dlg%, 102, 5)
        SYS "SendDlgItemMessage", !dlg%, 102, UDM_SETRANGE, 0, (0 << 16) + 100
        SYS "SetDlgItemText", !dlg%, 101, "40"
 
        ON ERROR  PROC_closedialog(dlg%):PRINT REPORT$:END
        ON CLOSE  PROC_closedialog(dlg%):QUIT
 
        REPEAT
          WAIT 1
        UNTIL FALSE
        PROC_closedialog(dlg%)
        END
 
        DEF PROCsetdelta(hdlg%, udid%, delta%)
        LOCAL D%,M%,O%,P%
        PRIVATE C%,L% : IF C%=0 DIM C% 100, L% -1
        P% = C%
        SYS "GetWindowLong", hdlg%, -4 TO O%
        [OPT 10
        .D% pop eax : push O% : push eax : jmp "CallWindowProc"
        .M% cmp dword [esp+8],WM_NOTIFY : jnz D%
        mov edx,[esp+16] : cmp dword [edx+4],udid% : jnz D%
        cmp dword [edx+8],UDN_DELTAPOS : jnz D%
        mov eax,[edx+16] : imul eax,delta% : mov [edx+16],eax
        xor eax,eax : ret 16
        ]
        SYS "SetWindowLong", hdlg%, -4, M%
        ENDPROC

The procedure PROCsetdelta takes three parameters: the handle of the dialogue box, the ID of the up-down control and the desired step size.

However this may not always be what you want. Suppose that the contents of the associated edit box are initially 1 rather than 0 (for example because the user has typed in that value). Now, when you click the up button, the value will change to 6, then 11, then 16 and so on. You might prefer that instead of adding (or subtracting) 5, the up-down control changes the value to the next multiple of 5, so that the first click will change it from 1 to 5 (rather than 6). That can be achieved using this slightly more complicated code:

        REM!WC
        UDN_DELTAPOS = -722
        WM_NOTIFY = 78
        ES_NUMBER = 8192
        UDM_SETRANGE = 1125
 
        INSTALL @lib$+"WINLIB2"
        dlg% = FN_newdialog("test1",100,100,100,100,8,200)
 
        PROC_editbox(dlg%,"50",101,10,10,50,10,ES_NUMBER)
        PROC_dlgctrl(dlg%,"",102,0,0,0,0,&50000096,"msctls_updown32")
 
        PROC_showdialog(dlg%)
        PROCsetdelta(!dlg%, 102, 5)
        SYS "SendDlgItemMessage", !dlg%, 102, UDM_SETRANGE, 0, (0 << 16) + 100
        SYS "SetDlgItemText", !dlg%, 101, "41"
 
        ON ERROR  PROC_closedialog(dlg%):PRINT REPORT$:END
        ON CLOSE  PROC_closedialog(dlg%):QUIT
 
        REPEAT
          WAIT 1
        UNTIL FALSE
        PROC_closedialog(dlg%)
        END
 
        DEF PROCsetdelta(hdlg%, udid%, delta%)
        LOCAL D%,M%,O%,P%
        PRIVATE C%,L% : IF C%=0 DIM C% 100, L% -1
        P% = C%
        SYS "GetWindowLong", hdlg%, -4 TO O%
        [OPT 10
        .D% pop eax : push O% : push eax : jmp "CallWindowProc"
        .M% cmp dword [esp+8],WM_NOTIFY : jnz D%
        mov edx,[esp+16] : cmp dword [edx+4],udid% : jnz D%
        cmp dword [edx+8],UDN_DELTAPOS : jnz D%
        mov eax,[edx+12] : mov ecx,delta% : xor edx,edx : idiv ecx : mov ecx,edx
        mov edx,[esp+16] : imul ecx,[edx+16]
        bt ecx,31 : adc eax,[edx+16] : imul eax,delta%
        sub eax,[edx+12] : mov [edx+16],eax
        xor eax,eax : ret 16
        ]
        SYS "SetWindowLong", hdlg%, -4, M%
        ENDPROC
This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information
changing_20the_20step_20size_20of_20an_20up-down_20control.txt · Last modified: 2018/04/17 14:55 by tbest3112