Das hier funktioniert so gut, dass ich zunächst in der praktischen Ausführung keinen Scrollfehler am Tablet finde. Gut zu sehen am Listview in der Mitte des Scrollbereichs. Ist nur für den vertikalen y-Bereich ausgeführt:
AutoIt
#Include <StaticConstants.au3>
;~ #include <StructureConstants.au3>
;~ #include <WindowsConstants.au3>
;~ #include <Array.au3>
;~ #include <WinAPI.au3>
;~ #include <GUIScrollBars.au3>
;~ #include <ScrollBarConstants.au3>
#include <ListViewConstants.au3>
#include <Array.au3>
#include <GuiEdit.au3>
#include "GuiScroll_alt.au3" ; -> http://autoit.de/index.php?page=Thread&postID=162464#post162464
Global $g_idMemo,$hScrollPl
Global Const $tagTOUCHINPUT = "LONG x; LONG y; HANDLE hSource; DWORD dwID; DWORD dwFlags; DWORD dwMask; DWORD dwTime; ULONG_PTR dwExtraInfo; DWORD cxContact; DWORD cyContact"
Global $iMemo = 0
Global $y = -1
Global $g_iMouseButtons, $g_iDigitizer
; Diese Konstanten sind leider noch nicht in Autoit deklariert... sonst wären sie in WindowsConstants.au3 zu finden.
Global Const $SM_DIGITIZER = 0x5E ; 94
Global Const $TABLET_CONFIG_NONE = 0x00
Global Const $NID_INTEGRATED_TOUCH = 0x01
Global Const $NID_EXTERNAL_TOUCH = 0x02
Global Const $NID_INTEGRATED_PEN = 0x04
Global Const $NID_EXTERNAL_PEN = 0x08
Global Const $NID_MULTI_INPUT = 0x40
Global Const $NID_READY = 0x80
; Specifies that hWnd prefers noncoalesced touch input.
Global Const $TWF_FINETOUCH = 0x00000001
; Setting this flag disables palm rejection which reduces delays for getting WM_TOUCH messages. This is useful if you want as quick of a response as possible when a user touches your application.
; By default, palm detection is enabled and some WM_TOUCH messages are prevented from being sent to your application. This is useful if you do not want to receive WM_TOUCH messages that are from palm contact.
Global Const $TWF_WANTPALM = 0x00000002
Global $hScrollPl_b = 400; Hoehe Scrollfenster
Global $hScrollPl_a = 650; Max Scroll
Global $hScrollPl_c = $hScrollPl_a - $hScrollPl_b; Scrollbereich
startGui()
Func startGui()
_GetSystemMetrics()
$Gui = GUICreate("", 850, 700, -1, -1)
$up = GUICtrlCreateButton("UP", 10, 10, 80, 40)
$down = GUICtrlCreateButton("DOWN", 100, 10, 80, 40)
GUICtrlCreateLabel("Schliessen mit ESC", 550, 10, 120, 40)
;GUICtrlCreateLabel("y = ",580, 30)
;$iMemo = GUICtrlCreateLabel("",550, 30)
$iMemo = GUICtrlCreateEdit("", 530, 50, 300, 600, $WS_VSCROLL)
_GUICtrlEdit_SetLimitText($iMemo, 0x80000000)
GUIRegisterMsg($WM_MOUSEWHEEL, "_Scrollbars_WM_MOUSEWHEEL")
$hScrollPl = GUICreate("$hScrollPl", 500, $hScrollPl_b, 10, 100, BitOR($WS_POPUP, $WS_GROUP, $WM_VSCROLL, $WS_CLIPSIBLINGS), $WS_EX_MDICHILD, $Gui)
GUISetBkColor(0xffffff)
Scrollbar_Create($hScrollPl, $SB_VERT, 500)
Scrollbar_Step(10, $hScrollPl, $SB_VERT)
_GUIScrollBars_SetScrollInfoMax($hScrollPl, $SB_VERT, $hScrollPl_a); also: 650 minus 400 Hoehe = 250 scroll
$hDLL = DllCall("User32.dll", "BOOL", "RegisterTouchWindow", "HWND", $hScrollPl, "ULONG", 2) ; hier nach Entstehung von $hScrollPl
GUIRegisterMsg($WM_TOUCH, "WM_TOUCH")
$art = GUICtrlCreateLabel("", 1, 1) ; Label für folgenden Focus...
$hListV = GUICtrlCreateListView("1|2", 100, 100, 300, 200, BitOR($LVS_REPORT, $LVS_NOCOLUMNHEADER, $LVS_SHOWSELALWAYS))
GUISetState(@SW_SHOW, $Gui)
GUISetState(@SW_SHOW, $hScrollPl)
GUICtrlSetState($art, $GUI_FOCUS); Focus auf Label von $hScrollPl
GUISwitch($Gui)
;GUISetState(@SW_SHOW, $Gui)
_Memo(@CRLF & "Vertical" & @CRLF & "--------------------------------------")
_Memo("nPage.... : " & _GUIScrollBars_GetScrollInfoPage($hScrollPl, $SB_VERT))
_Memo("nPos..... : " & _GUIScrollBars_GetScrollInfoPos($hScrollPl, $SB_VERT))
_Memo("nMin..... : " & _GUIScrollBars_GetScrollInfoMin($hScrollPl, $SB_VERT))
_Memo("nMax..... : " & _GUIScrollBars_GetScrollInfoMax($hScrollPl, $SB_VERT))
_Memo("nTrackPos : " & _GUIScrollBars_GetScrollInfoTrackPos($hScrollPl, $SB_VERT))
;_GUIScrollBars_Init($hScrollPl)
;_GUIScrollBars_SetScrollInfoPos($hScrollPl,$SB_VERT,100)
;_GUIScrollBars_ScrollWindow($hScrollPl,0,200); bewegt nur das Fenster - nicht die Scrollbar
;Scrollbar_Scroll($hScrollPl, $SB_VERT, 250); scrollt um ...
While 1
$iMsg3 = GUIGetMsg()
Switch $iMsg3
Case $GUI_EVENT_CLOSE
DllClose($hDLL)
Exit
Case $up
MsgBox(0, "Info", "Button up gedrückt")
GUICtrlSetState($art, $GUI_FOCUS); Focus auf Label von $hScrollPl
Scrollbar_Scroll($hScrollPl, $SB_VERT, 250); scrollt um ...
Case $down
MsgBox(0, "Info", "Button down gedrückt")
GUICtrlSetState($art, $GUI_FOCUS); Focus auf Label von $hScrollPl
EndSwitch
WEnd
EndFunc ;==>startGui
; Die in Au3Check 1.51 eingeführte Anweisung #uses, wurde ab 1.52 in #forceref umbenannt. Diese hat zwei Aufgaben.
; 1.) Vermeidung von -w 5 Warnungen durch Au3Check.
; 2.) Vermeiden, dass globale Variablen und Funktionen in der Liste der Bezugssymbole erscheinen, wenn eine Funktion z.B. via Call($fn) aufgerufen wird.
Func WM_TOUCH($hWnd, $Msg, $wParam, $lParam)
#forceref $hWnd, $Msg
Local Static $aDllError = [ _
[1, 'Die Dll-Datei kann nicht verwendet werden.'], _
[2, 'unbekannter Rückgabewert "return type".'], _
[3, 'Funktion wurde nicht in der DLL-Datei gefunden.'], _
[4, 'Falsche Anzahl von Parametern.'], _
[5, 'Falscher Parameter.']], _
$idwID, $iX, $iY
Local Enum $eID, $eX, $eY
Local $iTouchPoints = _WinAPI_LoWord($wParam) ; Anzahl der Berührungspunkte, an der das Display berührt wurde, als diese Message erstellt wurde.
Local $aTouchInput[$iTouchPoints]
Local $iBuffer = DllStructCreate("BYTE buffer[" & $iTouchPoints * 40 & "]")
;~ _Memo("BYTE buffer[" & $iTouchPoints * 40 & "]")
Local $tTouchInfo = DllStructCreate($tagTOUCHINPUT, DllStructGetPtr($iBuffer))
Local $pTouchInfo = DllStructGetPtr($tTouchInfo)
Local $iStructSize = DllStructGetSize($tTouchInfo)
For $i = 0 To $iTouchPoints - 1 Step 1
$aTouchInput[$i] = DllStructCreate($tagTOUCHINPUT, $pTouchInfo + $i * 40)
Next
; https://msdn.microsoft.com/de-de/library/windows/desktop/dd317334(v=vs.85).aspx
; typedef struct _TOUCHINPUT {
; LONG x;
; LONG y;
; HANDLE hSource;
; DWORD dwID;
; DWORD dwFlags;
; DWORD dwMask;
; DWORD dwTime;
; ULONG_PTR dwExtraInfo;
; DWORD cxContact;
; DWORD cyContact;
; } TOUCHINPUT, *PTOUCHINPUT;
Local $aRet = DllCall("User32.dll", "BOOL", "GetTouchInputInfo", "HANDLE", $lParam, "UINT", $wParam, "ULONG_PTR", $pTouchInfo, "int", DllStructGetSize($tTouchInfo))
; If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, use the GetLastError function.
If @error Then
Local $iError = @error, $iIndex = _ArraySearch($aDllError, $iError), $sErrorText = $iIndex = -1 ? 'Unbekannter Fehler' : $aDllError[$iIndex][1]
_Memo("Error bei DllCall : " & $iError & ' Errortext = ' & $sErrorText)
_Memo("_WinAPI_GetLastError() : " & _WinAPI_GetLastError())
_Memo("_WinAPI_GetLastErrorMessage() : " & _WinAPI_GetLastErrorMessage())
_Memo("_ArrayToString($aRet, ', ') : " & _ArrayToString($aRet, ', '))
Else
_Memo("************************************")
_Memo("Finger Numbers : " & $iTouchPoints)
Local $aPoints[$iTouchPoints][3] ; $idwID, $iX/100, $iY/100
For $j = 0 To $iTouchPoints - 1 Step 1
$aPoints[$j][$eID] = DllStructGetData($aTouchInput[$j], "dwID")
$aPoints[$j][$eX] = DllStructGetData($aTouchInput[$j], "x") / 100
$aPoints[$j][$eY] = DllStructGetData($aTouchInput[$j], "y") / 100
_Memo(StringFormat("Points %2i dwID: %3i x: %5s y: %5s" & $j, $aPoints[$j][$eID], $aPoints[$j][$eX], $aPoints[$j][$eY]))
Next
_Memo("Position : " & _GUIScrollBars_GetScrollInfoPos($hScrollPl,$SB_VERT))
Local $iPosY = 0
Local $iPos = 0
Local $bY = 0
Local $iDirectionX = 0
Local $iDirectionY = 0;, $iXAmount, $iYAmount
Switch $iTouchPoints
Case 1 ; Gui vertikal scrollen... sobald sich die y-Koordinate in Relation zum Startpunkt geändert hat und sich die dwID nicht geändert hat!
; $idwID, $iX, $iY
; $eID, $eX, $eY
If $idwID <> $aPoints[0][$eID] Then ; dann neue ID und Startpunkte merken und auf nächste Message warten
$idwID = $aPoints[0][$eID]
$iX = $aPoints[0][$eX]
$iY = $aPoints[0][$eY]
Else
If $iX <> $aPoints[0][$eX] Then ; dann müssen horizontal wir scrollen!
; $iXAmount ...
; Positive Werte für $iXAmount verschieben den sichtbaren Fensterbereich nach rechts, negative Werte verschieben nach links.
; $iXAmount = DllStructGetData($tTEXTMETRIC, "tmAveCharWidth")
; tmAveCharWidth Definiert die durchschnittliche Breite der Zeichen in der Schrift (üblicherweise festgelegt als die Breite des Buchstabens x).
; Dieser Wert enthält nicht den erforderlichen Überhang für Fett oder kursiv geschriebene Zeichen.
; Positive Werte für $iYAmount verschieben den sichtbaren Fensterbereich nach unten, negative Werte verschieben nach oben.
_Memo(StringFormat("WM_TOUCH: Das Fenster wird nach %s gescrollt!", $iX < $aPoints[0][$eX] ? 'rechts' : 'links'))
$iDirection = $iX = $aPoints[0][$eX] ? $SB_LINERIGHT : $SB_LINELEFT
$iDirectionX = 1
$iX = $aPoints[0][$eX] ; neue Position merken
EndIf
If $iY <> $aPoints[0][$eY] Then ; dann müssen wir vertikal scrollen!
$bY = $aPoints[0][$eY] - $iY ; positiv wenn nach unten gewischt wird
$iPos = _GUIScrollBars_GetScrollInfoPos($hScrollPl,$SB_VERT)
$iPosY = $iPos+$bY
If $iPosY < 0 Then
$iPosY = 0
Endif
If $iPosY > $hScrollPl_c Then
$iPosY = $hScrollPl_c
Endif
; $iYAmount ...
; $iYAmount = DllStructGetData($tTEXTMETRIC, "tmHeight") + DllStructGetData($tTEXTMETRIC, "tmExternalLeading")
; tmHeight Definiert die Höhe (Oberlänge + Unterlänge) der Zeichen.
; tmExternalLeading Definiert den Durchschuß (Abstand) den die Anwendung zwischen den Zeilen hinzufügt.
; Da dieser Bereich sich außerhalb der Schrift befindet, enthält er keine Zeichen und wird nicht durch Textausgabe-Aufrufe modifiziert, weder im Modus OPAQUE noch im Modus TRANSPARENT.
; Der Designer kann dieses Mitglied auf Null setzen.
_Memo(StringFormat("WM_TOUCH: Das Fenster wird nach %s gescrollt!", $iY < $aPoints[0][$eY] ? 'unten' : 'oben'))
$iDirection = $iY = $aPoints[0][$eY] ? $SB_LINEDOWN : $SB_LINEUP
$iDirectionY = 1
$iY = $aPoints[0][$eY] ; neue Position merken
EndIf
For $i = 1 To 7 ; Schleife regelt die Scroll Geschwindigkeit, je mehr Durchläufe desto schneller
If $iDirectionX = 1 Then Scrollbar_Scroll($hScrollPl,$SB_HORZ, 0)
If $iDirectionY = 1 Then Scrollbar_Scroll($hScrollPl,$SB_VERT, $iPosY)
Next
EndIf
Case 2 ; manueller Zoom
; tu was...
Case 3 ; automatischer Zoom
; tu was...
EndSwitch
EndIf
EndFunc ;==>WM_TOUCH
; wParam
; Das höherwertige Wort gibt die Entfernung an, um die das Rad gedreht wird, ausgedrückt in Vielfachen oder Unterteilungen von WHEEL_DELTA, was 120 ist. Ein positiver Wert zeigt an,
; dass das Rad vorwärts gedreht wurde, weg von dem Benutzer; Ein negativer Wert zeigt an, dass das Rad rückwärts zum Benutzer gedreht wurde.
; Das niederwertige Wort gibt an, ob verschiedene virtuelle Tasten gedrückt sind. Dieser Parameter kann einen oder mehrere der folgenden Werte haben.
; MK_CONTROL 0x0008 The CTRL key is down.
; MK_LBUTTON 0x0001 The left mouse button is down.
; MK_MBUTTON 0x0010 The middle mouse button is down.
; MK_RBUTTON 0x0002 The right mouse button is down.
; MK_SHIFT 0x0004 The SHIFT key is down.
; MK_XBUTTON1 0x0020 The first X button is down.
; MK_XBUTTON2 0x0040 The second X button is down.
; lParam
; Das niederwertige Wort gibt die X-Koordinate des Zeigers relativ zur oberen linken Ecke des Bildschirms an.
; Das höherwertige Wort gibt die Y-Koordinate des Zeigers relativ zur oberen linken Ecke des Bildschirms an.
; Return value
; Wenn eine Anwendung diese Nachricht verarbeitet, sollte sie null zurückgeben.
Func _Scrollbars_WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam)
#forceref $hWnd, $iMsg, $lParam
Local $iDirection, $iDelta = BitShift($wParam, 16) ; Mouse wheel movement
If BitAND($wParam, 0x0000FFFF) Then ; If Ctrl or Shift pressed move Horz scrollbar
$iDirection = $SB_LINERIGHT
If $iDelta > 0 Then $iDirection = $SB_LINELEFT
_Memo(StringFormat("WM_MOUSEWHEEL: Das Fenster wird nach %s gescrollt!", $iDirection = $SB_LINERIGHT ? 'rechts' : 'links'))
For $i = 1 To 7
_SendMessage($hWnd, $WM_HSCROLL, $iDirection)
Next
Else ; Move Vert scrollbar
$iDirection = $SB_LINEDOWN
If $iDelta > 0 Then $iDirection = $SB_LINEUP
_Memo(StringFormat("WM_MOUSEWHEEL: Das Fenster wird nach %s gescrollt!", $iDirection = $SB_LINEUP ? 'oben' : 'unten'))
For $i = 1 To 7 ; Schleife regelt die Scroll Geschwindigkeit, je mehr Durchläufe desto schneller
_SendMessage($hWnd, $WM_VSCROLL, $iDirection)
Next
EndIf
;~ Return $GUI_RUNDEFMSG
EndFunc ;==>_Scrollbars_WM_MOUSEWHEEL
; https://msdn.microsoft.com/en-us/library/windows/desktop/ms724385(v=vs.85).aspx
Func _GetSystemMetrics()
; ___ 0___|___ 10___|___ 20___|___ 30___|___ 40___|___ 50___|___ 60___|___ 70___|___ 80___|___ 90___|
; 123456789|123456789|123456789|123456789|123456789|123456789|123456789|123456789|123456789|123456789|
Local Static $aDigitizer[7] = [ _
'! $g_iDigitizer: 0x00 - Der Eingabedigitizer verfügt nicht über Fingereingabefunktionen.', _
'+ $g_iDigitizer: 0x01 - Für die Eingabe wird ein integrierter Fingereingabedigitizer verwendet.', _
'+ $g_iDigitizer: 0x02 - Für die Eingabe wird ein externer Fingereingabedigitizer verwendet.', _
'+ $g_iDigitizer: 0x04 - Für die Eingabe wird ein integrierter Stiftdigitizer verwendet.', _
'+ $g_iDigitizer: 0x08 - Für die Eingabe wird ein externer Stiftdigitizer verwendet.', _
'+ $g_iDigitizer: 0x40 - Für die Eingabe wird ein Eingabedigitizer verwendet, der Mehrfacheingaben\unterstützt.', _
'! $g_iDigitizer: 0x80 - Der Eingabedigitizer ist für die Eingabe bereit. Wenn dieser Wert nicht\festgelegt ist, bedeutet dies möglicherweise, dass der Tablettdienst\beendet wurde, der Digitizer nicht unterstützt wird oder die\Digitizertreiber nicht installiert wurden.']
If _ArraySearch($aDigitizer, '\', 0, 0, 0, 1) > -1 Then
Local $aSlit, $sIndent = __StringRepeat(' ', StringInStr($aDigitizer[0], '-') -1), $sSpacer = __StringRepeat('-', 96) & @CRLF
For $i = 0 To UBound($aDigitizer) -1 Step 1
$aSplit = StringSplit($aDigitizer[$i], '\', 2)
;~ If @error Then ContinueLoop
For $j = 0 To UBound($aSplit) -1 Step 1
$aSplit[$j] = $j = 0 ? $aSplit[$j] & @CRLF : StringLeft($aSplit[0], 2) & $sIndent & $aSplit[$j] & @CRLF
;~ If $j = 0 Then $aSplit[$j] &= @CRLF
;~ If $j > 0 Then $aSplit[$j] = StringLeft($aSplit[0], 2) & ' ' & $aSplit[$j] & @CRLF
Next
$aDigitizer[$i] = _ArrayToString($aSplit, '')
Next
EndIf
; Ungleich Null, wenn eine Maus installiert ist; ansonsten 0. Dieser Wert ist selten Null, da virtuelle Mäuse unterstützt werden und einige Systeme das Vorhandensein des Ports anstelle des Vorhandenseins einer Maus erkennen.
$g_iMousePresent = _WinAPI_GetSystemMetrics($SM_MOUSEPRESENT)
; Die Anzahl der Tasten auf einer Maus, oder Null, wenn keine Maus installiert ist. PS: Da frage ich mich doch glatt, wozu $SM_MOUSEPRESENT gut sein soll?!
$g_iMouseButtons = _WinAPI_GetSystemMetrics($SM_CMOUSEBUTTONS)
; Ungleich Null, wenn das aktuelle Betriebssystem mindestens Windows 7 oder Windows Server 2008 R2 ist und der Tablet PC-Eingabe-Dienst gestartet wurde; andernfalls 0.
$g_iDigitizer = _WinAPI_GetSystemMetrics($SM_DIGITIZER)
ConsoleWrite($sSpacer)
ConsoleWrite(($g_iMousePresent ? '+ ' : '! ') & '$g_iMousePresent: Du hast '&($g_iMousePresent ? '' : 'k')&'eine Maus angeschlossen!' & @CRLF)
ConsoleWrite($g_iMouseButtons ? '+ $g_iMouseButtons: Du hast eine Maus mit '&$g_iMouseButtons&' Buttons angeschlossen!' & @CRLF : '! $g_iMouseButtons: Du hast keine Maus angeschlossen!')
For $i = 0 To UBound($aDigitizer) -1 Step 1
Switch True
Case $i = 0 And BitAND($g_iDigitizer, $TABLET_CONFIG_NONE) = $TABLET_CONFIG_NONE
ConsoleWrite($aDigitizer[0] & @CRLF)
Case $i = 1 And BitAND($g_iDigitizer, $NID_INTEGRATED_TOUCH) = $NID_INTEGRATED_TOUCH
ConsoleWrite($aDigitizer[1] & @CRLF)
Case $i = 2 And BitAND($g_iDigitizer, $NID_EXTERNAL_TOUCH) = $NID_EXTERNAL_TOUCH
ConsoleWrite($aDigitizer[2] & @CRLF)
Case $i = 3 And BitAND($g_iDigitizer, $NID_INTEGRATED_PEN) = $NID_INTEGRATED_PEN
ConsoleWrite($aDigitizer[3] & @CRLF)
Case $i = 4 And BitAND($g_iDigitizer, $NID_EXTERNAL_PEN) = $NID_EXTERNAL_PEN
ConsoleWrite($aDigitizer[4] & @CRLF)
Case $i = 5 And BitAND($g_iDigitizer, $NID_MULTI_INPUT) = $NID_MULTI_INPUT
ConsoleWrite($aDigitizer[5] & @CRLF)
Case $i = 6 And BitAND($g_iDigitizer, $NID_READY) = $NID_READY
ConsoleWrite($aDigitizer[6] & @CRLF)
EndSwitch
Next
ConsoleWrite($sSpacer)
EndFunc ;==>_GetSystemMetrics
Func _Memo($sMessage)
GUICtrlSetData($iMemo, $sMessage & @CRLF, 1)
EndFunc ;==>MemoWrite
Func __StringRepeat($sString, $iRepeat)
Local $sStr
For $i = 1 To $iRepeat Step 1
$sStr &= $sString
Next
Return $sStr
EndFunc
Alles anzeigen