Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Mapping touch gestures to legacy VFP apps

fire555

Programmer
Apr 17, 2025
2
Hi guys,

Has anyone ever gone down the route of trying to map touch screen digitizer events, particularly scroll, to work in VFP?

The Microsoft site says that wm_touch messages were being mapped to wm_scroll messages exactly for legacy support, but this doesn't seem to work in VFP and Win 11.

In particular, I would like to be able to swipe on forms with scrollbars to scroll them.

Any idea?
Thanks
 
I hope this helps someone in the future. You can handle touch screen digitizer messages with the following code. I am only concerned with vertical panning, but you could add other gestures if required.

Put this into your forms init or anywhere else appropriate.

Code:
DECLARE INTEGER GetGestureInfo IN user32 LONG hGestureInfo, STRING @pGestureInfo
DECLARE INTEGER CloseGestureInfoHandle IN user32 LONG hGestureInfo
DECLARE INTEGER GetLastError IN kernel32
DECLARE INTEGER SetGestureConfig IN user32 INTEGER HWND, INTEGER dwReserved, INTEGER cIDs, STRING @lpGestureConfig, INTEGER cbSize

** WM IDs
#DEFINE WM_GESTURE            0x0119

** Gesture IDs
#DEFINE GID_PAN                4

** Gesture configuration flags
#DEFINE GC_ALLGESTURES         0x00000001
#DEFINE GC_PAN                 0x00000001
#DEFINE GC_PAN_WITH_SINGLE_FINGER_VERTICALLY  0x00000002
#DEFINE GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004
#DEFINE GC_PAN_WITH_GUTTER  0x00000008
#DEFINE GC_PAN_WITH_INERTIA 0x00000010
#DEFINE GC_ZOOM                0x00000001
#DEFINE GC_ROTATE              0x00000001
#DEFINE GC_TWOFINGERTAP        0x00000001
#DEFINE GC_PRESSANDTAP         0x00000001
#DEFINE GC_ROTATE_PINCH        0x00000003

** Disable all gestures
gc_dwID     = BINTOC(0, "4RS")
gc_dwWant   = BINTOC(0, "4RS")
gc_dwBlock  = BINTOC(0x01, "4RS")

** Combine into binary structure (12 bytes)
gc_struct = gc_dwID + gc_dwWant + gc_dwBlock
cbSize = 12

SetGestureConfig(THIS.HWND, 0, 1, @gc_struct, cbSize)

** Set vertical pan only
gc_dwID     = BINTOC(GID_PAN, "4RS")
gc_dwWant   = BINTOC(GC_PAN_WITH_SINGLE_FINGER_VERTICALLY + GC_PAN_WITH_INERTIA, "4RS")
gc_dwBlock  = BINTOC(GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY, "4RS")

** Combine into binary structure (12 bytes)
gc_struct = gc_dwID + gc_dwWant + gc_dwBlock
cbSize = 12
SetGestureConfig(THIS.HWND, 0, 1, @gc_struct, cbSize)

** Bind Windows messages
BINDEVENT(THIS.HWND, WM_GESTURE, THIS, "HandleTouch")

Touch events are then handled in this case by an event called HandleTouch.

Code:
LPARAMETERS HWND, nMsg, wParam, lParam

** GESTUREINFO return structure on 32 bit systems
**//
**    Field Sizes & Offsets (32-bit)
**    Field            Type        Size(Bytes)    Offset    Notes
**    cbSize            UINT        4            0
**    dwFlags            DWORD        4            4
**    dwID            DWORD        4            8
**    hwndTarget        HWND        4            12        32-bit HWND
**    ptsLocation        POINTS        4            16        (SHORT x, y)
**    dwInstanceID    DWORD        4            20
**    dwSequenceID    DWORD        4            24
**    ullArguments    ULONGLONG    8            28        8-byte aligned (starts at 28)
**    cbExtraArgs        UINT32        4            36
**    Padding    (none)                8            40        Compiler adds 8 bytes to round up to 48

**    Total: 48 bytes (40 usable + 8 padding)
**//
#DEFINE GID_START         1
#DEFINE GID_END           2
#DEFINE GID_ZOOM          3
#DEFINE GID_PAN           4
#DEFINE GID_ROTATE        5
#DEFINE GID_TWOFINGERTAP  6
#DEFINE GID_PRESSANDTAP   7

** Create buffer for the GESTUREINFO structure
dwSize     = BINTOC(48, "4RS") && Size of the structure (always 48 bytes)
dwFlags    = BINTOC(0, "4RS") && Default flags (0)
dwID       = BINTOC(0, "4RS") && GID_PAN for pan gesture
hwndTarget = BINTOC(0, "4RS")
ptLocationX = BINTOC(0, "2RS") && Default location (X = 0)
ptLocationY = BINTOC(0, "2RS") && Default location (Y = 0)
dwInstanceID = BINTOC(0, "4RS")
dwSequenceID = BINTOC(0, "4RS")
ullArguments = BINTOC(0, "8RS")
cbExtraArgs = BINTOC(0, "4RS")
padding = BINTOC(0, "8RS")

** Combine the parts into a single binary string
gestureInfo = dwSize + dwFlags + dwID  + hwndTarget + ptLocationX + ptLocationY + dwInstanceID + dwSequenceID + ullArguments + cbExtraArgs + padding

** Get result
lnResult = GetGestureInfo(lParam, @gestureInfo)

IF lnResult = 1
    ** API Returned OK
    ** Extract relevant into. We only need dwID and ptLocationX/Y

    *dwSize     = CTOBIN(SUBSTR(gestureInfo, 1, 4), "4rs")
    *dwFlags    = CTOBIN(SUBSTR(gestureInfo, 5, 4), "4rs")
    dwID       = CTOBIN(SUBSTR(gestureInfo, 9, 4), "4rs")
    *hwndTarget = CTOBIN(SUBSTR(gestureInfo, 13, 4), "4rs")
    ptLocationX = CTOBIN(SUBSTR(gestureInfo, 17, 2), "2rs")
    ptLocationY = CTOBIN(SUBSTR(gestureInfo, 19, 2), "2rs")
    *dwInstanceID = CTOBIN(SUBSTR(gestureInfo, 21, 4), "4rs")
    *dwSequenceID = CTOBIN(SUBSTR(gestureInfo, 25, 4), "4rs")
    *ullArguments = CTOBIN(SUBSTR(gestureInfo, 33, 8), "8rs")

    DO CASE
    CASE dwID = GID_START
        ** Handle start of pan gesture. Save initial X/Y position
        THIS.ptlocationy_initial = ptLocationY
        THIS.ptlocationx_initial = ptLocationX

    CASE dwID = GID_PAN
        ** Handle gesture in progress. Calculate dY/dX and apply to the viewport
        dy = ptLocationY - THIS.ptlocationy_initial
        dx = ptLocationX - THIS.ptlocationx_initial
        THISFORM.SETVIEWPORT(0, IIF((THISFORM.VIEWPORTTOP - dy) < 0, 0, THISFORM.VIEWPORTTOP - dy))

        THIS.ptlocationy_initial= ptLocationY
        THIS.ptlocationx_initial= ptLocationX
    ENDCASE
ENDIF

CloseGestureInfoHandle(lParam)

Just a quick note, you will not receive WM_GESTURE messages if you have already registered the hWnd to receive WM_TOUCH messages.

Thanks
 

Part and Inventory Search

Sponsor

Back
Top