Jump to content

Recommended Posts

Posted

I check this snippet:

https://www.autoitscript.com/wiki/Snippets_(_GUI_)#GUI_With_Scrollable_TabItem

Modified them and I refactored. That's because I needed to adapt it to my needs (I'll write later).
I thought I understood how it works.
But I was wrong.

 

This is my example which is showing what I want to achieve.

#include <AutoItConstants.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiScrollBars.au3>
#include <GUIScrollbars_Ex.au3>
#include <StringConstants.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>

GUIRegisterMsg($WM_VSCROLL, WM_VSCROLL)

_Example()

Func _Example()
    Local $i_Count = 30
    Local $a_Options_List[$i_Count + 1]
    $a_Options_List[0] = $i_Count
    For $i = 1 To $i_Count
        $a_Options_List[$i] = 'Test #' & $i
    Next
    ConsoleWrite("- " & _my_gui_Wybierz('Testing', $a_Options_List) & @CRLF)
EndFunc   ;==>_Example

Func _my_gui_Wybierz($s_Description, $a_Options_List = "", $i_Left = Default, $i_Top = Default, $i_Width = Default, $hWnd_Parent = 0)
;~  WinSetOnTop($ACROBAT_TITLE, "", $WINDOWS_NOONTOP )
    If $i_Left = Default Then $i_Left = -1
    If $i_Top = Default Then $i_Top = -1
    If $i_Width = Default Then $i_Width = 400

    #Region _my_gui_Wybierz - GUI Creation
    Local $i_Height = 600
    Local $hWND_DateForm = GUICreate("", $i_Width, $i_Height, $i_Left, $i_Top, BitOR(0, $WS_SIZEBOX), -1, $hWnd_Parent)
    WinSetOnTop($hWND_DateForm, "", $WINDOWS_ONTOP)

    Local $hChild = GUICreate("Scroll area", $i_Width - 15, $i_Height - 40, 0, 0, $WS_POPUP, $WS_EX_MDICHILD, $hWND_DateForm)
    _GUIScrollBars_Init($hChild, -1)
    _GUIScrollBars_ShowScrollBar($hChild, $SB_HORZ, False)
    _GUIScrollBars_ShowScrollBar($hChild, $SB_VERT, True)
;~  _GUIScrollBars_SetScrollRange($hChild, $SB_VERT, 3, 30)
    GUICtrlCreateLabel("", 10, 7, $i_Width - 45, 80)
    Local $id_Label1 = GUICtrlCreateLabel("", 10, 7 + 5, $i_Width - 45, 80 - 5)
    GUICtrlSetBkColor(-1, 0x88AABB)

    Local $a_List_of_Button_ID[$a_Options_List[0] + 1]
    For $IDX_Item = 1 To $a_Options_List[0]
        If $IDX_Item > 0 And $IDX_Item < 10 Then
            $a_List_of_Button_ID[$IDX_Item] = GUICtrlCreateButton( _
                    $IDX_Item & ". " & $a_Options_List[$IDX_Item], _
                    10, 90 + ($IDX_Item - 1) * 21, $i_Width - 45, 20, BitOR($BS_LEFT, $WS_GROUP))
        Else
            $a_List_of_Button_ID[$IDX_Item] = GUICtrlCreateButton( _
                    Chr(Asc('A') + $IDX_Item - 10) & ". " & $a_Options_List[$IDX_Item], _
                    10, 90 + ($IDX_Item - 1) * 21, $i_Width - 45, 20, BitOR($BS_LEFT, $WS_GROUP))
        EndIf
    Next

    Local $temp_var = $a_Options_List[0]
    Local $a_accelerators[($temp_var * 2) + 1][2]

    Local $i_Accelerators_Counter = 0
    Local $i_Accelerator_Char1 = ''
    Local $i_Accelerator_Char2 = ''
    For $IDX_Item = 1 To $a_Options_List[0]
        If $IDX_Item > 9 Then
            $i_Accelerator_Char1 = Chr(Asc('A') + $IDX_Item - 10)
            $i_Accelerator_Char2 = Chr(Asc('a') + $IDX_Item - 10)
        Else
            $i_Accelerator_Char1 = "{NUMPAD" & $IDX_Item & "}"         ;Chr(48 + $IDX_Item)
            $i_Accelerator_Char2 = $IDX_Item
        EndIf
        $a_accelerators[($IDX_Item * 2) - 1][0] = $i_Accelerator_Char1
        $a_accelerators[($IDX_Item * 2) - 1][1] = $a_List_of_Button_ID[$IDX_Item]

        $a_accelerators[($IDX_Item * 2) - 1 + 1][0] = $i_Accelerator_Char2
        $a_accelerators[($IDX_Item * 2) - 1 + 1][1] = $a_List_of_Button_ID[$IDX_Item]

        $i_Accelerators_Counter += 2
    Next
    $a_accelerators[0][0] = $i_Accelerators_Counter
    GUISetAccelerators($a_accelerators, $hChild)
    GUICtrlSetData($id_Label1, $s_Description)

    GUISetState(@SW_SHOW, $hWND_DateForm)
    GUISetState(@SW_SHOW, $hChild)
    #EndRegion _my_gui_Wybierz - GUI Creation

    #Region - _my_gui_Wybierz - Handling messages
    Local $i_Selected_item = 0
    Local $v_Return_Value = ""
    Local $a_GUI_Messages
    While 1
        $a_GUI_Messages = GUIGetMsg($GUI_EVENT_ARRAY)
        If $a_GUI_Messages[0] = $GUI_EVENT_NONE Then
            ; do nothing
        ElseIf $a_GUI_Messages[1] = $hWND_DateForm Then
            If $a_GUI_Messages[0] = $GUI_EVENT_CLOSE Then ExitLoop
        ElseIf $a_GUI_Messages[1] <> $hChild Then
            ; ....
        Else
            For $IDX_Check = 1 To $a_Options_List[0]
                If $a_List_of_Button_ID[$IDX_Check] = $a_GUI_Messages[0] Then
                    $v_Return_Value = GUICtrlRead($a_List_of_Button_ID[$IDX_Check])
                    $i_Selected_item = $IDX_Check
                    $v_Return_Value = _RegExpFirstMatch($v_Return_Value, '.+?\. (.+)')
                    ExitLoop 2         ; exit from ForNext and also from WhileWend
                EndIf
            Next
        EndIf
    WEnd
    #EndRegion - _my_gui_Wybierz - Handling messages

    GUIDelete($hChild)
    GUIDelete($hWND_DateForm)

    Return SetError(0, $i_Selected_item, $v_Return_Value)

