Scrollbalken auslesen

  • Hallo,

    ich habe folgendes Problem. Ich möchte dass bei meiner kleinen GUI bestimmte Buttons und Checkboxen erst aktiv werden, wenn der Scrollbalken ganz nach unten gescrollt wurde. (Es geht um eine Art Regeln gelesen und verstanden GUI für unseren Schulungsraum im Büro.)

    Nun meine Frage, wie kann ich den Scrollbalken auslesen lassen? Das Aktivieren wäre dann kein Problem mehr.
    Aktuell funktioniert das ganze indem ich die Pixelfarbe am Scrollbalken auslesen lasse. Da es aber verständlicher weise zu problemen kommt, wenn verschiedene Auflösungen genutzt werden, soll nun eine saubere Lösung her.

    Weis jemand rat?


    Vielen dank,
    Marvin

    Einmal editiert, zuletzt von Jasfar (3. Juli 2013 um 10:01)

  • Ob diese Lösung jetzt so sauber ist, weiß ich nicht aber sie funktioniert tadellos:

    Spoiler anzeigen
    [autoit]

    #include <WindowsConstants.au3>
    #include <GuiConstants.au3>
    #include <GuiEdit.au3>
    #include <string.au3>

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

    Opt("GUIOnEventMode", 1)
    Opt("TrayIconHide", 1)

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

    $hGui = GUICreate("Disclaimer", 300, 500, Default, Default, BitOR($WS_CAPTION, $WS_POPUP, $WS_BORDER, $WS_CLIPSIBLINGS))
    ; Schliessen ist jetzt nur durch Klick auf den Button möglich, der nur erscheint, wenn der Text bis ans Ende gescrollt wird.

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

    $idEdit = GUICtrlCreateEdit("", 0, 0, 300, 470, BitOR($GUI_SS_DEFAULT_EDIT, $ES_READONLY)) ;Edit Control besteht aus 34 Zeilen
    $idButton = GUICtrlCreateButton("Bitte aufmerksam Wort für Wort bis zum Ende lesen...", 5, 472, 290)
    GUICtrlSetOnEvent(-1, "_Exit")
    GUICtrlSetState(-1, $GUI_DISABLE)

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

    GUISetState()

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

    _FillEdit(120) ;Edit Control mit sinnlosem Zeug befüllen

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

    $iLength = _GUICtrlEdit_GetLineCount($idEdit) - 34 ;Anzahl aller Zeilen Minus Zeilenanzahl des Edit controls
    ;ist dieser Wert am oberen Ende des Edit erreicht, befindet sich der Scrollbalken am unteren Ende
    If $iLength > 0 Then ;Funtionen nur registrieren, wenn der Text länger ist, als das Edit Control
    GUISetOnEvent($GUI_EVENT_PRIMARYUP, "_CheckPosition", $hGui) ;Position wird überprüft, wenn LMB losgelassen wird
    GUIRegisterMsg($WM_COMMAND, "_CheckPosition") ;Registriert Mausrad, Bild auf/ab und wenn der Curser im Edit Control bewegt wird (unter anderem)
    Else
    GUICtrlSetState($idButton, $GUI_ENABLE) ;Button aktivieren, wenn nicht genügend Zeilen vorhanden sind
    GUICtrlSetData($idButton, "Jetzt hab ich's verstanden, Scheffe!")
    EndIf

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

    While Sleep(1000)
    WEnd

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

    Func _CheckPosition()
    Local $iPos = _GUICtrlEdit_GetFirstVisibleLine($idEdit)
    ConsoleWrite($iPos & "->" & $iLength & @CRLF)
    Switch $iPos
    Case $iLength
    GUICtrlSetState($idButton, $GUI_ENABLE)
    GUICtrlSetData($idButton, "Jetzt hab ich's verstanden, Scheffe!")
    Case Else ;kann man weglassen, wenn der User nur einmal bis zum Ende scrollen soll
    GUICtrlSetState($idButton, $GUI_DISABLE) ;Button wird nur angezeigt, wenn man sich am Ende des Textes befindet
    GUICtrlSetData($idButton, "Lies schneller! Du bist erst bei Zeile " & $iPos + 34)
    EndSwitch
    EndFunc ;==>_CheckPosition

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

    Func _FillEdit($iCount)
    Local $sDisclaimer
    For $i = 1 To $iCount
    $sDisclaimer &= StringFormat("Zeile Nr. %03s: BlaBla Rabarberkompott mit alles und scharf" & @CRLF, $i)
    Next
    $sDisclaimer = StringTrimRight($sDisclaimer, 2) ;abschliessendes @CRLF entfernen
    _GUICtrlEdit_SetText($idEdit, $sDisclaimer)
    EndFunc ;==>_FillEdit

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

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

    [/autoit]

    Sanfte Grüße :D

  • Nur als Hinweis für spätere Scripte.
    @CRLF sind zwei Zeichen, nämlich CR und LF. Also muss das so heißen.

    [autoit]

    $sDisclaimer = StringTrimRight($sDisclaimer, 2)

    [/autoit]


    Den Prefix $h... verwendet man nur bei Controls die ein Handle zurückgeben.
    Die, die eine ID zurückgeben fangen mit $c an.
    Da $WM_COMMAND auch _CheckPosition aufruft, müsste die eigentlich für $WM_COMMAND anders aussehen, wenn man es sauber programmiert.
    Aber wenn Windows nicht meckert, kannst es so lassen.

  • Danke für's Korrekturlesen :thumbup:

    Werde das gleich abändern. Wegen der Präfixe werde ich mich aber an das Tutorial von Chesstiger halten, wonach Control IDs den Präfix $id haben sollten.
    Ich wollte mich auch eigendlich schon daran halten, aber im Schreibfluss bin ich in alte Gewohnheiten zurückgefallen :rolleyes:

    Bei WM_COMMAND weiss ich allerdings nicht genau, was du meinst. Könntest du das man näher erläutern?

  • So ist es mit WM_COMMAND.

    Spoiler anzeigen
    [autoit]

    #include <WindowsConstants.au3>
    #include <GuiConstants.au3>
    #include <GuiEdit.au3>
    #include <String.au3>

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

    Opt("GUIOnEventMode", 1)
    Opt("TrayIconHide", 1)

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

    Global $hGui, $cEdit, $cButton, $iLength

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

    $hGui = GUICreate("Disclaimer", 300, 500, Default, Default, BitOR($WS_CAPTION, $WS_POPUP, $WS_BORDER, $WS_CLIPSIBLINGS))
    ; Schliessen ist jetzt nur durch Klick auf den Button möglich, der nur erscheint, wenn der Text bis ans Ende gescrollt wird.

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

    $cEdit = GUICtrlCreateEdit("", 0, 0, 300, 470, BitOR($GUI_SS_DEFAULT_EDIT, $ES_READONLY)) ;Edit Control besteht aus 34 Zeilen
    $cButton = GUICtrlCreateButton("Bitte aufmerksam Wort für Wort bis zum Ende lesen...", 5, 472, 290)
    GUICtrlSetOnEvent(-1, "_Exit")
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUISetState()

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

    GUISetOnEvent($GUI_EVENT_PRIMARYUP, "_CheckPosition", $hGui) ;Position wird überprüft, wenn LMB losgelassen wird
    GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND") ;Registriert Mausrad, Bild auf/ab und wenn der Curser im Edit Control bewegt wird (unter anderem)

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

    _FillEdit(120) ;Edit Control mit sinnlosem Zeug befüllen

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

    $iLength = _GUICtrlEdit_GetLineCount($cEdit) - 34 ;Anzahl aller Zeilen Minus Zeilenanzahl des Edit controls
    ;ist dieser Wert am oberen Ende des Edit erreicht, befindet sich der Scrollbalken am unteren Ende
    If $iLength <= 0 Then GUICtrlSetState($cButton, $GUI_ENABLE) ;Button aktivieren, wenn nicht genügend Zeilen vorhanden sind

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

    While 1
    Sleep(10)
    WEnd

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

    Func _CheckPosition()
    Local $iPos = _GUICtrlEdit_GetFirstVisibleLine($cEdit)
    ConsoleWrite($iPos & "->" & $iLength & @CRLF)
    If $iPos = $iLength Then
    GUICtrlSetState($cButton, $GUI_ENABLE)
    GUICtrlSetData($cButton, "Jetzt hab ich's verstanden, Scheffe!")
    Else ;kann man weglassen, wenn der User nur einmal bis zum Ende scrollen soll
    GUICtrlSetState($cButton, $GUI_DISABLE) ;Button wird nur angezeigt, wenn man sich am Ende des Textes befindet
    GUICtrlSetData($cButton, "Lies schneller! Du bist erst bei Zeile " & $iPos + 34)
    EndIf
    EndFunc ;==>_CheckPosition

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

    Func _WM_COMMAND($_hWnd, $_iMsg, $_iWParam, $_iLParam)
    #forceref $_hWnd, $_iMsg, $_iWParam, $_iLParam
    Local $_hWndFrom, $_iIDFrom, $_iCode, $_hEdit, $_iPos

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

    If Not IsHWnd($cEdit) Then $_hEdit = GUICtrlGetHandle($cEdit)

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

    $_hWndFrom = $_iLParam
    $_iIDFrom = BitAND($_iWParam, 0xFFFF)
    $_iCode = BitShift($_iWParam, 16)

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

    Switch $_hWndFrom
    Case $cEdit, $_hEdit
    Switch $_iCode
    Case $EN_VSCROLL
    $_iPos = _GUICtrlEdit_GetFirstVisibleLine($cEdit)
    ConsoleWrite($_iPos & "->" & $iLength & @CRLF)
    If $_iPos = $iLength Then
    GUICtrlSetState($cButton, $GUI_ENABLE)
    GUICtrlSetData($cButton, "Jetzt hab ich's verstanden, Scheffe!")
    Else ;kann man weglassen, wenn der User nur einmal bis zum Ende scrollen soll
    GUICtrlSetState($cButton, $GUI_DISABLE) ;Button wird nur angezeigt, wenn man sich am Ende des Textes befindet
    GUICtrlSetData($cButton, "Lies schneller! Du bist erst bei Zeile " & $_iPos + 34)
    EndIf
    EndSwitch
    EndSwitch

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

    Return $GUI_RUNDEFMSG
    EndFunc

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

    Func _FillEdit($count)
    Local $sDisclaimer
    For $i = 1 To $count
    $sDisclaimer &= StringFormat("Zeile Nr. %03s: BlaBla Rabarberkompott mit alles und scharf" & @CRLF, $i)
    Next
    $sDisclaimer = StringTrimRight($sDisclaimer, 2) ;abschliessendes @CRLF entfernen
    _GUICtrlEdit_SetText($cEdit, $sDisclaimer)
    EndFunc ;==>_FillEdit

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

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

    [/autoit]


    Und id verwende ich nicht, weil ich öfters Felder habe die heißen dann $cID. Und $idID irgendwie blöd ist. Aber jeder kann es natürlich nennen wie er will. Nur die meisten nehmen wirklich $c.... Und wenn ich jetzt ein Array habe von Controls heißt es $ac..., bei dir müsste es dann $aid.. heißen. Und bei meiner Variante besteht auch keine Verwechselung mit $i... für Integer. Ich hatte mir mal die Regel gesetzt, dass die jeweiligen Buchstaben der Prefixe nicht bei den Anderen vorkommen.

  • Puh! Da hab ich ja nen ziemlichen Wust an Code ausgelassen ;(
    Werde mir das später mal genauer zu Gemüte führen.
    Aber ich muss trotzdem fragen; was spricht gegen meinen "unsauberen" Code? Ist Windows so nachsichtig? Hab ich einfach nur "Glück" gehabt? Immerhin funktionierts ja scheinbar genauso gut...

    Das mit den Präfixen klingt ganz einleuchtend, was du schreibst. Vieleicht werde ich meine Notation nochmal überdenken :P