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 TouchToneTommy 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

Status
Not open for further replies.

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
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top