EndFunc   ;==>_my_gui_Wybierz

Func WM_VSCROLL($hWnd, $msg, $wParam, $lParam)
    #forceref $msg, $wParam, $lParam
    Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
    Local $index = -1, $yChar, $yPos
    Local $Min, $Max, $Page, $Pos, $TrackPos

    For $x = 0 To UBound($aSB_WindowInfo) - 1
        If $aSB_WindowInfo[$x][0] = $hWnd Then
            $index = $x
            $yChar = $aSB_WindowInfo[$index][3]
            ExitLoop
        EndIf
    Next
    If $index = -1 Then Return 0

    ; Get all the vertial scroll bar information
    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    $Min = DllStructGetData($tSCROLLINFO, "nMin")
    $Max = DllStructGetData($tSCROLLINFO, "nMax")
    $Page = DllStructGetData($tSCROLLINFO, "nPage")
    ; Save the position for comparison later on
    $yPos = DllStructGetData($tSCROLLINFO, "nPos")
    $Pos = $yPos
    $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")

    Switch $nScrollCode
        Case $SB_TOP ; user clicked the HOME keyboard key
            DllStructSetData($tSCROLLINFO, "nPos", $Min)

        Case $SB_BOTTOM ; user clicked the END keyboard key
            DllStructSetData($tSCROLLINFO, "nPos", $Max)

        Case $SB_LINEUP ; user clicked the top arrow
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1)

        Case $SB_LINEDOWN ; user clicked the bottom arrow
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1)

        Case $SB_PAGEUP ; user clicked the scroll bar shaft above the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page)

        Case $SB_PAGEDOWN ; user clicked the scroll bar shaft below the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page)

        Case $SB_THUMBTRACK ; user dragged the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $TrackPos)
    EndSwitch

    ; Set the position and then retrieve it.  Due to adjustments
    ; by Windows it may not be the same as the value set.

    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    ; If the position has changed, scroll the window and update it
    $Pos = DllStructGetData($tSCROLLINFO, "nPos")
    If ($Pos <> $yPos) Then
        _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos))
        $yPos = $Pos
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_VSCROLL

Func _RegExpFirstMatch($s_Data, $s_Pattern)
    Local $a_Results = StringRegExp($s_Data, $s_Pattern, $STR_REGEXPARRAYGLOBALMATCH)
    If @error Then Return SetError(@error, @extended, '')
    Return SetError(0, UBound($a_Results), $a_Results[0])
EndFunc   ;==>_RegExpFirstMatch

 

I have few problems with this code, and many question related to them.

Question 1:
How to make the Scrollbars to work ?
I mean to scroll buttons.

