Jump to content

GUICtrlCreateList scrolled to bottom by default


Recommended Posts

I have a list (GUICtrlCreateList) tall enough to display 7 items. A scrollbar appears when the list had more than 7 items, which is the desired behavior. However, if the list is showing the last 7 items, not the first 7. In other words, the scrollbar is scrolled to the end by default instead of the top of the list. Is there any way to change this behavior?

Here's what I have:

Local $List_Queue = GUICtrlCreateList("", 2, 60, 400, 100, BitOR($LBS_MULTIPLESEL,$WS_HSCROLL,$WS_VSCROLL,$WS_BORDER))
GUICtrlSetLimit(-1, 200) ; to limit horizontal scrolling
Gerard J. Pinzonegpinzone AT yahoo.com
Link to comment
Share on other sites

  • Moderators

GPinzone,

When I create a list it is the top 7 items that are displayed:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#include <ListBoxConstants.au3>

$hGUI = GUICreate("Test", 500, 500)

Local $cList = GUICtrlCreateList("", 2, 60, 400, 100, BitOR($LBS_MULTIPLESEL,$WS_HSCROLL,$WS_VSCROLL,$WS_BORDER))
GUICtrlSetLimit(-1, 200) ; to limit horizontal scrolling

GUISetState()

For $i = 1 To 20
    GUICtrlSetData($cList, "Item " & $i)
    Sleep(100)
Next

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
Can you post a reproducer that results in you keeping the bottom 7 in view? :waco:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

I Think I know what's causing the issue for me now that I look at your code. I'm also using _GUICtrlListBox_SetSel to pre select the items as I add them to the list. I modified your example to include _GUICtrlListBox_SetSel and it exhibits the same behavior. 

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#include <ListBoxConstants.au3>
#include <GuiListBox.au3>

$hGUI = GUICreate("Test", 500, 500)

Local $cList = GUICtrlCreateList("", 2, 60, 400, 100, BitOR($LBS_MULTIPLESEL, $WS_HSCROLL, $WS_VSCROLL, $WS_BORDER))
GUICtrlSetLimit(-1, 200) ; to limit horizontal scrolling GUISetState()

For $i = 1 To 20
    GUICtrlSetData($cList, "Item " & $i)
    _GUICtrlListBox_SetSel($cList, $i-1)
Next

GUISetState(@SW_SHOW)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

I suppose a "solution" would be to do the loop twice something like:

For $i = 1 To 20
    GUICtrlSetData($cList, "Item " & $i)
Next

For $i = 20 To 1 Step -1
    _GUICtrlListBox_SetSel($cList, $i-1)
Next

to do the _GUICtrlListBox_SetSel stuff in reverse order, but that's not very elegant.

Gerard J. Pinzonegpinzone AT yahoo.com
Link to comment
Share on other sites

  • Moderators

GPinzone,

Then I suggest you tell the listbox to scroll to the top once you have filled it: ;)

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#include <ListBoxConstants.au3>
#include <GuiListBox.au3>

$hGUI = GUICreate("Test", 500, 500)

Local $cList = GUICtrlCreateList("", 2, 60, 400, 100, BitOR($LBS_MULTIPLESEL, $WS_HSCROLL, $WS_VSCROLL, $WS_BORDER))
GUICtrlSetLimit(-1, 200) ; to limit horizontal scrolling GUISetState()

For $i = 1 To 20
    GUICtrlSetData($cList, "Item " & $i)
    _GUICtrlListBox_SetSel($cList, $i-1)
Next

GUICtrlSendMsg($cList, $LB_SETTOPINDEX, 0, 0) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

GUISetState(@SW_SHOW)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
That seems to work. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

GPinzone,

Glad I could help. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Why are you selecting each one as you add it?

I would (and do) just select the one I want, after the List has been fully populated, which is usually the first entry, by using

_GUICtrlListBox_SetSel($cList, 0)

which is outside the Loop, like Melba23's alternative method.

P.S. That will scroll it into view if it's not.

Edited by TheSaint

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

Knight:

   It's a CD/DVD duplicator queue, and I want all of the items on the list to be processed by default. That's why I want them all to be selected by default. If any of the discs are to be omitted, the person would click on the corresponding entry, which would toggle it off.

EDIT: After digging into _GUICtrlListBox_SetSel, I could have just used:

GUICtrlSendMsg(-1, $LB_SETSEL, True, $i)

instead of _GUICtrlListBox_SetSel. I still have to re-adjust the list position.
 

Edited by GPinzone
Gerard J. Pinzonegpinzone AT yahoo.com
Link to comment
Share on other sites

BTW, Take a look at the _GUICtrlListBox_SetSel function:

