Skip to main content
WM_POINTERDOWN message

Posted when a pointer makes contact over the client area of a window. This input message targets the window over which the pointer makes contact, and the pointer is implicitly captured to the window so that the window continues to receive input for the pointer until it breaks contact.

A window receives this message through its WindowProc function.

Important  Desktop apps should be DPI aware. If your app is not DPI aware, screen coordinates contained in pointer messages and related structures might appear inaccurate due to DPI virtualization. DPI virtualization provides automatic scaling support to applications that are not DPI aware and is active by default (users can turn it off). For more information, see Writing High-DPI Win32 Applications.


#define WM_POINTERDOWN                   0x0246

Parameters

wParam

Contains information about the pointer. Use the following macros to retrieve information from the wParam parameter.

  • GET_POINTERID_WPARAM(wParam): the pointer identifier.
  • IS_POINTER_NEW_WPARAM(wParam): a flag that indicates whether this message represents the first input generated by a new pointer.
  • IS_POINTER_INRANGE_WPARAM(wParam): a flag that indicates whether this message was generated by a pointer during its lifetime. This flag is not set on messages that indicate that the pointer has left detection range
  • IS_POINTER_INCONTACT_WPARAM(wParam): a flag that indicates whether this message was generated by a pointer that is in contact with the window surface. This flag is not set on messages that indicate a hovering pointer.
  • IS_POINTER_PRIMARY_WPARAM(wParam): indicates that this pointer has been designated as primary.
  • IS_POINTER_FIRSTBUTTON_WPARAM(wParam): a flag that indicates whether there is a primary action.
    • This is analogous to a mouse left button down.
    • A touch pointer will have this set when it is in contact with the digitizer surface.
    • A pen pointer will have this set when it is in contact with the digitizer surface with no buttons pressed.
  • IS_POINTER_SECONDBUTTON_WPARAM(wParam): a flag that indicates whether there is a secondary action.
    • This is analogous to a mouse right button down.
    • A pen pointer will have this set when it is in contact with the digitizer surface with the pen barrel button pressed.
  • IS_POINTER_THIRDBUTTON_WPARAM(wParam): a flag that indicates whether there are one or more tertiary actions based on the pointer type; applications that wish to respond to tertiary actions must retrieve information specific to the pointer type to determine which tertiary buttons are pressed. For example, an application can determine the buttons states of a pen by calling GetPointerPenInfo and examining the flags that specify button states.
  • IS_POINTER_FOURTHBUTTON_WPARAM(wParam): a flag that indicates whether the specified pointer took fourth action. Applications that wish to respond to fourth actions must retrieve information specific to the pointer type to determine if the first extended mouse (XButton1) button is pressed.
  • IS_POINTER_FIFTHBUTTON_WPARAM(wParam): a flag that indicates whether the specified pointer took fifth action. Applications that wish to respond to fifth actions must retrieve information specific to the pointer type to determine if the second extended mouse (XButton2) button is pressed.

    See Pointer Flags for more details.

    Note  A hovering pointer has none of the button flags set. This is analogous to a mouse move with no mouse buttons down. An application can determine the buttons states of a hovering pen, for example, by calling GetPointerPenInfo and examining the flags that specify button states.

lParam

Contains the point location of the pointer.

Note  Because the pointer may make contact with the device over a non-trivial area, this point location may be a simplification of a more complex pointer area. Whenever possible, an application should use the complete pointer area information instead of the point location.

Use the following macros to retrieve the physical screen coordinates of the point.

Return value

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

If the application does not process this message, it should call DefWindowProc.

Remarks

Important  When a window loses capture of a pointer and it receives the WM_POINTERCAPTURECHANGED notification, it typically will not receive any further notifications. For this reason, it is important that you not make any assumptions based on evenly paired WM_POINTERDOWN/ WM_POINTERUP or WM_POINTERENTER/ WM_POINTERLEAVE notifications.

Each pointer has a unique pointer identifier during its lifetime. The lifetime of a pointer begins when it is first detected.

A WM_POINTERENTER message is generated if a hovering pointer is detected. A WM_POINTERDOWN message followed by a WM_POINTERENTER message is generated if a non-hovering pointer is detected.

During its lifetime, a pointer may generate a series of WM_POINTERUPDATE messages while it is hovering or in contact.

The lifetime of a pointer ends when it is no longer detected. This generates a WM_POINTERLEAVE message.

When a pointer is aborted, POINTER_FLAG_CANCELED is set.

