Win7 Touchevents

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benni125
Beiträge: 14
Registriert: 05.04.2007 22:37

Win7 Touchevents

Beitrag von Benni125 »

Es hat mich viele Nerven gekostet bis hier hin zu kommen. Aber es ging voran. Ich habe es geschafft PureBasic davon zu überzeugen Touch-Events zu verstehen ^^. Es ist mehr als stümperhaft programmiert, aber was damit anfangen kann, darf es auch verbessern.

Code: Alles auswählen

InitSprite()
InitMouse()
#user32 = 10
#win32 = 20

;RegisterTouchWindowFlags
#TWF_FINETOUCH = $00000001
#TWF_WANTPALM = $00000002

;Events
#EventMultiTouch = $90000000
#EVENT_TOUCHSCREENHIT = $90000010

;Systemmetrics
#SM_DIGITIZER = 94
#SM_CXBORDER = 5
#SM_CXEDGE = 45
#SM_CYEDGE = 46
#SM_CYFIXEDFRAME = 8
#SM_CYSIZE = 31

#TABLET_CONFIG_NONE = $00000000

#NID_INTEGRATED_TOUCH = $00000001
#NID_EXTERNAL_TOUCH = $00000002
#NID_INTEGRATED_PEN = $00000004
#NID_EXTERNAL_PEN = $00000008
#NID_MULTI_INPUT = $00000040
#NID_READY = $00000080

#TOUCHEVENTF_MOVE = $0001
#TOUCHEVENTF_DOWN = $0002
#TOUCHEVENTF_UP = $0004
#TOUCHEVENTF_INRANGE = $0008
#TOUCHEVENTF_PRIMARY = $0010
#TOUCHEVENTF_NOCOALESCE = $00205
#TOUCHEVENTF_PALM = $0080
#TOUCHEVENTF_MOUSE = $0160
#TOUCHEVENTF_HIT = $0320

#TOUCHINPUTMASKF_CONTACTAREA = $0004
#TOUCHINPUTMASKF_EXTRAINFO = $0002
#TOUCHINPUTMASKF_TIMEFROMSYSTEM = $0001
#WM_TOUCH = $240


Structure TTouchPoint  
  x.l ;The x-coordinate (horizontal point) of the touch input. This member is indicated in hundredths of a pixel of physical screen coordinates.
  y.l ;The y-coordinate (vertical point) of the touch input. This member is indicated in hundredths of a pixel of physical screen coordinates.
  hSource.i ;A device handle for the source input device. Each device is given a unique provider at run time by the touch input provider.
  dwID.i ;A touch point identifier that distinguishes a particular touch input. This value stays consistent in a touch contact sequence from the point a contact comes down until it comes back up. An ID may be reused later for subsequent contacts.
  dwFlags.i ;A set of bit flags that specify various aspects of touch point press, release, and motion. The bits in this member can be any reasonable combination of the values in the Remarks section.
  dwMask.i ;A set of bit flags that specify which of the optional fields in the structure contain valid values. The availability of valid information in the optional fields is device-specific. Applications should use an optional field value only when the corresponding bit is set in dwMask. This field may contain a combination of the dwMask flags mentioned in the Remarks section.
  dwTime.i ;The time stamp for the event, in milliseconds. The consuming application should note that the system performs no validation on this field; when the TOUCHINPUTMASKF_TIMEFROMSYSTEM flag is not set, the accuracy and sequencing of values in this field are completely dependent on the touch input provider.
  dwExtraInfo.i ;An additional value associated with the touch event.
  cxContact.i ;The width of the touch contact area in hundredths of a pixel in physical screen coordinates. This value is only valid if the dwMask member has the TOUCHEVENTFMASK_CONTACTAREA flag set.
  cyContact.i ;The height of the touch contact area in hundredths of a pixel in physical screen coordinates. This value is only valid if the dwMask member has the TOUCHEVENTFMASK_CONTACTAREA flag set.
  ;lastX.i
  ;lastY.i
  ;speedX.f
  ;speedY.f
EndStructure 

Structure TTouchPointInfo
  lastX.i
  lastY.i
  speedX.f
  speedY.f
  active.b
EndStructure

Structure wRect
  left.l
  top.l
  right.l
  bottom.l
EndStructure

Procedure.l TOUCH_COORDS_TO_PIXEL(l.l)
  ProcedureReturn l / 100 
EndProcedure


Global Dim TouchPoints.TTouchPoint(10)
Global Dim TouchPointsInfo.TTouchPointInfo(10)
Global ActiveTouchPoints.i = 10
Global _t.TTouchPoint



