Sign in to follow this  
Followers 0
OjO

Changing UpDown Acceleration

5 posts in this topic

Hi there, been trying to change the acceleration of increasing/decreasing an updown control. (speed increases if you hold it down for nSec seconds) I'm pretty new to using gui features only have just begun to figure out how to send messages to controls.

Here is some info I found on the acceleration message from MSDN website:

UDM_SETACCEL Message

--------------------------------------------------------------------------------

Sets the acceleration for an up-down control.

Syntax

To send this message, call the SendMessage function as follows.

lResult = SendMessage( // returns LRESULT in lResult

(HWND) hWndControl, // handle to destination control

(UINT) UDM_SETACCEL, // message ID

(WPARAM) wParam, // = (WPARAM) (int) nAccels;

(LPARAM) lParam // = (LPARAM) (LPUDACCEL) aAccels;

);

Parameters

nAccels

Number of UDACCEL structures specified by aAccels.

aAccels

Pointer to an array of UDACCEL structures that contain acceleration information. Elements should be sorted in ascending order based on the nSec member.

Return Value

Returns TRUE if successful, or FALSE otherwise.

-----------------------------------------

The UDACCEL stucture is as follows:

Syntax

typedef struct {

UINT nSec;

UINT nInc;

} UDACCEL, *LPUDACCEL;

Members

nSec

Amount of elapsed time, in seconds, before the position change increment specified by nInc is used.

nInc

Position change increment to use after the time specified by nSec elapses

Here is my code so far, but it isn't setting the acceleration properly. Can anyone help me out?

#include <GUIConstants.au3>

$gui = guicreate("testing", 500, 300, 100, 200 )

$updownbox = GUICtrlCreateinput ( 9000, 20, 150, 60, -1, $ES_READONLY )

$updownctrl = GUICtrlCreateUpdown ( $updownbox )

GUISetState()

$UDM_SETACCEL = $WM_USER+107

$UDM_GETACCEL = $WM_USER+108

$str = "uint;uint"

$a = DllStructCreate($str)

GUICtrlSendMsg($updownctrl, $UDM_GETACCEL, 1, DllStructGetPtr($a))

DllStructSetData ( $a, 1, 100 )

GUICtrlSendMsg($updownctrl, $UDM_SETACCEL, 1, DllStructGetPtr($a))

while 1

$msg = GUIgetmsg()

select

case $msg = $GUI_EVENT_CLOSE

exitloop

endselect

wend

I noticed it is supposed to be an array of structures as specified in the UDACCEL documentation, but I don't know how to do that.

I know there are other people who wanted this feature, so maybe someone who has more experience working with sending messages to controls could help.

Thanks for any help

Chris

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I noticed it is supposed to be an array of structures as specified in the UDACCEL documentation, but I don't know how to do that.

I know there are other people who wanted this feature, so maybe someone who has more experience working with sending messages to controls could help.

Well at least you succeeded in sending acceleration speed with 1 structure (since your code makes the updown scroll with speed always 1 instead of the default windows acceleration). The key must be this structure array because they contain the different acceleration 'stages'.

Well sorry to not be of any help, but that's about as far as I got too when I tried the same thing some weeks ago :whistle:

I played around with DllStructGetPtr() and tried this:

Dim $strucArray[10]
For $x = 1 To 10
    $strucArray[$x-1] = DllStructCreate($str)  ; <-- edit: had [$x] instead of [$x-1], shame on me :)
    DllStructSetData ($strucArray[$x-1], 1*$x, 100*$x)
Next
GUICtrlSendMsg($updownctrl,$UDM_SETACCEL,1, DllStructGetPtr($strucArray))

... but this crashes hardcore. But we need to feed it a pointer to an array of structures. I'm guessing that an autoIt array is something else than a dll structure array so we can't directly get the pointer to it in a form that the dll call understands?

I really wonder if anyone can help with this (PaulIA is a name that comes to mind?), I was looking for this too but I'm not yet all that much into dll structure programming stuff. I'm still learning that, hopefully I will in this thread... :P

Edited by SadBunny

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Success!!!!

After about 3 hours of messing around, I found a solution to my problem. I've made a _GUICtrlUpdownSetAccel function for everyone to use - maybe it will be in the next beta? Any help to clean up the code would be appreciated, I tried to model it like the other _GUICtrl.... functions in the include folder.

;example script using _GUICtrlUpdownSetAccel()
#include <GUIConstants.au3>
$gui = GUICreate ( "Updown Accel Increment Changer", 200, 100 )
$button = GUICtrlCreateButton ( "Change Accels", 50, 30, 100, 20 )
$updownbox = GUICtrlCreateInput ( "9000", 50, 60, 60, -1, $ES_READONLY )
$updownctrl = GUICtrlCreateUpdown ( $updownbox )
GUISetState()

