Basic windows 8 touchscreen tap recognition

Post your working scripts, libraries and tools
fodakahn
Posts: 2
Joined: 04 Dec 2013, 18:16

Basic windows 8 touchscreen tap recognition

19 Jun 2014, 15:50

I spent quite a while figuring out how to do this :?
so maybe this will save someone time in the future.

the tricks were that you need to register it as a touch window with windows API RegisterTouchWindow(handle, 0) and the onmessage code for WM_Touch is 0x240

EDIT: Added GetTouchInfo for X, Y, etc.

Code: Select all

SysGet, swidth, 16
SysGet, sheight, 17


gui, add, button, gguiclose, EXIT
gui, add, text, w300 h300 vthetext, 
gui, show, w%swidth% h%sheight%, Touchscreen Test
WinGet, thishwnd, ID, Touchscreen Test
registerResult := dllcall("User32.dll\RegisterTouchWindow", Int, thishwnd, Int, 0)
msgbox, DLLCall error level is %errorlevel% (0 = success)
msgbox, Register Touch Window DllCall result is %registerResult% (nonzero = success)
OnMessage(0x240,"Touching")	;WM_TOUCH
return

Touching(wparam, lparam, msg, hwnd)
{
	global
	GetTouchInfo(wParam, lParam)
}

GetTouchInfo(wParam, lParam) 
{
	global
   Static TI_Size := (4 * 8) + (A_PtrSize * 2) ; Size of TOUCHINPUT
   Static OffX := 0
        , OffY := OffX + 4
        , OffSource := OffY + 4
        , OffID := OffSource + A_PtrSize
        , OffFlags := OffID + 4
        , OffMask := OffFlags + 4
        , OffTime := OffMask + 4
        , OffExtraInfo := OffTime + 4
        , OffContactW := OffExtraInfo + A_PtrSize
        , OffContactH := OffContactW + 4
   TI_Count := wParam & 0xFFFF ; The low-order word contains the number of touch points associated with this message.
   VarSetCapacity(TI_Array, TI_SIze * TI_Count, 0)
   If DllCall("User32.dll\GetTouchInputInfo", "Ptr", lParam
                                            , "UInt", TI_Count
                                            , "Ptr", &TI_Array
                                            , "Int", TI_Size
                                            , "UInt") {
      TI_Addr := &TI_Array
      Loop, % TI_Count {
         Msg := "TOUCHINPUT " . A_Index . " of " .TI_COunt
		 setformat, float, 0.0
         Msg .= "`nX: " . NumGet(TI_Addr + 0, OffX, "UInt")/100
         Msg .= "`nY: " . NumGet(TI_Addr + 0, OffY, "UInt")/100
         Msg .= "`nSource: " . NumGet(TI_Addr + 0, OffSource, "UPtr")
         Msg .= "`nID: " . NumGet(TI_Addr + 0, OffID, "UInt")
         Msg .= "`nFlags: " . NumGet(TI_Addr + 0, OffFlags, "UInt")
         Msg .= "`nMask: " . NumGet(TI_Addr + 0, OffMask, "UInt")
         Msg .= "`nTime: " . NumGet(TI_Addr + 0, OffTime, "UInt")
         Msg .= "`nExtraInfo: " . NumGet(TI_Addr + 0, OffExtraInfo, "UPtr")
         Msg .= "`nContactW: " . NumGet(TI_Addr + 0, OffContactW, "UInt")
         Msg .= "`nContactH: " . NumGet(TI_Addr + 0, OffContactH, "UInt")
		 guicontrol, text, thetext, %msg%
         TI_Addr += TI_Size
      }
   }
}

GuiClose:
ExitApp
Last edited by fodakahn on 10 Sep 2014, 14:09, edited 2 times in total.
drabne
Posts: 22
Joined: 17 Feb 2014, 02:26

Re: Basic windows 8 touchscreen tap recognition

20 Jun 2014, 02:14

Nice, the sample code works well. Will we be able to add touch actions to other (non ahk GUI) windows using this method? I tried replacing "touchscreen tap test" in the WinGet row to some other windows but then registerResult was 0 and nothing happens.
arcticir
Posts: 578
Joined: 17 Nov 2013, 11:32

Re: Basic windows 8 touchscreen tap recognition

07 Jul 2014, 02:27

How to get information from "lparam" it? :(
User avatar
joedf
Posts: 7238
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada
Contact:

Re: Basic windows 8 touchscreen tap recognition

07 Jul 2014, 03:43

Cool!
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500 @ 4.00 GHz, 2x8GB DDR4 3143 MHz, NVIDIA GTX 1060 6GB | [About Me] | [ASPDM - StdLib Distribution]
[Populate the AHK MiniCity!] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library] | [About the AHK Foundation]
just me
Posts: 6485
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Basic windows 8 touchscreen tap recognition

07 Jul 2014, 06:38

arcticir wrote:How to get information from "lparam" it? :o
WM_TOUCH
GetTouchInputInfo

Code: Select all