OpenLibrary(#win32, "user32.dll")

Prototype.l GetTouchInputInfo(hwnd.l, cInputs.i, *p.TTouchPoint, cbsize.i)
Prototype.l GetSystemMetrics(nIndex.l)
Prototype.l GetWindowRect(hwnd.i, *r.wRect)
Prototype.l RegisterTouchWindow(hwnd.i, uFlags.i)
Prototype.l UnregisterTouchWindow(hwnd.i)
Prototype.l IsTouchWindow(hwnd.i, uFlags.i)
Prototype.l CloseTouchInputHandle(hTouchInput.i)
Prototype.l CallWindowProc(proc, wnd.l, MSG.i, wParam.i, lParam.i)

ExamineLibraryFunctions(#win32)

Global GetTouchInputInfo.GetTouchInputInfo = GetFunction(#win32, "GetTouchInputInfo")
Global GetSystemMetrics.GetSystemMetrics = GetFunction(#win32, "GetSystemMetrics")
Global GetWindowRect.GetWindowRect = GetFunction(#win32, "GetWindowRect")
Global RegisterTouchWindow.RegisterTouchWindow = GetFunction(#win32, "RegisterTouchWindow")
Global UnregisterTouchWindow.UnregisterTouchWindow = GetFunction(#win32, "UnregisterTouchWindow")
Global IsTouchWindow.IsTouchWindow = GetFunction(#win32, "IsTouchWindow")
Global CloseTouchInputHandle.CloseTouchInputHandle = GetFunction(#win32, "CloseTouchInputHandle")
Global CallWindowProc.CallWindowProc = GetFunction(#win32, "CallWindowProcA")

Procedure TTouchPointInit(*t.TTouchPoint)

EndProcedure 

Procedure TTouchPointUpdate(*t.TTouchPoint)

EndProcedure 

Procedure TouchGetXSpeed(*t.TTouchPoint)

EndProcedure 

Procedure TouchGetYSpeed(*t.TTouchPoint)

EndProcedure 

Procedure TouchMoveFlags(*t.TTouchPoint)
 ProcedureReturn (*t\dwFlags & #TOUCHEVENTF_MOVE) > 0 
EndProcedure 

Procedure TouchFlagInRange(*t.TTouchPoint)
  ProcedureReturn (*t\dwFlags & #TOUCHEVENTF_INRANGE) > 0 
EndProcedure 

Procedure TouchFlagPrimary(*t.TTouchPoint)
  ProcedureReturn (*t\dwFlags & #TOUCHEVENTF_PRIMARY) > 0   
EndProcedure 

Procedure TouchFlagNotCoalesce(*t.TTouchPoint)
  ProcedureReturn (*t\dwFlags & #TOUCHEVENTF_NOCOALESCE) > 0   
EndProcedure 

Procedure TouchFlagPalm(*t.TTouchPoint)
  ProcedureReturn (*t\dwFlags & #TOUCHEVENTF_Palm) > 0   
EndProcedure 

Procedure TouchFlagHit(*t.TTouchPoint)
  ProcedureReturn (*t\dwFlags & #TOUCHEVENTF_Hit) > 0   
EndProcedure 

Procedure TouchMaskContactArea(*t.TTouchPoint)
  ProcedureReturn (*t\dwMask & #TOUCHINPUTMASKF_CONTACTAREA) > 0 
EndProcedure 

Procedure TouchMaskExtraInfo(*t.TTouchPoint)
  ProcedureReturn (*t\dwMask & #TOUCHINPUTMASKF_EXTRAINFO) > 0 
EndProcedure 

Procedure TouchMaskTimeFromSystem(*t.TTouchPoint)
  ProcedureReturn (*t\dwMask & #TOUCHINPUTMASKF_TIMEFROMSYSTEM) > 0 
EndProcedure 

Procedure TouchDeinit(hwnd.i)
  If(UnregisterTouchWindow(hwnd))
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf 
EndProcedure 

Procedure TouchInit(hwnd.i, IncludeTouchHit.b = #True, Flags.i = 0)
  TouchDeinit(hwnd)  
  If(RegisterTouchWindow(hwnd, Flags))
    ProcedureReturn #True 
  Else
    ProcedureReturn #False
  EndIf 
  _t\dwMask = #TOUCHINPUTMASKF_CONTACTAREA
  For i = 0 To (ActiveTouchPoints - 1)
    TouchPoints(i)\dwMask = #TOUCHINPUTMASKF_CONTACTAREA
    ;TouchPoints(i)\dwExtraInfo = 1
  Next 
EndProcedure 

Procedure GetVisualPosX(hwnd_ressource.i, x.l)
  clRect.wRect
  xmax = WindowWidth(hwnd_ressource)
  GetWindowRect(WindowID(hwnd_ressource), @clRect)
  x = x-(0.5*((clRect\right - clRect\left) - xmax) + clRect\left)-GetSystemMetrics(#SM_CXBORDER)
  If(x < 0)
    x = 0
  ElseIf x > xmax
    x = xmax
  EndIf
  ProcedureReturn x
  
EndProcedure 

Procedure GetVisualPosY(hwnd_ressource.i, y.l)
  clRect.wRect
  ymax = WindowHeight(hwnd_ressource)
  GetWindowRect(WindowID(hwnd_ressource), @clRect)
  y = y-(0.5*((clRect\bottom - clRect\top) - ymax) + clRect\top)-GetSystemMetrics(#SM_CYSIZE)
  If(y < 0)
    y = 0
  ElseIf y > ymax
    y = ymax
  EndIf
  ProcedureReturn y
EndProcedure 

Procedure _wndCallback(hwnd.i, msg.i, wp.i, lp.i)
  TouchPoints = #Null
  ;Debug "wp: "+Str(wp)
  ;Debug "lp: "+Str(lp)
  ;Debug "Size: "+Str(SizeOf(TTouchPoint))
  _event = msg
  Select msg
    Case #WM_TOUCH
      ActiveTouchPoints = wp
        
      Dim ltouch.TTouchPoint(wp)
      For i= 0 To ActiveTouchPoints
        ltouch(i) = TouchPoints(i)
      Next
      *ptr.l = @ltouch()
      v.l = GetTouchInputInfo(lp, wp, *ptr, 40) 
      
      For i= 0 To ActiveTouchPoints-1
        TouchPointsInfo(i)\speedX = TouchPoints(i)\x - TouchPointsInfo(i)\lastX
        TouchPointsInfo(i)\speedY = TouchPoints(i)\y -TouchPointsInfo(i)\lastY
        TouchPointsInfo(i)\lastX = TouchPoints(i)\x
        TouchPointsInfo(i)\lastY = TouchPoints(i)\y
        TouchPoints(i) = ltouch(i)
        If(TouchPoints(i)\dwFlags&#TOUCHEVENTF_Hit)
          TouchPoints(i)\dwTime = ElapsedMilliseconds()
          TouchPoints(i)\dwMask = #TOUCHINPUTMASKF_TIMEFROMSYSTEM
          TouchPoints(i)\dwExtraInfo = 1
          TouchPointsInfo(i)\active = ~TouchPoints(i)\dwFlags & #TOUCHEVENTF_UP
          If(TouchPointsInfo(i)\active > 0)
            TouchPointsInfo(i)\active =#True
          EndIf
        EndIf
        If(TouchPointsInfo(i)\active = #True)
          TouchPoints(i)\x = GetVisualPosX(0, TOUCH_COORDS_TO_PIXEL(ltouch(i)\x))
          TouchPoints(i)\y = GetVisualPosY(0, TOUCH_COORDS_TO_PIXEL(ltouch(i)\y))
          Debug "cx: "+Str(TouchPoints(i)\cxContact)
        EndIf 
        Debug TouchPointsInfo(i)\active
      Next
  EndSelect 
  CloseTouchInputHandle(lp)
  
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure 

OpenWindow(0, 0, 0, 640, 480, "")

val.i = TouchInit(WindowID(0), #TWF_FINETOUCH)

SetWindowCallback(@_wndCallback())
img = CreateImage(#PB_Any, 640, 480)
While (1)
  e = WindowEvent() 
  
  If(e = #PB_Event_CloseWindow)
    Break
  EndIf 
  StartDrawing(ImageOutput(img))
  Box(0, 0, 640, 480, RGB(0,0,0))
  DrawText(10, 10, "Points: "+Str(ActiveTouchPoints), RGB(255, 255, 255))
  If(ActiveTouchPoints > 0)
    For i = 0 To ActiveTouchPoints-1
      If(TouchPointsInfo(i)\active = #True)  
        DrawText(10, 50+(i*15), "Point X"+Str(i)+": "+Str(TouchPoints(i)\x))
        DrawText(110, 50+(i*15), "Point Y"+Str(i)+": "+Str(TouchPoints(i)\y))
        If(TouchPoints(i)\dwFlags&#TOUCHEVENTF_DOWN)
          Debug "down"
        EndIf
        If(TouchPoints(i)\dwFlags&#TOUCHEVENTF_HIT)
          Debug "hit"
        EndIf
        If(TouchPoints(i)\dwFlags&#TOUCHEVENTF_MOVE)
          Debug "move"
        EndIf
        If(TouchPoints(i)\dwFlags&#TOUCHEVENTF_UP)
          Debug "up"
        EndIf
        If(TouchPoints(i)\dwMask&#TOUCHINPUTMASKF_CONTACTAREA)
          Debug "hover"
        EndIf
      EndIf 
    Next 
  EndIf 
  StopDrawing()
  StartDrawing(WindowOutput(0))
  DrawImage(ImageID(img), 0 ,0)
  StopDrawing()
  Delay(10)
Wend 

End 
Hat jemand ne Ahnung wie es besser funktionieren kann?
Die wichtigste Funktion ist_wndCallback Da findet das entscheidende statt.

Grüße
Benjamin