WIN 10 Tablet - ScrollBar - WM_TOUCH

  • Hallo,

    am Rechner habe ich ein scrollbares Fenster mit Scrollbalken. Drehe ich im Fensterbereich das Mausrad ist der Scrollbalken synchron. Andersherum genauso. Wenn ich auf dem Tablet im Fensterbereich mit dem Finger "scrolle" ist das asynchron zum Balken. Teile des gescrollten Fensters verschwinden auch. Das funktioniert nur einwandfrei, wenn man mit dem Finger den Scrollbalken bedient. Gibt es da Abhilfe? Hat jemand Erfahrung damit und kann mir einen Tipp geben?

    Dank und Gruß

    Thomas

  • Hier noch ein Beispiel (File und GuiScroll.au3 angehängt):

  • Hallo allerseits,

    ich bin ein klein wenig weitergekommen und habe mich mal an diesem Script probiert:

    Spoiler anzeigen

    Die WM-TOUCH Funktion funktioniert grundsätzlich. Jedoch ist die Zeile

    Code
    For $i = 0 To (Int($wParam)-1) Step 1

    problematisch, weil

    Code
    Int($wParam)

    immer 1 gibt. D.h. hier kann keine Schleifenverarbeitung stattfinden, soweit ich das sehe. Hat jemand eine Idee?

    Ansonsten: Frohe Weihnachten!

    Dank und Gruß

    Thomas

  • Dann "aktiviere" doch mal die Zeilen 57-50... oder ändere sie, für maximale Debug-Info...

    AutoIt
        GUICtrlSetData($iMemo, "$hWnd                         : " & $hWnd & @CRLF, 1)
        GUICtrlSetData($iMemo, "$Msg                          : " & $Msg & @CRLF, 1)
        GUICtrlSetData($iMemo, "$wParam                       : " & $wParam & @CRLF, 1)
        GUICtrlSetData($iMemo, "$lParam                       : " & $lParam & @CRLF, 1)
    
        GUICtrlSetData($iMemo, "@error                        : " & @error & @CRLF, 1)
        GUICtrlSetData($iMemo, "_WinAPI_GetLastError()        : " & _WinAPI_GetLastError() & @CRLF, 1)
        GUICtrlSetData($iMemo, "_WinAPI_GetLastErrorMessage() : " & _WinAPI_GetLastErrorMessage()() & @CRLF, 1)
        GUICtrlSetData($iMemo, "Func0 Ret                     : " & $aRet0[0] & @CRLF, 1)
  • Hatte ich natürlich zwischenzeitlich aktiviert - ohne Erkenntnisse ... Hier die Ausgabe mit Deinen Zeilen:

    Microsoft sagt z.B. zu wParam: Link

  • wParam

    The low-order word contains the number of touch points associated with this message. The high-order word is reserved for future use.


    wParam liefert dir also die Anzahl der Berührungspunkte, an der das Display berührt wurde, zu dem Zeitpunkt, an dem die WM_TOUCH-Message erstellt wurde.

    Wenn du das Display nur mit einem Finger berührst, dann kommt da natürlich auch immer eine 1.

    Demnach sind die Infos in der Debugausgabe also völlig korrekt! Berühre das Display mal mit mehreren Fingern... in $iTouchPoints (s. neues Script) sollte dann die Anzahl der "Finger" stehen.

    Ich habe dein Script mal ein wenig umgeschrieben... teste es mal...

    5 Mal editiert, zuletzt von Bitnugger (26. Dezember 2017 um 09:55)

  • Ahh... Ich hatte den wParam falsch verstanden! Dann müßte das Delta-y (ich brauche nur den y-Scrollweg) über dieselbe dwID und die Differenz des y-Wertes dabei (zwischen Anfang und Ende der andauernden Fingerbewegung) auf die Funktionen der <GuiScrollBars.au3> übertragen werden um die entsprechenden Positionen zu synchronisieren.

    Vielen Dank!

    Wobei dann jetzt für jeden WM_TOUCH-Durchlauf mit dieser einen dwID in Verbindung mit dem ersten und letzten y-Wert ein Speicher zur Auswertung angelegt werden. Tricky ...

    Einmal editiert, zuletzt von TJF (26. Dezember 2017 um 11:48)

  • So wie ich es verstehe, ist die dwID bei nur einem TouchPoint nicht von Interesse. Die spielt nur dann eine wichtige Rolle, wenn du mehrere TouchPoints hast, denn in dem Fall musst du diese ja unterscheiden können.

    Von daher benötigst du eigentlich nur den y-Wert... und immer wenn eine WM_TOUCH-Message kommt, synchronisierst du die ScrollBar auf den neuen Wert.

    Du musst in deinem "Message-Handler" WM_TOUCH aber noch überprüfen, ob du mehrere TouchPoints bekommen hast... ist dies der Fall, dann darfst du die y-Position nämlich nicht synchronisieren!

    Was passieren soll, wenn zwei oder mehr TouchPoints vorhanden sind, kannst du dann natürlich auch händeln. Auf meinem Andoid-Tablet werden z.B. zwei aufeinanderfolgende Nachrichten mit drei TouchPoints innerhalb eines Doppelklicks, als Auto-Zoom verstanden, eine Nachricht mit zwei TouchPoints als manuellen Zoom... oder so ähnlich... 8o

  • Wenn ich mit einem "Fingerstreich" scrolle (also pausenlos den Finger auf dem Tablet bewege) wird die WM_TOUCH Funktion mehrmals durchlaufen. Eine einzelne Berührung, die nicht "scrollt" ist unerheblich. Genau für diese eine "Fingerstreich"-Aktion ist eine dwID aussagekräftig. Diese hat einen ersten Koordinaten-Wert (der Punkt auf der Tablet-Koordinate wo der Finger aufsetzt) und einen letzten Wert (der Punkt auf der Tablet-Koordinate wo der Finger wieder absetzt). Die Differenz muss dann mit der Scrollfunktion synchronisiert werden.

    Der erste Gedanke, der mir dabei kommt, ist die Speicherung in einem sich verändernden Array am Ende der WM_TOUCH-Funktion. Vielleicht bin ich da aber auch gerade zu kompliziert drauf... :/

  • Die Differenz muss dann mit der Scrollfunktion synchronisiert werden.

    Ich meine, da hast du einen Denkfehler... denn du willst doch sicherlich in "Echtzeit" scrollen... in dem Fall musst du bereits bei der der ersten x-/y-Koordinate reagieren, die nicht mit dem Startpunkt übereinstimmt... und nicht erst dann, wenn du den Finger wieder wegnimmst!

    Und ja, sicher, die dwID brauchst du natürlich... immer... denn sobald sich diese ändert, musst du dir den neuen Startpunkt merken. Solange die identisch mit der vorherigen Nachricht ist, musst du nur kontrollieren, ob sich die x-/y-Koordinate geändert hat, und wenn ja, die Position(en) synchronisieren, bzw. die Richtung(en) angeben, in die gescrollt werden soll.

    Test das Script im Anhang mal... wenn möglich auch mit Mausrad... habe da auch noch ein paar Sachen/Kommentare eingebaut... und gib mir mal bitte die minimalen und maximalen Koordinaten für x und y durch.

  • Wow...

    Ich melde mich am späten Nachmittag genauer zurück. Muss heute arbeiten...

    In x-Richtung scrolle ich momentan gar nicht. In y-Richtung zwischen 0 und 250 in meinem Demo-Scrollbereich. Das ist aber fensterabhängig.

  • Schaut ja sehr fein aus. Ich habe das mal hier an meine Tablet-Größe angepasst:

    Die Rückmeldungen kommen wie gewünscht. Bis auf das Scrollen :). Hier stehe ich mit der Variable auf dem Schlauch:

    Code
    $iDirectionX
    Code
    For $i = 1 To 7 ; Schleife regelt die Scroll Geschwindigkeit, je mehr Durchläufe desto schneller
        If $iDirectionX Then _SendMessage($hWnd, $WM_HSCROLL, $iDirectionX)
        If $iDirectionX Then _SendMessage($hWnd, $WM_VSCROLL, $iDirectionY)
    Next
  • Ops... ja, erwischt!

    Da ist ein $iDirectionX zu viel... wieder mal ein typischer Copy & Paste-Fehler. ;)

    Richtig ist:

    AutoIt
    For $i = 1 To 7 ; Schleife regelt die Scroll Geschwindigkeit, je mehr Durchläufe desto schneller
        If $iDirectionX Then _SendMessage($hWnd, $WM_HSCROLL, $iDirectionX) ; horizontal scrollen (rechts, links)
        If $iDirectionY Then _SendMessage($hWnd, $WM_VSCROLL, $iDirectionY) ; vertikal scrollen (oben, unten)
    Next

    Das mit der For...Next-Schleife will mir aber nicht so richtig in den Kopf... die Aussage, das es dadurch schneller gehen soll, ist in meinen Augen völliger Quatsch... für einen ersten Test habe ich das aber mal alles unverändert gelassen. Das werde ich aber noch genauer untersuchen.

    Hier liest du ja auch mit...  Melba23 wird wohl über kurz oder lang auch eine Unterstüzung für WM_TOUCH in seine UDF einbauen... dann kannst du das Aktivieren der ScrollBars mit nur einem Funktionsaufruf erledigen.

    Die Syntax dafür sieht dann so aus:

    AutoIt
    _GUIScrollbars_Generate ($hWnd, $iH_Scroll = 0, [$iV_Scroll = 0, [$iH_Tight = 0, [$iV_Tight = 0, [$fBefore = False, [$iRepeat = 0 [, $bRegisterMsg = True]]]]]])
  • Ja, definiert ist die Variable. Sie nimmt aber nie einen Wert an. Teste mal:

    AutoIt
    For $i = 1 To 7 ; Schleife regelt die Scroll Geschwindigkeit, je mehr Durchläufe desto schneller
        If $iDirectionX Then _SendMessage($hWnd, $WM_HSCROLL, $iDirectionX)
        If $iDirectionY Then _SendMessage($hWnd, $WM_VSCROLL, $iDirectionY)
        MsgBox(0,"$iDirectionY",$iDirectionY,1)
    Next

    Das hier z.B. gibt einen Wert aus und es scrollt!!! Zwar noch nicht perfekt - aber doch ... :)

  • Ich habe das jetzt schon halbwegs (!) in die richtige Richtung gebracht. Habe jetzt hier die aktuelle ScrollPosition ausgelesen und die jeweilige y-Bewegung (Wertdifferenz) addiert. Das ganze muss jetzt noch limitiert werden durch den Scrollbereich ... weil das Scroll-Fenster noch über und unter das Soll verschoben werden kann.

  • Ja, definiert ist die Variable. Sie nimmt aber nie einen Wert an.

    Doch, das tut sie... die Variablen $iDirectionX und $iDirectionY wurden in Zeile 152 deklariert und werden entsprechend der WM_TOUCH-Message in Zeile 170 und 181 definiert - das ist soweit alles richtig! ;)

    Variablen deklarieren... (benennen, bezeichnen, kundgeben, kundtun, zur Kenntnis bringen)

    AutoIt
    Local $iDirectionX, $iDirectionY

    Variablen definieren.... (bestimmen, determinieren, festlegen, Wert(e) zuweisen)

    AutoIt
    $iDirection = $iX = $aPoints[0][$eX] ? $SB_LINERIGHT : $SB_LINELEFT
    AutoIt
    $iDirection = $iY = $aPoints[0][$eY] ? $SB_LINEDOWN : $SB_LINEUP

    Message senden... hier ist der Fehler!

    AutoIt
    If $iDirectionX Then _SendMessage($hWnd, $WM_HSCROLL, $iDirectionX)
    If $iDirectionX Then _SendMessage($hWnd, $WM_VSCROLL, $iDirectionY)


    Richtig ist...

    Code
    If $iDirectionX Then _SendMessage($hWnd, $WM_HSCROLL, $iDirectionX)
    If $iDirectionY Then _SendMessage($hWnd, $WM_VSCROLL, $iDirectionY)

    Teste mal bitte das Script im Anhang... das ist von Melba23 ...ich habe da lediglich noch WM_TOUCH hinzugefügt.

  • Scrollt aber auch so nicht:

    AutoIt
    For $i = 1 To $g_iSendRepeat ; 1, hier stand 7... angeblich regelt die Schleife die Scrollgeschwindigkeit... je mehr Durchläufe, desto schneller.
        _SendMessage($hWnd, $WM_HSCROLL, 50) ; horizontal scrollen (rechts, links)
        _SendMessage($hWnd, $WM_VSCROLL, 50) ; vertikal scrollen (oben, unten)
    Next