; ...
; ...
; ...
On_WM_TOUCH(wParam, lParam) {
   GetTouchInfo(wParam, lParam)
}
; ...
; ...
; ...
GetTouchInfo(wParam, lParam) {
   Static TI_Size := (4 * 8) + (A_PtrSize * 2) ; Size of TOUCHINPUT
   Static OffX := 0
        , OffY := OffX + 4
        , OffSource := OffY + 4
        , OffID := OffSource + A_PtrSize
        , OffFlags := OffID + 4
        , OffMask := OffFlags + 4
        , OffTime := OffMask + 4
        , OffExtraInfo := OffTime + 4
        , OffContactW := OffExtraInfo + A_PtrSize
        , OffContactH := OffContactW + 4
   TI_Count := wParam & 0xFFFF ; The low-order word contains the number of touch points associated with this message.
   VarSetCapacity(TI_Array, TI_SIze * TI_Count, 0)
   If DllCall("User32.dll\GetTouchInputInfo", "Ptr", lParam
                                            , "UInt", TI_Count
                                            , "Ptr", &TI_Array
                                            , "Int", TI_Size
                                            , "UInt") {
      TI_Addr := &TI_Array
      Loop, % TI_Count {
         Msg := "TOUCHINPUT " . A_Index . " of " .TI_COunt
         Msg .= "`nX: " . NumGet(TI_Addr + 0, OffX, "UInt")
         Msg .= "`nY: " . NumGet(TI_Addr + 0, OffY, "UInt")
         Msg .= "`nSource: " . NumGet(TI_Addr + 0, OffSource, "UPtr")
         Msg .= "`nID: " . NumGet(TI_Addr + 0, OffID, "UInt")
         Msg .= "`nFlags: " . NumGet(TI_Addr + 0, OffFlags, "UInt")
         Msg .= "`nMask: " . NumGet(TI_Addr + 0, OffMask, "UInt")
         Msg .= "`nTime: " . NumGet(TI_Addr + 0, OffTime, "UInt")
         Msg .= "`nExtraInfo: " . NumGet(TI_Addr + 0, OffExtraInfo, "UPtr")
         Msg .= "`nContactW: " . NumGet(TI_Addr + 0, OffContactW, "UInt")
         Msg .= "`nContactH: " . NumGet(TI_Addr + 0, OffContactH, "UInt")
         MsgBox, 0, %A_ThisFunc%, %Msg%
         TI_Addr += TI_Size
      }
   }
   Else
      MsgBox, 16, %A_ThisFunc%, Error: %ErrorLevel% - %A_LastError%
}
I cannot test it, maybe you want to do it?
arcticir
Posts: 578
Joined: 17 Nov 2013, 11:32

Re: Basic windows 8 touchscreen tap recognition

07 Jul 2014, 08:20

Thanks.

Perfect operation!

I wanted to write a Touch Gesture,
can use the touch screen to control desktop software.

Since 0x240 not global, it can only create a transparent GUI.

Code: Select all

SetBatchLines -1
Gui  +LastFound +AlwaysOnTop +E0x8000000 -Caption +ToolWindow +hwndhwnd
gui,show,NoActivate NA x0 y0 w%A_ScreenWidth% h%A_ScreenHeight%
WinSet, Transparent,1
Touch:=dllcall("User32.dll\RegisterTouchWindow",Int,hwnd,Int,0)
onmessage(0x240,"On_WM_TOUCH")
return

guiclose:
exitapp
Return


On_WM_TOUCH(wParam, lParam) {
	GetTouchInfo(wParam, lParam)
}


GetTouchInfo(wParam, lParam) {
   Static TI_Size := (4 * 8) + (A_PtrSize * 2) ; Size of TOUCHINPUT
   Static OffX := 0
        , OffY := OffX + 4
        , OffSource := OffY + 4
        , OffID := OffSource + A_PtrSize
        , OffFlags := OffID + 4
        , OffMask := OffFlags + 4
        , OffTime := OffMask + 4
        , OffExtraInfo := OffTime + 4
        , OffContactW := OffExtraInfo + A_PtrSize
        , OffContactH := OffContactW + 4

   TI_Count := wParam & 0xFFFF ; The low-order word contains the number of touch points associated with this message.
   VarSetCapacity(TI_Array, TI_SIze * TI_Count, 0)
   If DllCall("User32.dll\GetTouchInputInfo", "Ptr", lParam
                                            , "UInt", TI_Count
                                            , "Ptr", &TI_Array
                                            , "Int", TI_Size
                                            , "UInt") {
      TI_Addr := &TI_Array

      Loop, % TI_Count {
         Msg := "TOUCHINPUT " . A_Index . " of " .TI_COunt
         Msg .= "`nX: " . NumGet(TI_Addr + 0, OffX, "UInt")
         Msg .= "`nY: " . NumGet(TI_Addr + 0, OffY, "UInt")
         Msg .= "`nSource: " . NumGet(TI_Addr + 0, OffSource, "UPtr")
         Msg .= "`nID: " . NumGet(TI_Addr + 0, OffID, "UInt")
         Msg .= "`nFlags: " . NumGet(TI_Addr + 0, OffFlags, "UInt")
         Msg .= "`nMask: " . NumGet(TI_Addr + 0, OffMask, "UInt")
         Msg .= "`nTime: " . NumGet(TI_Addr + 0, OffTime, "UInt")
         Msg .= "`nExtraInfo: " . NumGet(TI_Addr + 0, OffExtraInfo, "UPtr")
         Msg .= "`nContactW: " . NumGet(TI_Addr + 0, OffContactW, "UInt")
         Msg .= "`nContactH: " . NumGet(TI_Addr + 0, OffContactH, "UInt")
         MsgBox, 0, %A_ThisFunc%, %Msg%
         TI_Addr += TI_Size
      }
   }
   Else
      MsgBox, 16, %A_ThisFunc%, Error: %ErrorLevel% - %A_LastError%
}
arcticir
Posts: 578
Joined: 17 Nov 2013, 11:32