Func _GUICtrlListBox_SetSel($hWnd, $iIndex = -1, $fSelect = -1)
    If $Debug_LB Then __UDF_ValidateClassName($hWnd, $__LISTBOXCONSTANT_ClassNames)
    Local $i_ret = True
    If IsHWnd($hWnd) Then
        If $iIndex == -1 Then ; toggle all
            For $iIndex = 0 To _GUICtrlListBox_GetCount($hWnd) - 1
                $i_ret = _GUICtrlListBox_GetSel($hWnd, $iIndex)
                If ($i_ret == $LB_ERR) Then Return SetError($LB_ERR, $LB_ERR, False)
                If ($i_ret > 0) Then ;If Selected Then
                    $i_ret = _SendMessage($hWnd, $LB_SETSEL, False, $iIndex) <> -1
                Else
                    $i_ret = _SendMessage($hWnd, $LB_SETSEL, True, $iIndex) <> -1
                EndIf
                If ($i_ret == False) Then Return SetError($LB_ERR, $LB_ERR, False)
            Next
        ElseIf $fSelect == -1 Then ; toggle state of index
            If _GUICtrlListBox_GetSel($hWnd, $iIndex) Then ;If Selected Then
                Return _SendMessage($hWnd, $LB_SETSEL, False, $iIndex) <> -1
            Else
                Return _SendMessage($hWnd, $LB_SETSEL, True, $iIndex) <> -1
            EndIf
        Else ; set state according to flag
            Return _SendMessage($hWnd, $LB_SETSEL, $fSelect, $iIndex) <> -1
        EndIf
    Else
        If $iIndex == -1 Then ; toggle all
            For $iIndex = 0 To _GUICtrlListBox_GetCount($hWnd) - 1
                $i_ret = _GUICtrlListBox_GetSel($hWnd, $iIndex)
                If ($i_ret == $LB_ERR) Then Return SetError($LB_ERR, $LB_ERR, False)
                If ($i_ret > 0) Then ;If Selected Then
                    $i_ret = GUICtrlSendMsg($hWnd, $LB_SETSEL, False, $iIndex) <> -1
                Else
                    $i_ret = GUICtrlSendMsg($hWnd, $LB_SETSEL, True, $iIndex) <> -1
                EndIf
                If ($i_ret == False) Then Return SetError($LB_ERR, $LB_ERR, False)
            Next
        ElseIf $fSelect == -1 Then ; toggle state of index
            If _GUICtrlListBox_GetSel($hWnd, $iIndex) Then ;If Selected Then
                Return GUICtrlSendMsg($hWnd, $LB_SETSEL, False, $iIndex) <> -1
            Else
                Return GUICtrlSendMsg($hWnd, $LB_SETSEL, True, $iIndex) <> -1
            EndIf
        Else ; set state according to flag
            Return GUICtrlSendMsg($hWnd, $LB_SETSEL, $fSelect, $iIndex) <> -1
        EndIf
    EndIf
    Return $i_ret
EndFunc ;==>_GUICtrlListBox_SetSel

If the function is called without an index value (or given -1 as the index), it toggles all the entries and leaves the list at the bottom. Perhaps the loop counter should go from _GUICtrlListBox_GetCount($hWnd) - 1 to 0 instead? Or maybe the existing position is temporarily saved at the beginning of the function and then reset after it's run?

EDIT: Is it possible to use_GUIScrollBars_GetScrollPos to get the position on a list? I tried it just for fun, but it always returns -1.

Edited by GPinzone
Gerard J. Pinzonegpinzone AT yahoo.com
Link to comment
Share on other sites

Sorry, hadn't picked up on the Multiple selection angle.

By memory, another possible alternative way, and using Melba23's final scroll method, would be to do a count after the list is fully populated, and then a range selection.

Overall, I'd recommend following what Melba23 provided, I only interjected out of curiosity and to provide what I thought might be an alternative.

 

Not sure what you mean by getting position on list?

If you are just after a single selected item, then just get the selected Index for that.

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

Let's assume the listbox contains 100 items and the user has scrolled down some arbitrary distance from the top. The _GUICtrlListBox_SetSel command is issued to toggle one or more entries in the list, but this forces the list to scroll to the entry in being modified. If we want to preserve the scrollbar locations prior to executing _GUICtrlListBox_SetSel, how would we do that? I suggested using _GUIScrollBars_GetScrollPos to get the position before executing _GUICtrlListBox_SetSel, store it in a variable, execute _GUICtrlListBox_SetSel, then restore the scrolbar position after it's done. However, I'm not sure it possible to get or set a listbox's scrollbar position.

The second question would be whether or not the _GUICtrlListBox_SetSel function should be modified assuming preservation of scrollbar positions is possible.

Gerard J. Pinzonegpinzone AT yahoo.com
Link to comment
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
 Share

×
×
  • Create New...