While 1
    $msg = GUIGetMsg()
    Select
    Case $msg = $GUI_EVENT_CLOSE
        ExitLoop
    Case $msg = $button
        $nSec1 = InputBox ( "test", "Enter nSec List", "0|2|5" )
        $nInc1 = InputBox ( "test", "Enter nInc List", "1|5|20" )
        _GUICtrlUpdownSetAccel ( $updownctrl, $nSec1, $nInc1 )
        If @error Then MsgBox ( 1, "Error", @error )
    EndSelect
WEnd


;===============================================================================
;
; Description:      _GUICtrlUpdownSetAccel
; Parameter(s):     $h_updown - updown controlID
;                   $nSecList - "|" delimited list of nSec times (Default "0|2|5" )
;                   $nIncList - "|" delimited list of nInc increment (Default "1|5|20" )
;                               after 0 seconds, updown increments by 1
;                               after 1 second, updown increments by 5
;                               after 5 seconds, updown increments by 20
; Requirement:      <GUIConstants.au3>
; Return Value(s):  Returns nonzero if successful, or zero otherwise.
;                           If an error occurs, the return value is $LV_ERR (-1) and @error is set to -1
; User CallTip:     _GUICtrlUpdownSetAccel ( $h_updown ) resets to default values in example above
;                   _GUICtrlUpdownSetAccel ( $h_updown, "0", "10" ) makes the updown increment by 10 with no acceleration
;                  _GUICtrlUpdownSetAccel ( $h_updown, "0|2", "1|10" ) makes the updown increment by 1. After 2 seconds, it increments by 10
; Author(s):        Chris Howes (OjO)
; Note(s):          $nSecList and $nIncList must have the same number of delimited values
;                   $nSecList must be in increasing order ex: "0|7|8"  - using "0|8|7" would fail and return -1
;                   string values in $nSecList and $nIncList must have integer value of 0 or greater
;
;===============================================================================
Func _GUICtrlUpdownSetAccel ( $h_updown = 0, $nSecList = "0|2|5", $nIncList = "1|5|20" ); 0|2|5 and 1|5|20 are default windows settings
    Const $UDM_SETACCEL = $WM_USER+107
    Local $nSecErr = 0
    Local $nSec = StringSplit ( $nSecList, "|" )
    Local $nInc = StringSplit ( $nIncList, "|" )
    Local $x = 0
    
    If $nSec[0] <> $nInc[0] Then Return SetError($CB_ERR,$CB_ERR,$CB_ERR);check for same # of nSec & nInc sets
    For $x = 1 to $nSec[0];check for non integers, and negative numbers, and zero length entries
        If StringIsInt ($nSec[$x]) = 0 Or Int ( $nSec[$x]) < 0 Or StringLen ( $nSec[$x] ) = 0 Then Return SetError($CB_ERR,$CB_ERR,$CB_ERR)
        If StringIsInt ($nInc[$x]) = 0 Or Int ( $nInc[$x]) < 0 Or StringLen ( $nInc[$x] ) = 0 Then Return SetError($CB_ERR,$CB_ERR,$CB_ERR)
    Next
    If $nsec[0] > 1 Then
        For $x = 2 To $nSec[0]
            If $nSec[$x] <= $nSec[$x-1] Then $nSecErr = 1;check for ascending order of nSec sequence
        Next
        If $nSecErr = 1 Then Return SetError($CB_ERR,$CB_ERR,$CB_ERR)
    EndIf
        
    Local $str = "uint;uint";create initial structure for set of nSec;nInc
    if $nsec[0] > 1 Then ;add more structure for additional entries
        For $x = 2 To $nSec[0]
            $str = $str & ";uint;uint"
        Next
    EndIf
    Local $AccelStruct = DllStructCreate ( $str )
    
    For $x = 1 To $nSec[0];Put Data in the structure
        DllStructSetData ( $AccelStruct, ($x * 2) - 1, Number ($nSec[$x]) )
        DllStructSetData ( $AccelStruct, ($x * 2), Number ($nInc[$x]) )
    Next
    
    If IsHWnd($h_updown) Then
        Local $a_ret = DllCall("user32.dll", "int", "SendMessage", "hwnd", $h_updown, "int", $UDM_SETACCEL, "int", $nSec[0], "ptr", DllStructGetPtr($AccelStruct))
        Return $a_ret[0]
    Else
        GUICtrlSendMsg($h_updown, $UDM_SETACCEL, $nSec[0], DllStructGetPtr ( $AccelStruct ))
    EndIf
EndFunc

Hope this helps others who were trying to change the default updown increment settings. This was really fun, I think I'll try to find more solutions to other ppl's problems now! :whistle:

Cheers,

OjO

Edited by OjO

Share this post


Link to post
Share on other sites

Success!!!!

Cool! Thanks for the update, I'll try to understand it in more depth after work hours :whistle:

Nice job.


Roses are FF0000, violets are 0000FF... All my base are belong to you.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0