Re: Basic windows 8 touchscreen tap recognition

07 Jul 2014, 09:34

@just me

you Whether can help me check Flags correct?
It results that only "25" AND "26" two,
while the right should be the following:

Code: Select all

TOUCHEVENTF_MOVE	0x0001	Movement has occurred. Cannot be combined with TOUCHEVENTF_DOWN.

TOUCHEVENTF_DOWN	0x0002	The corresponding touch point was established through a new contact. Cannot be combined with TOUCHEVENTF_MOVE or TOUCHEVENTF_UP.

TOUCHEVENTF_UP	0x0004	A touch point was removed.

TOUCHEVENTF_INRANGE	0x0008	A touch point is in range. This flag is used to enable touch hover support on compatible hardware. Applications that do not want support for hover can ignore this flag.

TOUCHEVENTF_PRIMARY	0x0010	Indicates that this TOUCHINPUT structure corresponds to a primary contact point. See the following text for more information on primary touch points.

TOUCHEVENTF_NOCOALESCE	0x0020	When received using GetTouchInputInfo, this input was not coalesced.

TOUCHEVENTF_PALM	0x0080	The touch event came from the user's palm.

Thanks.
just me
Posts: 6485
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Basic windows 8 touchscreen tap recognition

07 Jul 2014, 10:13

As I said, I cannot test touch input. But maybe the MsgBox is not the best choice to report informations. You might try to change the ouput to ToolTip.

25 = TOUCHEVENTF_PRIMARY (16) + TOUCHEVENTF_INRANGE (8) + TOUCHEVENTF_MOVE (1)
26 = TOUCHEVENTF_PRIMARY (16) + TOUCHEVENTF_INRANGE (8) + TOUCHEVENTF_DOWN (2)
arcticir
Posts: 578
Joined: 17 Nov 2013, 11:32

Re: Basic windows 8 touchscreen tap recognition

07 Jul 2014, 10:45

Understanding. Thank you very much.




Almost solve all the problems, the only problem:
TOUCHEVENTF_UP 0x0004 No feedback.

Welcome to Test:

Code: Select all

SetBatchLines -1
Gui  +LastFound +AlwaysOnTop +E0x8000000 -Caption +ToolWindow +hwndhwnd
WinSet, Transparent,1
gui,show,NoActivate NA x0 y0 w%A_ScreenWidth% h%A_ScreenHeight%

Touch:=dllcall("User32.dll\RegisterTouchWindow",Int,hwnd,Int,0)
onmessage(0x240,"GetTouchInfo")
return


GetTouchInfo(wParam, lParam) {
   Static TI_Size := (4 * 8) + (A_PtrSize * 2) ; Size of TOUCHINPUT
   Static OffX := 0
        , OffY := OffX + 4
        , OffSource := OffY + 4
        , OffID := OffSource + A_PtrSize
        , OffFlags := OffID + 4
        , OffMask := OffFlags + 4
        , OffTime := OffMask + 4
        , OffExtraInfo := OffTime + 4
        , OffContactW := OffExtraInfo + A_PtrSize
        , OffContactH := OffContactW + 4

   TI_Count := wParam & 0xFFFF ; The low-order word contains the number of touch points associated with this message.

   VarSetCapacity(TI_Array, TI_SIze * TI_Count, 0)
   If DllCall("User32.dll\GetTouchInputInfo", "Ptr", lParam
                                            , "UInt", TI_Count
                                            , "Ptr", &TI_Array
                                            , "Int", TI_Size
                                            , "UInt") {
      TI_Addr := &TI_Array


      Loop, % TI_Count {
         ToolTip,% Msg := "TOUCHINPUT " . A_Index . " of " .TI_COunt
         . "`nX: " . NumGet(TI_Addr + 0, OffX, "UInt")//100
         . "`nY: " . NumGet(TI_Addr + 0, OffY, "UInt")//100
         . "`nSource: " . NumGet(TI_Addr + 0, OffSource, "UPtr")
         . "`nID: " . NumGet(TI_Addr + 0, OffID, "UInt")
         . "`nFlags: " . NumGet(TI_Addr + 0, OffFlags, "UInt")
         . "`nMask: " . NumGet(TI_Addr + 0, OffMask, "UInt")
         . "`nTime: " . NumGet(TI_Addr + 0, OffTime, "UInt")
         . "`nExtraInfo: " . NumGet(TI_Addr + 0, OffExtraInfo, "UPtr")
         . "`nContactW: " . NumGet(TI_Addr + 0, OffContactW, "UInt")
         . "`nContactH: " . NumGet(TI_Addr + 0, OffContactH, "UInt")

         TI_Addr += TI_Size
      }
   }
   Else
      MsgBox, 16, %A_ThisFunc%, Error: %ErrorLevel% - %A_LastError%
}

