7 out of 9 rated this helpful - Rate this topic

WM_GESTURE message

Applies to: desktop apps only

Passes information about a gesture.

Parameters

wParam

Provides information identifying the gesture command and gesture-specific argument values. This information is the same information passed in the ullArguments member of the GESTUREINFO structure.

lParam

Provides a handle to information identifying the gesture command and gesture-specific argument values. This information is retrieved by calling GetGestureInfo.

Return value

If an application processes this message, it should return 0.

If the application does not process the message, it must call DefWindowProc. Not doing so will cause the application to leak memory because the touch input handle will not be closed and associated process memory will not be freed.

Remarks

The following table lists the supported gesture commands.

Gesture IDValue (dwID)Description
GID_BEGIN1Indicates a generic gesture is beginning.
GID_END2Indicates a generic gesture end.
GID_ZOOM3Indicates zoom start, zoom move, or zoom stop. The first GID_ZOOM command message begins a zoom but does not cause any zooming. The second GID_ZOOM command triggers a zoom relative to the state contained in the first GID_ZOOM.
GID_PAN4Indicates pan move or pan start. The first GID_PAN command indicates a pan start but does not perform any panning. With the second GID_PAN command message, the application will begin panning.
GID_ROTATE5Indicates rotate move or rotate start. The first GID_ROTATE command message indicates a rotate move or rotate start but will not rotate. The second GID_ROTATE command message will trigger a rotation operation relative to state contained in the first GID_ROTATE.
GID_TWOFINGERTAP6Indicates two-finger tap gesture.
GID_PRESSANDTAP7Indicates the press and tap gesture.

 

Note   In order to enable legacy support, messages with the GID_BEGIN and GID_END gesture commands need to be forwarded using DefWindowProc.

The following table indicates the gesture arguments passed in the lParam and wParam parameters.

Gesture IDGestureullArgumentptsLocation in GestureInfo structure
GID_ZOOMZoom In/OutIndicates the distance between the two points.Indicates the center of the zoom.
GID_PANPanIndicates the distance between the two points. Indicates the current position of the pan.
GID_ROTATERotate (pivot)Indicates the angle of rotation if the GF_BEGIN flag is set. Otherwise, this is the angle change since the rotation has started. This is signed to indicate the direction of the rotation. Use the GID_ROTATE_ANGLE_FROM_ARGUMENT and GID_ROTATE_ANGLE_TO_ARGUMENT macros to get and set the angle value.This indicates the center of the rotation which is the stationary point that the target object is rotated around.
GID_TWOFINGERTAPTwo-finger TapIndicates the distance between the two fingers.Indicates the center of the two fingers.
GID_PRESSANDTAPPress and TapIndicates the delta between the first finger and the second finger. This value is stored in the lower 32 bits of the ullArgument in a POINT structure.Indicates the position that the first finger comes down on.

 

Note  All distances and positions are provided in physical screen coordinates.

Note  The dwID and ullArgument parameters should only be considered to be accompanying the GID_* commands and should not be altered by applications.

Examples

The following code illustrates how to obtain gesture-specific information associated with this message.

