Scrollbare GUI

  • Hallo zusammen,
    ich beschäftige mich gerade mit der Möglichkeit eine scrollbare GUI zu erstellen. Das klappt eigentlich auch schon ganz gut.

    Jedoch habe ich bis jetzt zwei Probleme...:
    1. Es lässt sich nur auf einer Länge von etwas 32780px etwas (z.B. Labels) erstellen
    2. Bei Maximierung/Verkleinerung des Fensters wird der Inhalt neu geladen, die Scrollbars bleiben aber auf ihrer vorigen Position

    ...und ein Ziel, das ich erreichen möchte, aber nicht weiß wie:
    3. Möglichkeit die Scrollbar mit dem Mausrad zu bewegen
    4. Möglichkeit die Scrollbar mit den Bildtasten zu bewegen

    Hier einmal ein Beispiel, wie weit ich es bis jetzt geschafft habe. Zum Test werden hier einfach eine variable Anzahl von Labels erstellt.
    AutoIt Beta verwenden!

    Spoiler anzeigen
    [autoit]


    ;Scrollable_Gui
    ;AutoIt Beta 3.2.11.10
    ;==============================
    ;Zum Test der scrollbaren GUI werden Labels erzeugt, deren Anzahl zuvor bestimmt werden kann
    ;
    ;Probleme: (Die mir bis jetzt aufgefallen sind)
    ;Offenbar begrenzte Länge der GUI, wo auch etwas (z.B. ein Label) angezeigt wird. Nämlich ca. 32780px
    ;Bei Maximierung/Verkleinerung des Fensters wird der Inhalt neu geladen, die Scrollbars bleiben aber auf
    ;ihrer vorigen Position
    ;==============================

    [/autoit] [autoit][/autoit] [autoit]

    #include <GuiConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <GuiScrollBars.au3>
    #include <ScrollBarConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $lab[5000]
    $var = 0
    ;(20 + ($var * 50)) => label top

    [/autoit] [autoit][/autoit] [autoit]

    $lab_number = InputBox("","Anzahl der Testlabels angeben", 200)
    If @error = 1 Then Exit

    [/autoit] [autoit][/autoit] [autoit]

    $gui = GUICreate("Scrollable Gui", 800, 600, -1, -1, $WS_CAPTION + $WS_SYSMENU + $WS_MINIMIZEBOX + $WS_MAXIMIZEBOX)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $lab_number;Erstellung des GUI Inhalts in Form von Labels
    If (20 + ($var * 50)) > 32780 Then;Die Labels werden nur auf einer Länge von ca.32780px erstellt
    MsgBox(0,"", "Zu lang");... vielleicht mache ich aber auch etwas falsch
    ExitLoop
    EndIf
    $lab[$i] = GUICtrlCreateLabel("=====" & $i & "=====", 200, (20 + ($var * 50)), 400, 25)
    GUICtrlSetResizing($lab[$i], $GUI_DOCKSIZE + $GUI_DOCKLEFT + $GUI_DOCKTOP)
    $var += 1
    Next

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_SIZE, "WM_SIZE");Benutzerdefinierte Windows Message ($WM_...)werden registriert
    GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL")
    GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL")

    [/autoit] [autoit][/autoit] [autoit]

    $scroll = (20 + ($var * 50)) / 16
    _GUIScrollBars_Init($gui, 0, $scroll);Scrollbars werden im Fenster $gui initialisiert|
    ;Länge horizontal = 0 |Länge vertikal = (20 + ($var * 50)) / 16 => Abhängig von der Anzahl der Labels
    _GUIScrollBars_ShowScrollBar($gui, $SB_HORZ, False);Horizontale Scrollbar wird deaktiviert

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()
    While 1
    $msg = GUIGetMsg()
    Select
    Case $msg = $GUI_EVENT_CLOSE
    ExitLoop
    EndSelect
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    #Region###Benutzerdefinierte Windows Message ($WM_...)
    Func WM_SIZE($hWnd, $Msg, $wParam, $lParam)
    #forceref $Msg, $wParam
    Local $index = -1, $yChar, $xChar, $xClientMax, $xClient, $yClient, $ivMax
    For $x = 0 To UBound($aSB_WindowInfo) - 1
    If $aSB_WindowInfo[$x][0] = $hWnd Then
    $index = $x
    $xClientMax = $aSB_WindowInfo[$index][1]
    $xChar = $aSB_WindowInfo[$index][2]
    $yChar = $aSB_WindowInfo[$index][3]
    $ivMax = $aSB_WindowInfo[$index][7]
    ExitLoop
    EndIf
    Next
    If $index = -1 Then Return 0

    [/autoit] [autoit][/autoit] [autoit]

    Local $tSCROLLINFO = DllStructCreate($tagSCROLLINFO)

    [/autoit] [autoit][/autoit] [autoit]

    ; Retrieve the dimensions of the client area.
    $xClient = BitAND($lParam, 0x0000FFFF)
    $yClient = BitShift($lParam, 16)
    $aSB_WindowInfo[$index][4] = $xClient
    $aSB_WindowInfo[$index][5] = $yClient

    [/autoit] [autoit][/autoit] [autoit]

    ; Set the vertical scrolling range and page size
    DllStructSetData($tSCROLLINFO, "fMask", BitOR($SIF_RANGE, $SIF_PAGE,$SIF_POS))
    DllStructSetData($tSCROLLINFO, "nMin", 0)
    DllStructSetData($tSCROLLINFO, "nMax", $ivMax)
    DllStructSetData($tSCROLLINFO, "nPage", $yClient / $yChar)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)

    [/autoit] [autoit][/autoit] [autoit]

    ; Set the horizontal scrolling range and page size
    DllStructSetData($tSCROLLINFO, "fMask", BitOR($SIF_RANGE, $SIF_PAGE,$SIF_POS))
    DllStructSetData($tSCROLLINFO, "nMin", 0)
    DllStructSetData($tSCROLLINFO, "nMax", 2 + $xClientMax / $xChar)
    DllStructSetData($tSCROLLINFO, "nPage", $xClient / $xChar)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)

    [/autoit] [autoit][/autoit] [autoit]

    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_SIZE

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_HSCROLL($hWnd, $Msg, $wParam, $lParam)
    #forceref $Msg, $lParam
    Local $nScrollCode = BitAND($wParam, 0x0000FFFF)

    [/autoit] [autoit][/autoit] [autoit]

    Local $index = -1, $xChar, $xPos
    Local $Min, $Max, $Page, $Pos, $TrackPos

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    ;~ ; Get all the horizontal scroll bar information
    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
    $Min = DllStructGetData($tSCROLLINFO, "nMin")
    $Max = DllStructGetData($tSCROLLINFO, "nMax")
    $Page = DllStructGetData($tSCROLLINFO, "nPage")
    ; Save the position for comparison later on
    $xPos = DllStructGetData($tSCROLLINFO, "nPos")
    $Pos = $xPos
    $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")
    #forceref $Min, $Max
    Switch $nScrollCode

    [/autoit] [autoit][/autoit] [autoit]

    Case $SB_LINELEFT ; user clicked left arrow
    DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1)

    [/autoit] [autoit][/autoit] [autoit]

    Case $SB_LINERIGHT ; user clicked right arrow
    DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1)

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
    ;// If the position has changed, scroll the window and update it
    $Pos = DllStructGetData($tSCROLLINFO, "nPos")
    If ($Pos <> $xPos) Then _GUIScrollBars_ScrollWindow($hWnd, $xChar * ($xPos - $Pos), 0)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_HSCROLL

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; 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")

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    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")

    [/autoit] [autoit][/autoit] [autoit]

    If ($Pos <> $yPos) Then
    _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos))
    $yPos = $Pos
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Return $GUI_RUNDEFMSG

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>WM_VSCROLL
    #EndRegion###Benutzerdefinierte Windows Message ($WM_...)

    [/autoit]

    Einmal editiert, zuletzt von fraengers (29. April 2008 um 21:55)

  • Mausrad geht bei mir.
    Um die Scrollbarposition zurückzusetzen Zeile 79 und 86 je ändern in

    [autoit]

    DllStructSetData($tSCROLLINFO, "fMask", BitOR($SIF_RANGE, $SIF_PAGE,$SIF_POS))

    [/autoit]
  • Prima Danke, das löst immerhin schon mal ein Problem.
    Nur bei mir lässt sich da nichts mit dem Mausrad scrollen.
    Kann man die Mausradbewegung irgendwie abfragen und demnach den Bereich scrollen?!