guiclose:
	exitapp
	Return
arcticir
Posts: 578
Joined: 17 Nov 2013, 11:32

Re: Basic windows 8 touchscreen tap recognition

08 Jul 2014, 23:24

I found the section on TOUCHEVENTF_UP code.
it uses a different method to determine whether there is TOUCHEVENTF_UP
I ask, AHK should ask how to do?

Code: Select all

C++

case WM_TOUCH:

{

    // A WM_TOUCH message can contain several messages from different contacts

   // packed together.

    unsigned int numInputs = (int) wParam; //Number of actual contact messages

    TOUCHINPUT* ti = new TOUCHINPUT[numInputs]; // Allocate the storage for

                                               //the parameters of the per-

                                              //contact messages

            

    // Unpack message parameters into the array of TOUCHINPUT structures, each

   // representing a message for one single contact.

    if (GetTouchInputInfo((HTOUCHINPUT)lParam, numInputs, ti,

                                                         sizeof(TOUCHINPUT)))

    {

        // For each contact, dispatch the message to the appropriate message

       // handler.

        for(unsigned int i=0; i<numInputs; ++i)

        {

            if (ti[i].dwFlags & TOUCHEVENTF_DOWN)

            {

                OnTouchDownHandler(hWnd, ti[i]);

            }

            else if (ti[i].dwFlags & TOUCHEVENTF_MOVE)

            {

                OnTouchMoveHandler(hWnd, ti[i]);

            }

            else if (ti[i].dwFlags & TOUCHEVENTF_UP)

            {

                OnTouchUpHandler(hWnd, ti[i]);

            }

        }

    }

    CloseTouchInputHandle((HTOUCHINPUT)lParam);

    delete [] ti;

}

break;


Code: Select all

C++  (Extracted from WinUser.h)

typedef struct tagTOUCHINPUT {

    LONG x;

    LONG y;

    HANDLE hSource;

    DWORD dwID;

    DWORD dwFlags;

    DWORD dwMask;

    DWORD dwTime;

    ULONG_PTR dwExtraInfo;

    DWORD cxContact;

    DWORD cyContact;

} TOUCHINPUT, *PTOUCHINPUT;

typedef TOUCHINPUT const * PCTOUCHINPUT;


/*

 * Conversion of touch input coordinates to pixels

 */

#define TOUCH_COORD_TO_PIXEL(l)         ((l) / 100)


/*

 * Touch input flag values (TOUCHINPUT.dwFlags)

 */

#define TOUCHEVENTF_MOVE            0x0001

#define TOUCHEVENTF_DOWN            0x0002

#define TOUCHEVENTF_UP              0x0004
just me
Posts: 6485
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Basic windows 8 touchscreen tap recognition

09 Jul 2014, 12:52

You might try this one which is using the methods of your C++ code, as always I couldn't test it:

Code: Select all

#NoEnv
SetBatchLines -1
Global Report := ""
SysGet, WA, MonitorWorkArea
X := WALeft
Y := WATop
W := WARight - WALeft
H := WABottom - WATop
Gui, Main:New, +LastFound +AlwaysOnTop +E0x8000000 -Caption +ToolWindow +hwndHGUI +LabelMain
WinSet, Transparent, 1
Gui, Show, NA x%X% y%Y% w%W% h%H%
If DllCall("User32.dll\RegisterTouchWindow", "Ptr", HGUI, "UInt", 0, "UInt")
   OnMessage(0x240, "OnTouch") ; 0x0240 = WM_TOUCH
Else
   MsgBox, 16, Error!, RegisterTouchWindow failed!
Return
; ----------------------------------------------------------------------------------------------------------------------
MainClose:
   DllCall("User32.dll\UnregisterTouchWindow", "Ptr", HGUI)
   Gui, Destroy
ExitApp
; ======================================================================================================================
; This hotkey will show the results gathered in OnTouch()
^+s::
   GoSub, ShowReport
Return
; ======================================================================================================================
ShowReport:
Gui, Report:New, +LabelReport +OwnerMain
Gui, Add, Edit, w600 r20, %Report%
Gui, Show, , Report
Return
ReportClose:
ReportEscape:
   Gui, Destroy