A WM_POINTERLEAVE message may also be generated when a non-captured pointer moves outside the bounds of a window.

To obtain the horizontal and vertical position of a pointer, use the following:


xPos = GET_X_LPARAM(lParam); 
yPos = GET_Y_LPARAM(lParam);

To convert the lParam parameter to a POINTS structure, use the MAKEPOINTS macro.

To retrieve further information associated with the message, use the GetPointerInfo function.

To determine the keyboard modifier key states associated with this message, use the GetKeyState function. For example, to detect that the ALT key was pressed, check whether GetKeyState(VK_MENU) < 0.

Note that if the application does not process this message, DefWindowProc may generate one or more WM_GESTURE messages if the sequence of input from this and, possibly, other pointers is recognized as a gesture. If a gesture is not recognized, DefWindowProc may generate mouse input.

If an application selectively consumes some pointer input and passes the rest to DefWindowProc, the resulting behavior is undefined.

When a window loses capture of a pointer and receives the WM_POINTERCAPTURECHANGED notification, it will typically not receive any further notifications. Therefore, it is important that a window does not make any assumptions of its pointer status, regardless of whether it receives evenly paired DOWN / UP or ENTER / LEAVE notifications.

Examples

The following code example shows how to use IS_POINTER_FIRSTBUTTON_WPARAM, GET_X_LPARAM, GET_Y_LPARAM, and IS_POINTER_SECONDBUTTON_WPARAMto retrieve the relevant information associated with the WM_POINTERDOWN message.


int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);

if (IS_POINTER_PRIMARYBUTTON_WPARAM(wParam))
{
    // process pointer down, similar to mouse left button down
}
else if (IS_POINTER_SECONDARYBUTTON_WPARAM(wParam))
{
    // process pointer down, similar to mouse right button down
}

The following code example shows how to use GET_POINTERID_WPARAM to retrieve the pointer id from the WM_POINTERDOWN message.


POINTER_INFO pointerInfo;
UINT32       pointerId = GET_POINTERID_WPARAM(wParam);

// Retrieve common pointer information
if (!GetPointerInfo(pointerId, &pointerInfo))
{
    // failure, call GetLastError()
}
else
{
    // success, process pointerInfo
}

The following code example shows how to handle different pointer type such as touch, pen, or default pointing devices.


POINTER_TOUCH_INFO   touchInfo;
POINTER_PEN_INFO     penInfo;
POINTER_INFO         pointerInfo;
UINT32               pointerId = GET_POINTERID_WPARAM(wParam);
POINTER_TYPE         pointerType = PT_POINTER;

// default to unhandled to enable call to DefWindowProc
fHandled = FALSE;

if (!GetPointerType(pointerId, &pointerType))
{
    // failure, call GetLastError()
    // set PT_POINTER to fall to default case below
    pointerType = PT_POINTER;
}

switch (pointerType)
{
case PT_TOUCH:
    // Retrieve touch information
    if (!GetPointerTouchInfo(pointerId, &touchInfo))
    {
        // failure, call GetLastError()
    }
    else
    {
        // success, process touchInfo
        // mark as handled to skip call to DefWindowProc
        fHandled = TRUE;
    }
    break;
case PT_PEN:
    // Retrieve pen information
    if (!GetPointerPenInfo(pointerId, &penInfo))
    {
        // failure, call GetLastError()
    }
    else
    {
        // success, process penInfo
        // mark as handled to skip call to DefWindowProc
        fHandled = TRUE;
    }
    break;
default:
    if (!GetPointerInfo(pointerId, &pointerInfo)) 
    {
        // failure.
    } 
    else 
    {
        // success, proceed with pointerInfo.
        fHandled = HandleGenericPointerMessage(&pointerInfo);
    }
    break;
}

Requirements

Minimum supported client

Windows 8 [desktop apps only]

Minimum supported server

Windows Server 2012 [desktop apps only]

Header

Winuser.h (include Windows.h)

See also

Messages
Reference
Pointer Flags
GET_POINTERID_WPARAM
IS_POINTER_NEW_WPARAM
IS_POINTER_INRANGE_WPARAM
IS_POINTER_INCONTACT_WPARAM
IS_POINTER_PRIMARY_WPARAM
IS_POINTER_FIRSTBUTTON_WPARAM
IS_POINTER_SECONDBUTTON_WPARAM
IS_POINTER_THIRDBUTTON_WPARAM
IS_POINTER_FOURTHBUTTON_WPARAM
IS_POINTER_FIFTHBUTTON_WPARAM