Note   You should always forward unhandled messages to DefWindowProc and should close the gesture input handle for messages that you do handle with a call to CloseGestureInfoHandle. In this example, the default gesture handler behavior will be suppressed because the TOUCHINPUT handle is closed in each of the gesture cases. If you removed the cases in the above code for unhandled messages, the default gesture handler would process the messages by getting forwarded to DefWindowProc in the default case.


  LRESULT DecodeGesture(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
    // Create a structure to populate and retrieve the extra message info.
    GESTUREINFO gi;  
    
    ZeroMemory(&gi, sizeof(GESTUREINFO));
    
    gi.cbSize = sizeof(GESTUREINFO);

    BOOL bResult  = GetGestureInfo((HGESTUREINFO)lParam, &gi);
    BOOL bHandled = FALSE;

    if (bResult){
        // now interpret the gesture
        switch (gi.dwID){
           case GID_ZOOM:
               // Code for zooming goes here     
               bHandled = TRUE;
               break;
           case GID_PAN:
               // Code for panning goes here
               bHandled = TRUE;
               break;
           case GID_ROTATE:
               // Code for rotation goes here
               bHandled = TRUE;
               break;
           case GID_TWOFINGERTAP:
               // Code for two-finger tap goes here
               bHandled = TRUE;
               break;
           case GID_PRESSANDTAP:
               // Code for roll over goes here
               bHandled = TRUE;
               break;
           default:
               // A gesture was not recognized
               break;
        }
    }else{
        DWORD dwErr = GetLastError();
        if (dwErr > 0){
            //MessageBoxW(hWnd, L"Error!", L"Could not retrieve a GESTUREINFO structure.", MB_OK);
        }
    }
    if (bHandled){
        return 0;
    }else{
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
  }


Requirements

Minimum supported client

Windows 7

Minimum supported server

Windows Server 2008 R2

Header

Winuser.h (include Windows.h)

See also

Notifications
Windows Touch Gestures Programming Guide

 

 

Send comments about this topic to Microsoft

Build date: 3/7/2012

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
Not forwarding messages to DefWindowProc still triggers legacy behavior
In the Examples section, if you handle GID_ZOOM and return 0 from the WM_TOUCH handler, I would expect that the legacy behavior of receiving a WM_MOUSEWHEEL event would not occur, but this doesn't seem to be the case. I haven't tried blocking the GID_BEGIN, but I also don't think it's possible to know that GID_BEGIN will be followed by a GID_ZOOM, so I'm guessing that wouldn't work either. $0$0 $0 $0I haven't check WM_GESTURENOTIFY to see if that tells you a GID_ZOOM is about to start before the GID_BEGIN is sent.$0
Value
WM_GESTURE = 0x0119;
Tips & Corrections
I'm using Win7 RTM + DELL XT Tablet with MultiTouch and Delphi 4/5/6/7
Two finger Tap
ullArgument - always returns zero (so either doc above is wrong or my driver is screwing up)
ptsLocation - Yes does indeed return the centre point between the 2 fingers.
Tip: You have the first finger position from the WM_GESTURENOTIFY message. With the centre position you can now calculate the 2nd finger position.
Press and Tap
ullArgument - So this is the x,y (smallPoint) offset from the first finger (the Delta). You will see number like 0x00000000FFFE0004 -- LoDWord FFFE0004 is a smallPoint x=4, y=-2. This point comes in once at the start of the gesture (see GF_BEGIN gesture flag). then its zero.
Tip. After tapping try panning with finger 1. ptsLocation will update allowing you to pan within the Press and Tap gesture.
Zoom
Info above is correct. You have centre point and distance between fingers.
Tip: After initiating zoom move both fingers to pan within the zoom gesture. Very cool - Zoom and Pan (without inertia) together.
Rotate
ullArgument - Pass the loWord of the LoDWord to macro GID_ROTATE_ANGLE_FROM_ARGUMENT(). This gives the angle in Radians. Convert radians to degrees if required.
For the first message (GF_BEGIN flag) this is the initial angle. Other message are the difference in angle from initial angle.
ptsLocation - Centre point between fingers.
Tip: Once rotation gesture is started try moving bother fingers. ptsLocation will change giving you pan (without inertia). Very cool.
Pan
ullArgument - Distance between fingers. Zero if panning with only one finger. ptsLocation - Yes centre of fingers or single finger position. This will change as you move around. Tip: Try panning with 2 fingers while changing distance between fingers. You basically have zoom and pan
together (like zoom command but this time with inertia). Tip: If Pan Gutter is enabled then as you move left right the gesture hugs the x-axis without changing the y value. Similarly if you move up down then the x value wont change.
Tip: Inertia - this is when you pan and flick. The ptsLocation point will continue moving after your finger(s) leave the screen, gradually slowing down until stopped. Inertia and Gutter events (as well as Pan With Single Finger Vert/Horiz) can be switch on and off in the WM_GESTUTRENOTIFY event by calling SetGestureConfig().

Really nice implementation. Works well.

Note1: Flicks are not part of WM_GESTURE events although I really wish they were. See instead the
WM_TABLET_FLICK. Unlike WM_GESTURE the WM_TABLET_FLICK messages (off the main window) stops firing (at least in Delphi) once you cover your form with controls. Only fires on an empty form. Now in Delphi at least to subclass all controls so you get this message would be a nightmare.
So you need to forget WM_TABLET_MESSAGE and listen for the follow on key events etc that Windows
sends out after a flick is detected.
Note 2: WM_GESTURENOTIFY message is very handy. This message comes before every gesture and flick and gives you the handle of the control receiving the gesture and screen location of the gesture (first finger to touch).