Return
; ----------------------------------------------------------------------------------------------------------------------
OnTouch(wParam, lParam) {
   Static TI_Size := (4 * 8) + (A_PtrSize * 2) ; Size of TOUCHINPUT
   Static OffX := 0
        , OffY := OffX + 4
        , OffHSource := OffY + 4
        , OffID := OffHSource + A_PtrSize
        , OffFlags := OffID + 4
        , OffMask := OffFlags + 4
        , OffTime := OffMask + 4
        , OffExtraInfo := OffTime + 4
        , OffW := OffExtraInfo + A_PtrSize
        , OffH := OffW + 4
   Static TOUCHEVENT_DOWN := 0x0002
        , TOUCHEVENT_MOVE := 0x0001
        , TOUCHEVENT_UP   := 0x0004
   ; A WM_TOUCH message can contain several messages from different contacts packed together.
   ; The low-order word of wParam contains the number of touch points associated with this message.
   TI_Count := wParam & 0xFFFF
   ; Allocate the storage for the parameters of the per-contact messages.
   VarSetCapacity(TI_Array, TI_SIze * TI_Count, 0)
   ; Unpack message parameters into the array of TOUCHINPUT structures, each representing a message
   ; for one single contact.
   If DllCall("User32.dll\GetTouchInputInfo", "Ptr", lParam
                                            , "UInt", TI_Count
                                            , "Ptr", &TI_Array
                                            , "Int", TI_Size
                                            , "UInt") {
      ; For each contact, inspect the message.
      TI_Addr := &TI_Array
      Loop, % TI_Count {
         Flags := NumGet(TI_Addr + 0, OffFlags, "UInt")
         Time  := NumGet(TI_Addr + 0, OffTime, "UInt")
         If (Flags & TOUCHEVENT_DOWN)
            Report .= Time . " -> TOUCHEVENT_DOWN"
         Else If (Flags & TOUCHEVENT_MOVE)
            Report .= Time . " -> TOUCHEVENT_MOVE"
         Else If (Flags & TOUCHEVENT_UP)
            Report .= Time . " -> TOUCHEVENT_UP"
         Else
            Report := Time . " -> " . Flags . " ???"
         TI_Addr += TI_Size
      }
      DllCall("User32.dll\CloseTouchInputHandle", "Ptr", lParam)
   }
   Else
      MsgBox, 16, %A_ThisFunc%, Error: %ErrorLevel% - %A_LastError%
}
arcticir
Posts: 578
Joined: 17 Nov 2013, 11:32

Re: Basic windows 8 touchscreen tap recognition

10 Jul 2014, 08:52

Perfect. Everything is normal. :D
received Touch UP.
But because AHK performance limitations, I have to use AHKH, in order to receive all.

Code: Select all

/*	
[hy]
Content=1
key=Volume_Down up
Limit=1
[c]
; Based AHKH  script console Hydrangea
*/  
	Global Touch:=CriticalObject(),ZTAssistant
	sysget, PM_x, 76
	sysget, PM_y, 77
	sysget, PM_w, 78
	sysget, PM_h, 79
	Gui, Main:New, +LastFound +AlwaysOnTop +E0x8000000 -Caption +ToolWindow +hwndHGUI +LabelMain
	WinSet, Transparent, 1
	Gui, Show, % "NA x" PM_x  " y" PM_y  " w" PM_w " h" PM_h
	If DllCall("User32.dll\RegisterTouchWindow", "Ptr", Touch.GUI:=HGUI, "UInt", 0, "UInt")
		OnMessage(0x240,HGUI, "OnTouch")  ; 0x0240 = WM_TOUCH ;  AHKH Improve OnMessage
	Else
		{
		MsgBox, 16, Error!, RegisterTouchWindow failed!
		Gosub MainClose
		}

	Z_Lion("ZTouchDrum",,,"ZTouchDrum",CriticalObject(Touch,1), CriticalObject(Touch,2))
	ZTDrum:=sh["ZTouchDrum"]

	Z_Lion("ZTouchAssistant",,,"ZTouchAssistant",CriticalObject(Touch,1), CriticalObject(Touch,2))
	ZTAssistant:=sh["ZTouchAssistant"]
Return

Volume_Down::
	if !VolumeTime
		VolumeTime := A_TickCount
Return

Volume_Down up::
	if (A_TickCount - VolumeTime < 500)
	{
		VolumeTime:=""
		if Hide
		{     
			Show:            
			WinSet, Transparent, 1, % "AHK_ID " Touch.GUI  
			Z_Status("Touch Show",15,"Touch")
			Hide:=0
			Return
		}
		else    
		{
			Hide:
			WinSet, Transparent, 0, % "AHK_ID " Touch.GUI
			Z_Status("Touch Hide",15,"Touch")             
			Hide:=1
			Return
		}      
	}
	else
	{
		Z_Status("Touch Close",15,"Touch")
		Gosub MainClose
	}

Return

; ----------------------------------------------------------------------------------------------------------------------
MainClose:
	ZTDrum.ahkTerminate()
	ZTAssistant.ahkTerminate()
	DllCall("User32.dll\UnregisterTouchWindow", "Ptr", HGUI)
	Gui, Destroy
ExitApp