Question 2:
Do I must to ues Child Window, or is it possible to scroll buttons without using Child Window ?

Question 3:
Why after uncommenting this following line:

;~  _GUIScrollBars_SetScrollRange($hChild, $SB_VERT, 3, 30)

the ScrollBar disapears ?

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

Posted

Ha...
I was able to solve my problems with @Melba23  UDF:


Here is finall script:

#include <AutoItConstants.au3>
#include <Array.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiScrollBars.au3>
#include <StringConstants.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>
#include "GUIScrollbars_Ex.au3"


_Example()

Func _Example()
    Local $i_Count = 30
    Local $a_Options_List[$i_Count + 1]
    $a_Options_List[0] = $i_Count
    For $i = 1 To $i_Count
        $a_Options_List[$i] = 'Test #' & $i
    Next
    ConsoleWrite("- " & _GUI__Choose_Options('Testing', $a_Options_List) & @CRLF)
EndFunc   ;==>_Example

Func _GUI__Choose_Options($s_Description, $a_Options_List = "", $i_GUI_Left = Default, $i_GUI_Top = Default, $i_GUI_Width = Default, $hWnd_Parent = 0)
    If $i_GUI_Left = Default Then $i_GUI_Left = -1
    If $i_GUI_Top = Default Then $i_GUI_Top = -1
    If $i_GUI_Width = Default Then $i_GUI_Width = 400

    Local $i_Left = 5 ; The distance of the labels from the left edge of the window
    Local $i_Label_Top = 10
    Local $i_Label_Height = 80
    Local $i_Button_Top = 5
    Local $i_Button_Width = $i_GUI_Width - 35
    Local $i_Button_Height = 25
    Local $i_Spacing = 1

    #Region _GUI__Choose_Options - GUI Creation
    Local $i_GUI_Height = 600
    Local $hWND_DateForm = GUICreate("", $i_GUI_Width, $i_GUI_Height, $i_GUI_Left, $i_GUI_Top, -1, -1, $hWnd_Parent)
    WinSetOnTop($hWND_DateForm, "", $WINDOWS_ONTOP)

    GUICtrlCreateLabel("", $i_Left, $i_Label_Top, $i_GUI_Width - 10, $i_Label_Height)
    GUICtrlSetBkColor(-1, 0x88AABB)
    Local $id_Label1 = GUICtrlCreateLabel("", $i_Left + 5, $i_Label_Top + 5, $i_GUI_Width - 15, $i_Label_Height - 5)
    GUICtrlSetBkColor(-1, 0x88AABB)

    Local $i_Child_top = $i_Label_Height + 15
    Local $hChild = GUICreate("Scroll area", $i_GUI_Width - 5, $i_GUI_Height - $i_Label_Height - 30, 0, $i_Child_top, $WS_POPUP, $WS_EX_MDICHILD, $hWND_DateForm)

    Local $i_bottom
    Local $a_List_of_Button_ID[$a_Options_List[0] + 1]
    Local $a_List_of_Dummy_ID = $a_List_of_Button_ID
    For $IDX_Item = 1 To $a_Options_List[0]
        GUISwitch($hWND_DateForm)
        $a_List_of_Dummy_ID[$IDX_Item] = GUICtrlCreateDummy()
        If $IDX_Item > 0 And $IDX_Item < 10 Then
            GUISwitch($hChild)
            $a_List_of_Button_ID[$IDX_Item] = GUICtrlCreateButton( _
                    $IDX_Item & ". " & $a_Options_List[$IDX_Item], _
                    $i_Left, $i_Button_Top, $i_Button_Width, $i_Button_Height, BitOR($BS_LEFT, $WS_GROUP))
        Else
            GUISwitch($hChild)
            $a_List_of_Button_ID[$IDX_Item] = GUICtrlCreateButton( _
                    Chr(Asc('A') + $IDX_Item - 10) & ". " & $a_Options_List[$IDX_Item], _
                    $i_Left, $i_Button_Top, $i_Button_Width, $i_Button_Height, BitOR($BS_LEFT, $WS_GROUP))
        EndIf
        $i_bottom = $i_Button_Top + $i_Button_Height ; Bottom edge of the last Button
        $i_Button_Top = $i_bottom + $i_Spacing ; Top of next Button
    Next

    Local $iMaxScrollHeight = $i_Button_Top
    _GUIScrollbars_Generate($hChild, 0, $iMaxScrollHeight)

    Local $temp_var = $a_Options_List[0]
    Local $a_accelerators_for_Buttons[($temp_var * 2) + 1][2]
    Local $a_accelerators_for_Dummy = $a_accelerators_for_Buttons

    Local $i_Accelerators_Counter = 0
    Local $i_Accelerator_Upper_Char = ''
    Local $i_Accelerator_Lower_Char = ''
    For $IDX_Item = 1 To $a_Options_List[0]
        If $IDX_Item > 9 Then
            $i_Accelerator_Upper_Char = Chr(Asc('A') + $IDX_Item - 10)
            $i_Accelerator_Lower_Char = Chr(Asc('a') + $IDX_Item - 10)
        Else
            $i_Accelerator_Upper_Char = "{NUMPAD" & $IDX_Item & "}"
            $i_Accelerator_Lower_Char = $IDX_Item
        EndIf
        $a_accelerators_for_Buttons[($IDX_Item * 2) - 1][0] = $i_Accelerator_Lower_Char
        $a_accelerators_for_Buttons[($IDX_Item * 2) - 1][1] = $a_List_of_Button_ID[$IDX_Item]
        $a_accelerators_for_Buttons[($IDX_Item * 2)][0] = $i_Accelerator_Upper_Char
        $a_accelerators_for_Buttons[($IDX_Item * 2)][1] = $a_List_of_Button_ID[$IDX_Item]

        $a_accelerators_for_Dummy[($IDX_Item * 2) - 1][0] = $i_Accelerator_Lower_Char
        $a_accelerators_for_Dummy[($IDX_Item * 2) - 1][1] = $a_List_of_Dummy_ID[$IDX_Item]
        $a_accelerators_for_Dummy[($IDX_Item * 2)][0] = $i_Accelerator_Upper_Char
        $a_accelerators_for_Dummy[($IDX_Item * 2)][1] = $a_List_of_Dummy_ID[$IDX_Item]

        $i_Accelerators_Counter += 2
    Next
    $a_accelerators_for_Buttons[0][0] = $i_Accelerators_Counter
    $a_accelerators_for_Dummy[0][0] = $i_Accelerators_Counter
