Detecting touch screen presses in AutoHotkey in Windows 8

I am using a Dell Venue 8 Pro running Windows 8.1 32 bit. I am trying to use AutoHotkey to map certain regions of the screen to certain buttons on the keyboard, in order to be able to use the touch screen to control a certain pinball game that already exists. My goal is to press A if the left half of the screen is touched, and to press B for the right half (the screen resolution is set to 640x480). This is the script I wrote:

~LButton::
MouseGetPos, x,y
if (x > 0 and x < 320)
    Send {A}
if (x > 320 and x < 640)
    Send {B}
return

However, it doesn't seem to be recognizing touch screen presses at all. It seems as though touch screen presses are distinct from normal mouse clicks. How can I use AutoHotkey to recognize a touch screen press, or is there another solution for what I am trying to do?

Edit: I am starting to think that AutoHotkey is not capable of doing what I want to accomplish here. If anyone can find an alternative way that produces this same outcome (presses keyboard buttons when screen regions are touched), I will accept the answer.


Solution 1:

I'm not sure what language you're coding the game in... Normally, [ javascript ] , [ jquery ], and [ Webkit ] support touch events. But if that doesn't help, then you could try this script and alter it as per your convenience:

Quote from the creator of the script: [ link ]

I have an MID (Mobile Internet Device) called Viliv S5. It has resolution of 1024 x 768 for 4.8 inch screen. That means icons are to small to click with fingers. So I developed a script to convert touchscreen (absolute coordinate) to touchpad (relative coordinate).

This script hooks mouse down, hiding real cursors and showing fake cursors. When the finger is released, the mouse pointer is moved to the intended position and reveal the cursor.

Usage:

  1. Decompress the zip file in the relevant folder.

  2. Open Touchpad.ini and set cursor "speed" (0 ~ 1).

  3. Drag the screen and the cursor moves.

  4. Tap anywhere on the screen and click is sent.

  5. Double tapping is double click.

  6. "Ctrl + u" pause/restart the script.

  7. Click the tray icon and exit the script.

To do:

  1. Implement dragging.

  2. Sometimes cursors jump to my finger position.

  3. Sometimes cursors are hidden.

Download the zip file here: http://cafe.naver.com/flowpad/34 (I updated the above link.)

SCRIPT:

; AutoHotkey Version: 1.x
; Language:       English
; Platform:       Win9x/NT
; Author:         Seung-Young Noh <[email protected]>


#SingleInstance force
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

Menu, Tray, NoStandard
Menu, Tray, Tip, Touchpad V0.7
Menu, Tray, Icon, 1.ico, , 1
Menu, Tray, add, Exit, MenuQuit
Menu, Tray, Default, Exit
Menu, Tray, Click, 1

#Persistent
CoordMode, Mouse, Screen

IniRead, Cursor_speed, Touchpad.ini, main, Cursor_speed
if not Cursor_speed
    Cursor_speed := 0.7

SystemCursor("I")
SetTimer, WatchCursor, 50
return

MenuQuit:
    ExitApp
return

LWin & u::
    Suspend
    SetTimer, WatchCursor, Off
    SetTimer, MovePointer, Off
    SystemCursor(1)

    if (A_IsSuspended = 1) {
        Menu, Tray, Icon, 2.ico
    } else {
        Menu, Tray, Icon, 1.ico
    }
return  

WatchCursor:
    MouseGetPos, x, y
    GetKeyState, state, LButton
    FromX := FromX1
    FromY := FromY1
    FromX1 := x
    FromY1 := y
return

StartWatchCursor:
    SetTimer, WatchCursor, On
return

LButton::
    SystemCursor(0)
    SetTimer, WatchCursor, Off

    ToX := FromX
    ToY := FromY

    SplashImage, C:\Windows\Cursors\arrow_r.cur, x%ToX% y%ToY% B

    MouseGetPos, thisX, thisY
    SetTimer, MovePointer, 100
return