; ----------------------------------------------------------------------------------------------------------------------
OnTouch(wParam, lParam) {
	Static TI_Size := (4 * 8) + (A_PtrSize * 2) ; Size of TOUCHINPUT
	Static OffX := 0
		, OffY := OffX + 4
		, OffHSource := OffY + 4
		, OffID := OffHSource + A_PtrSize
		, OffFlags := OffID + 4
		, OffMask := OffFlags + 4
		, OffTime := OffMask + 4
		, OffExtraInfo := OffTime + 4
		, OffW := OffExtraInfo + A_PtrSize   
		, OffH := OffW + 4
	Static TOUCHEVENT_DOWN := 0x0002
		, TOUCHEVENT_MOVE := 0x0001
		, TOUCHEVENT_UP   := 0x0004

	; A WM_TOUCH message can contain several messages from different contacts packed together.
	; The low-order word of wParam contains the number of touch points associated with this message.
	TI_Count := wParam & 0xFFFF
	; Allocate the storage for the parameters of the per-contact messages.
	VarSetCapacity(TI_Array, TI_SIze * TI_Count, 0)
	; Unpack message parameters into the array of TOUCHINPUT structures, each representing a message
	; for one single contact.
	If DllCall("User32.dll\GetTouchInputInfo", "Ptr", lParam
			, "UInt", TI_Count
			, "Ptr", TI_Addr :=&TI_Array
			, "Int", TI_Size
			, "UInt"){
		Loop, % TI_Count 
			{
			x:= NumGet(TI_Addr + 0, OffX, "UInt")//100
				,y:= NumGet(TI_Addr + 0, OffY, "UInt")//100
					; Source:= NumGet(TI_Addr + 0, OffSource, "UPtr")
				,id:= NumGet(TI_Addr + 0, OffID, "UInt")
				,Flags:= NumGet(TI_Addr + 0, OffFlags, "UInt")
					; Mask:= NumGet(TI_Addr + 0, OffMask, "UInt")
				,Time:= NumGet(TI_Addr + 0, OffTime, "UInt")
					; ExtraInfo:= NumGet(TI_Addr + 0, OffExtraInfo, "UPtr")
					; ContactW:= NumGet(TI_Addr + 0, OffContactW, "UInt")
					; ContactH:= NumGet(TI_Addr + 0, OffContactH, "UInt")
				, ((Flags & TOUCHEVENT_MOVE)
					? (Touch["_" id]["Flags"].Insert([x,y,Time]),Touch.ji ? "": ZTAssistant.ahkPostFunction("MOVE","_" id))
					: (Flags & TOUCHEVENT_DOWN)
						? ZTAssistant.ahkFunction("DOWN","_" id,x,y,Time)
						: (Flags & TOUCHEVENT_UP)
							?(Touch["_" id]["Flags"].Insert([x,y,Time,1]),Touch.ji?"": ZTAssistant.ahkPostFunction("MOVE","_" id))
						:"")
				,TI_Addr += TI_Size
			}
		DllCall("User32.dll\CloseTouchInputHandle", "Ptr", lParam)
		}
}

Thank you very much!
arcticir
Posts: 578
Joined: 17 Nov 2013, 11:32

Re: Basic windows 8 touchscreen tap recognition

17 Aug 2014, 09:07

@just me
Sorry to bother you, I assure you seek help.
I found the touch screen monitor global events, but I will not parse WM_INPUT RAWHID, can you help me resolve it?
I want to get "Down", "move", "Up",x,y And number of fingers.

Code: Select all

OnMessage(0xFF, "WM_INPUT")
RegisterRawInputDevices(0) ;Listener
Return 
f1::  RegisterRawInputDevices(1) ;Stop listening
f2:: 
ExitApp


WM_INPUT(wParam, lParam, msg, hwnd)
{  ;From http://39kasen.sakura.ne.jp/rawinputcontroltest/
	static RAWINPUTHEADER_Size :=8 + A_PtrSize * 2

	Critical

	;------------------------------------------- Reference: GetRawInputData function
	;	UINT WINAPI GetRawInputData(
	;	  __in       HRAWINPUT hRawInput,
	;	  __in       UINT uiCommand,
	;	  __out_opt  LPVOID pData,
	;	  __inout    PUINT pcbSize,
	;	  __in       UINT cbSizeHeader
	;	)
;http://msdn.microsoft.com/en-us/library/ms645562

	;-------------------------------------------
	; Get size of RAWINPUT data.
	ret := DllCall("GetRawInputData", "Ptr", lParam, "UInt", 0x10000003
	               , "Ptr", 0, "UInt*", cbSize, "UInt", RAWINPUTHEADER_Size)
	If (ret) {
		Return
	}
	VarSetCapacity(RawInputData, cbSize, 0)
	; Get RAWINPUT data.
	ret := DllCall("GetRawInputData", "Ptr", lParam, "UInt", 0x10000003
	               , "Str", RawInputData, "UInt*", cbSize, "UInt", RAWINPUTHEADER_Size)
	;------------------------------------------- Reference: RAWINPUT structure
	;	typedef struct tagRAWINPUT {
	;	  RAWINPUTHEADER header;
	;	  union {
	;	    RAWMOUSE    mouse;
	;	    RAWKEYBOARD keyboard;
	;	    RAWHID      hid;
	;	  } data;
	;	} RAWINPUT, *PRAWINPUT, *LPRAWINPUT;
	;------------------------------------------- Reference: RAWINPUTHEADER structure
	;	typedef struct tagRAWINPUTHEADER {
	;	  DWORD  dwType;
	;	  DWORD  dwSize;
	;	  HANDLE hDevice;
	;	  WPARAM wParam;
	;	} RAWINPUTHEADER, *PRAWINPUTHEADER;


	;------- Reference: RAWHID structure
	;	typedef struct tagRAWHID {
	;	  DWORD dwSizeHid;
	;	  DWORD dwCount;              
	;	  BYTE  bRawData[1];
	;	} RAWHID, *PRAWHID, *LPRAWHID;
	; http://msdn.microsoft.com/en-us/library/ms645549
	raw_stat := NumGet(RawInputData, RAWINPUTHEADER_Size + 8 + 1, "UChar") - 127
	raw_x := NumGet(RawInputData, RAWINPUTHEADER_Size + 8 + 2, "UShort")
	raw_y := NumGet(RawInputData, RAWINPUTHEADER_Size + 8 + 4, "UShort")
	ToolTip,% raw_x " " raw_y ,222,222
	; process WM_INPUT messages in new thread (To reduce dropping messages)
	If (Mod(raw_stat, 4) == 0) {
		TouchReleaseMessagePosted ++
		PostMessage, 0x1001, raw_stat, raw_x | (raw_y << 16),, ahk_id %hwnd%
	}
	Else
		PostMessage, 0x1000, raw_stat, raw_x | (raw_y << 16),, ahk_id %hwnd%
	Return 0
}

