BUG: GetMouseMovePointsEx Returns Incorrect Results with Negative Coordinates (269743)



The information in this article applies to:

  • Microsoft Platform Software Development Kit (SDK) 1.0, when used with:
    • the operating system: Microsoft Windows 2000
    • the operating system: Microsoft Windows Millennium Edition

This article was previously published under Q269743

SYMPTOMS

When you call the GetMouseMovePointsEx function, if negative coordinates are passed through the MOUSEMOVEPOINT structure, the function may fail or return erroneous values. Also, if any of the coordinates to be retrieved by GetMouseMovePointsEx has a negative value (as is very possible when multiple monitors are present), the returned coordinates are not valid.

CAUSE

GetMouseMovePointsEx takes as input one MOUSEMOVEPOINT structure whose members are as follows:
typedef struct tagMOUSEMOVEPOINT {
  int       x;
  int       y;
  DWORD     time;
  ULONG_PTR dwExtraInfo;
} MOUSEMOVEPOINT, *PMOUSEMOVEPOINT;
				
GetMouseMovePointsEx internally casts its cached mouse information to 16-bit values. This results in the function being unable to find a coordinate match when negative integer values are passed for the x or y members of the MOUSEMOVEPOINT structure.

In the case where the function returns a negative coordinate, the coordinate is cast to a 16-bit value, causing the high-order 16 bits to be lost.

RESOLUTION

To work around this problem, you must obtain the following values from the GetSystemMetrics function:
  • SM_XVIRTUALSCREEN
  • SM_YVIRTUALSCREEN
  • SM_CXVIRTUALSCREEN
  • SM_CYVIRTUALSCREEN
For each point that is returned from GetMouseMovePointsEx, perform the following transform:
int nVirtualWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN) ;
int nVirtualHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN) ;
int nVirtualLeft = GetSystemMetrics(SM_XVIRTUALSCREEN) ;
int nVirtualTop = GetSystemMetrics(SM_YVIRTUALSCREEN) ;
int cpt = 0 ;
int mode = GMMP_USE_DISPLAY_POINTS ;

MOUSEMOVEPOINT mp_in ;
MOUSEMOVEPOINT mp_out[64] ;

ZeroMemory(&mp_in, sizeof(mp_in)) ;
mp_in.x = pt.x & 0x0000FFFF ;//Ensure that this number will pass through.
mp_in.y = pt.y & 0x0000FFFF ;
cpt = GetMouseMovePointsEx(&mp_in, &mp_out, 64, mode) ;

for (int i = 0; i < cpt; i++)
{
   switch(mode)
   {
   case GMMP_USE_DISPLAY_POINTS:
      if (mp_out[i].x > 32767)
         mp_out[i].x -= 65536 ;
      if (mp_out[i].y > 32767)
         mp_out[i].y -= 65536 ;
      break ;
   case GMMP_USE_HIGH_RESOLUTION_POINTS:
      mp_out[i].x = ((mp_out[i].x * (nVirtualWidth - 1)) - (nVirtualLeft * 65536)) / nVirtualWidth ;
      mp_out[i].y = ((mp_out[i].y * (nVirtualHeight - 1)) - (nVirtualTop * 65536)) / nVirtualHeight ;
      break ;
   }
}
				

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

MORE INFORMATION

GetMouseMovePointsEx is used to retrieve up to 64 mouse points, starting from a point or time stamp that you supply or the first 64 available mouse points. For additional information, refer to the Platform SDK documentation on GetMouseMovePointsEx.

Modification Type:MinorLast Reviewed:7/11/2005
Keywords:kbbug KB269743