0

Working with C# in Visual Studio 2008 (.NET 3.5). Looking into System.Windows.Forms.MouseEventArgs.

I'm seeing strange behavior with long Panel when I intercept handle the MouseMove event. It appears that MouseEventArgs.X goes from 0 to 32767, and wraps around to -32768.

When I watch the variable in Visual Studio, it claims that it's of type int.

Apparently it's a 16-bit signed integer the way it's behaving. Is this true? Is this a hard limit?

Thanks!

John
  • 15,990
  • 10
  • 70
  • 110

2 Answers2

3

This probably comes from the fact that Windows Forms is basically a .NET wrapper around the C Windows API. For the WM_MOUSEMOVE and related messages (WM_LBUTTONDOWN, etc.), the mouse coordinates are sent in the LPARAM parameter. LPARAM is a typedef for LONG_PTR, which on 32-bit Windows (only) is in turn a typedef for long. As the docs for WM_MOUSEMOVE say, you can get the cursor position by using the GET_X_LPARAM and GET_Y_LPARAM macros, which return the low-order int and the high-order int, respectively.

Since the value is 32 bits to start with (on 32-bit Windows), the only way this makes sense is for the x and y coordinates to actually be 16-bit values. Based on the definition of GET_X_LPARAM in windowsx.h, I would also guess (but do not have an official source that says) that even on x64 only the lower 32 bits of the LPARAM are used for the mouse coordinates.

Joel
  • 660
  • 4
  • 5
  • Thanks Joel! Makes one wonder then why the type of MouseEventArgs.X and MouseEventArgs.Y aren't 16-bit signed, if that's all they can really be. – John Jun 16 '11 at 22:19
  • There's a similar issue with WM_VSCROLL. You can have 32-bit scroll bar positions, but the message only comes with 16 bits of data. The signed 16-bit mouse position limit is not actually documented for Windows Forms, so maybe they wanted to leave open the possibility of providing the cursor position returned from something like GetCursorInfo? Not sure. – Joel Jun 17 '11 at 15:17
1

Instead of using the position in the mouse move event, use:

PointToClient(Cursor.Position)

Microsoft could easily do this in their .Net wrapper. There might be a legitimate reason why they don't but it seems to work for me.

Jim Balkwill
  • 328
  • 5
  • 12