RegisterRawInputDevices(f){
	static a,b,c:=(VarSetCapacity(a,8+A_PtrSize),NumPut(13,a,0,"UShort"),NumPut(4,a,2,"UShort")
		,NumPut(0x00000100,a,4,"UInt"),NumPut(A_ScriptHWND,a,8,"UPtr")
		,VarSetCapacity(b,8+A_PtrSize),NumPut(13,b,0,"UShort"),NumPut(4,b,2,"UShort")
		,NumPut(0x00000001,b,4,"UInt"),NumPut(0,b,8,"UPtr")),i:=&a,n:=&b
	DllCall("RegisterRawInputDevices", "Ptr",  f?n:i, "UInt", 1, "UInt", 8 + A_PtrSize)
	}
lblb
Posts: 129
Joined: 30 Sep 2013, 11:31

Re: Basic windows 8 touchscreen tap recognition

17 Aug 2014, 15:34

Hi arcticir,

I think most of what you are trying to do is included in the script that has been posted here (see the "here" link at the top of the page for the most recent version):
http://39kasen.sakura.ne.jp/rawinputcontroltest/

This is an on-screen keyboard that can be easily customized. Importantly, it makes heavy use of Windows Touch functions. On Windows 7, you are able to turn off touch using normal Windows commands and still use this script with touch input!

This script has proven to be very popular to use with art programs on tablet pc's. See a discussion here:
http://forum.tabletpcreview.com/artists ... links.html

It has been used on a variety of Windows tablets with Wacom technology. Only recently has someone made some progress in adapting it to the Surface Pro 3:
http://forum.tabletpcreview.com/artists ... blets.html

Hope this helps!
arcticir
Posts: 578
Joined: 17 Nov 2013, 11:32

Re: Basic windows 8 touchscreen tap recognition

18 Aug 2014, 09:43

Hi,lblb

Thank you for information provided, I have found some of them, and to extract the previous example.
chomp. ahk seems to be a very powerful script, I need some time to understand.
You Also concerned about the interaction AHK and touch it?
I have been looking for ways to AHK control touch screen , but also solve many problems
but still there is insurmountable difficulties, intercepting touch events. Recently I searched a lot of information, but it seems we do not have solutions.
lblb
Posts: 129
Joined: 30 Sep 2013, 11:31

Re: Basic windows 8 touchscreen tap recognition

18 Aug 2014, 14:13

Hi arcticir,

I have also been interested in using AHK with Windows touch functions.

CHOMP is just a user-customized version of the original script found in the first link I provided. If you want to understand how this all works, I think you should use the original script and only later look at CHOMP.

I suggest you download the original script by clicking on the "here" link at the top of this page:
http://39kasen.sakura.ne.jp/rawinputcontroltest/

In the zip file, you will be interested in the file named "RawInputControlTest.ahk". Open this file in a text editor. Look at lines 366 to 575: I think you may be able to find what you need to process the x and y coordinates and touch down/up events. (The other lines in the file are mainly for the Gui that is used as an on-screen toolbar and the controls on the Gui.)