;~  _ArrayDisplay($a_accelerators_for_Buttons, '$a_accelerators_for_Buttons')
;~  _ArrayDisplay($a_accelerators_for_Dummy, '$a_accelerators_for_Dummy')

    ; Accelerators must be set for both Main and Child window because when you drag Main window then Accelerators for Child window will not be fired
    GUISetAccelerators($a_accelerators_for_Buttons, $hChild)
    GUISetAccelerators($a_accelerators_for_Dummy, $hWND_DateForm)
    GUICtrlSetData($id_Label1, $s_Description)

    GUISetState(@SW_SHOW, $hWND_DateForm)
    GUISetState(@SW_SHOW, $hChild)
    #EndRegion _GUI__Choose_Options - GUI Creation

    #Region - _GUI__Choose_Options - Handling messages
    Local $i_Selected_item = 0
    Local $v_Return_Value = ""
    Local $a_GUI_Messages
    While 1
        $a_GUI_Messages = GUIGetMsg($GUI_EVENT_ARRAY)
        If $a_GUI_Messages[0] = $GUI_EVENT_NONE Then
            ; do nothing
        ElseIf $a_GUI_Messages[1] = $hWND_DateForm And $a_GUI_Messages[0] = $GUI_EVENT_CLOSE Then
            ExitLoop
;~      ElseIf $a_GUI_Messages[1] <> $hChild And $a_GUI_Messages[1] <> $hWND_DateForm Then
;~          ; ....
        Else
            For $IDX_Check = 1 To $a_Options_List[0]
                If $a_List_of_Button_ID[$IDX_Check] = $a_GUI_Messages[0] Or $a_List_of_Dummy_ID[$IDX_Check] = $a_GUI_Messages[0] Then
                    $v_Return_Value = GUICtrlRead($a_List_of_Button_ID[$IDX_Check])
                    $i_Selected_item = $IDX_Check
                    $v_Return_Value = _RegExpFirstMatch($v_Return_Value, '.+?\. (.+)')
                    ExitLoop 2         ; exit from ForNext and also from WhileWend
                EndIf
            Next
        EndIf
    WEnd
    #EndRegion - _GUI__Choose_Options - Handling messages

    GUIDelete($hChild)
    GUIDelete($hWND_DateForm)

    Return SetError(0, $i_Selected_item, $v_Return_Value)

EndFunc   ;==>_GUI__Choose_Options

Func _RegExpFirstMatch($s_Data, $s_Pattern)
    Local $a_Results = StringRegExp($s_Data, $s_Pattern, $STR_REGEXPARRAYGLOBALMATCH)
    If @error Then Return SetError(@error, @extended, '')
    Return SetError(0, UBound($a_Results), $a_Results[0])
EndFunc   ;==>_RegExpFirstMatch

 

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

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
×
×
  • Create New...