LButton Up::
    SetTimer, MovePointer, Off

    MouseMove, %ToX%, %ToY%, 0
    SplashImage, Off
    if ((A_TimeSincePriorHotkey < 100) and (abs((ToX - FromY) * (ToY - FromY)) < 200)) {
        Click
    }
    FromX := ToX
    FromY := ToY

    SystemCursor(1)

    SetTimer, StartWatchCursor, -1000
return

MovePointer:
    MouseGetPos, x, y
    ToX := ToX + Round(Cursor_speed * (x - thisX))
    ToY := ToY + Round(Cursor_speed * (y - thisY))
    if (ToX <= 0) {
        ToX = 0
    } else if (ToX >= A_ScreenWidth) {
        ToX := A_ScreenWidth
    }
    if (ToY <= 0) {
        ToY = 0
    } else if (ToY >= A_ScreenHeight) {
        ToY := A_ScreenHeight
    }
    
    if (((x - thisX) != 0) or ((y - thisY) !=0)) {
        SplashImage, C:\Windows\Cursors\arrow_r.cur, x%ToX% y%ToY% B
    }
    thisX := x
    thisY := y
return

;; The script below is another's. I can't remember whose it is.

SystemCursor(OnOff=1)   ; INIT = "I","Init"; OFF = 0,"Off"; TOGGLE = -1,"T","Toggle"; ON = others
{
    static AndMask, XorMask, $, h_cursor
        ,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13 ; system cursors
        , b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13   ; blank cursors
        , h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,h12,h13   ; handles of default cursors
    if (OnOff = "Init" or OnOff = "I" or $ = "")       ; init when requested or at first call
    {
        $ = h                                          ; active default cursors
        VarSetCapacity( h_cursor,4444, 1 )
        VarSetCapacity( AndMask, 32*4, 0xFF )
        VarSetCapacity( XorMask, 32*4, 0 )
        system_cursors = 32512,32513,32514,32515,32516,32642,32643,32644,32645,32646,32648,32649,32650
        StringSplit c, system_cursors, `,
        Loop %c0%
        {
            h_cursor   := DllCall( "LoadCursor", "uint",0, "uint",c%A_Index% )
            h%A_Index% := DllCall( "CopyImage",  "uint",h_cursor, "uint",2, "int",0, "int",0, "uint",0 )
            b%A_Index% := DllCall("CreateCursor","uint",0, "int",0, "int",0
                , "int",32, "int",32, "uint",&AndMask, "uint",&XorMask )
        }
    }
    if (OnOff = 0 or OnOff = "Off" or $ = "h" and (OnOff < 0 or OnOff = "Toggle" or OnOff = "T"))
        $ = b  ; use blank cursors
    else
        $ = h  ; use the saved cursors

    Loop %c0%
    {
        h_cursor := DllCall( "CopyImage", "uint",%$%%A_Index%, "uint",2, "int",0, "int",0, "uint",0 )
        DllCall( "SetSystemCursor", "uint",h_cursor, "uint",c%A_Index% )
    }
}

Hope this helps... I haven't tested the script.

Solution 2:

In the AutoHotkey Wish List thread multi finger touch gestures, the main AutoHotkey developer, lexikos, says this on Septembre 30, 2013 :

I don't have a Windows tablet or touch screen, or any interest in getting one or developing touch input features.

Apart from this, as far as I know Windows 8 does send mouse events for touch screens, although they will be delayed until Windows decides that they are not gestures.

This stackoverflow thread says :

I've noticed that Windows 7's touch screen interface has this thing where it will hold back mousedown events. Due to the "tap-and-hold right click" gesture, Windows 7 won't actually send the application a mouse down event until:

  • the user "touch ups" (raise their finger from a touch, at which point both down and up are sent)
  • moves their finger (at which point the click becomes a drag)
  • or the right click circle gesture times out (after about 5-6 seconds)

Your application will need to work with these limitations, especially that of MouseGetPos not working until the user lifts or moves his finger in a way that is obviously (to Windows) not a gesture.

In effect, MouseGetPos may not function very well on a touch screen.