(By the way, the rest of the files in the zip file are for customization of the on-screen toolbar. In your case, you will probably be only interested in RawInputControlTest.ahk. But if you are interested in the customization part, you can look at the instructions that I provided here: http://www.mediafire.com/download/hb2x1 ... rol_v3.pdf)
arcticir
Posts: 578
Joined: 17 Nov 2013, 11:32

Re: Basic windows 8 touchscreen tap recognition

19 Aug 2014, 11:12

Yes, I have detailed look over, but unfortunately, I did not find get X and Y coordinates of the code.
Screen_X Screen_Y, these two variables are not displayed correctly.
The following example, you have no way, with a simple code to extract data?

Code: Select all

OnMessage(0xFF, "WM_INPUT")
RegisterRawInputDevices(0) ;Listener
Return 
f1::  RegisterRawInputDevices(1) ;Stop listening
f2:: 
ExitApp


WM_INPUT(wParam, lParam, msg, hwnd)
{  ;From http://39kasen.sakura.ne.jp/rawinputcontroltest/
    static RAWINPUTHEADER_Size :=8 + A_PtrSize * 2

    Critical

    ;------------------------------------------- Reference: GetRawInputData function
    ;   UINT WINAPI GetRawInputData(
    ;     __in       HRAWINPUT hRawInput,
    ;     __in       UINT uiCommand,
    ;     __out_opt  LPVOID pData,
    ;     __inout    PUINT pcbSize,
    ;     __in       UINT cbSizeHeader
    ;   )
;http://msdn.microsoft.com/en-us/library/ms645562

    ;-------------------------------------------
    ; Get size of RAWINPUT data.
    ret := DllCall("GetRawInputData", "Ptr", lParam, "UInt", 0x10000003
                   , "Ptr", 0, "UInt*", cbSize, "UInt", RAWINPUTHEADER_Size)
    If (ret) {
        Return
    }
    VarSetCapacity(RawInputData, cbSize, 0)
    ; Get RAWINPUT data.
    ret := DllCall("GetRawInputData", "Ptr", lParam, "UInt", 0x10000003
                   , "Str", RawInputData, "UInt*", cbSize, "UInt", RAWINPUTHEADER_Size)
    ;------------------------------------------- Reference: RAWINPUT structure
    ;   typedef struct tagRAWINPUT {
    ;     RAWINPUTHEADER header;
    ;     union {
    ;       RAWMOUSE    mouse;
    ;       RAWKEYBOARD keyboard;
    ;       RAWHID      hid;
    ;     } data;
    ;   } RAWINPUT, *PRAWINPUT, *LPRAWINPUT;
    ;------------------------------------------- Reference: RAWINPUTHEADER structure
    ;   typedef struct tagRAWINPUTHEADER {
    ;     DWORD  dwType;
    ;     DWORD  dwSize;
    ;     HANDLE hDevice;
    ;     WPARAM wParam;
    ;   } RAWINPUTHEADER, *PRAWINPUTHEADER;


    ;------- Reference: RAWHID structure
    ;   typedef struct tagRAWHID {
    ;     DWORD dwSizeHid;
    ;     DWORD dwCount;              
    ;     BYTE  bRawData[1];
    ;   } RAWHID, *PRAWHID, *LPRAWHID;
    ; http://msdn.microsoft.com/en-us/library/ms645549
    raw_stat := NumGet(RawInputData, RAWINPUTHEADER_Size + 8 + 1, "UChar") - 127
    raw_x := NumGet(RawInputData, RAWINPUTHEADER_Size + 8 + 2, "UShort")
    raw_y := NumGet(RawInputData, RAWINPUTHEADER_Size + 8 + 4, "UShort")
    ToolTip,% raw_x " " raw_y ,222,222
    ; process WM_INPUT messages in new thread (To reduce dropping messages)
    If (Mod(raw_stat, 4) == 0) {
        TouchReleaseMessagePosted ++
        PostMessage, 0x1001, raw_stat, raw_x | (raw_y << 16),, ahk_id %hwnd%
    }
    Else
        PostMessage, 0x1000, raw_stat, raw_x | (raw_y << 16),, ahk_id %hwnd%
    Return 0
}

RegisterRawInputDevices(f){
    static a,b,c:=(VarSetCapacity(a,8+A_PtrSize),NumPut(13,a,0,"UShort"),NumPut(4,a,2,"UShort")
        ,NumPut(0x00000100,a,4,"UInt"),NumPut(A_ScriptHWND,a,8,"UPtr")
        ,VarSetCapacity(b,8+A_PtrSize),NumPut(13,b,0,"UShort"),NumPut(4,b,2,"UShort")
        ,NumPut(0x00000001,b,4,"UInt"),NumPut(0,b,8,"UPtr")),i:=&a,n:=&b
    DllCall("RegisterRawInputDevices", "Ptr",  f?n:i, "UInt", 1, "UInt", 8 + A_PtrSize)
    }
 
Or, you Whether know how to extract RAWHID data?
lblb
Posts: 129
Joined: 30 Sep 2013, 11:31

Re: Basic windows 8 touchscreen tap recognition

22 Sep 2014, 11:18

Hi arcticir,

Sorry for the very late reply as I was away for quite a while. Maybe you'll be interested in this:

http://forum.tabletpcreview.com/threads ... ars.63949/
arcticir
Posts: 578
Joined: 17 Nov 2013, 11:32

Re: Basic windows 8 touchscreen tap recognition

23 Sep 2014, 08:04

Thank you, lblb
You recommend article useful.


My touch script has stopped development.
because I can not intercept the touch screen events,
so I'm looking forward to WIN9 release,
expect it will improve touch API.

Return to “Scripts and Functions”

Who is online

Users browsing this forum: enrica and 53 guests