Unexplained OverflowException casting IntPtr representing screen coordinate for Int32

We have a WinForms AnyCPU application in which managing the vendor library sometimes throws the following exception in a 64-bit user box with multiple monitors:

System.OverflowException: Arithmetic operation resulted in an overflow.
   at VendorLibraryName.VendorControl.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

I looked at the vendor library's WndProc handler handler, and the only bit of code that looks like it might cause an overflow is (my comments are decompiled):

switch (msg)
{
    case 132: // NCHITTEST 
    case 672: // NCMOUSEHOVER 

    // Technically dangerous: convert IntPtr to Int32 in a 64-bit process.
    // However, note that for these message codes, 
    // LParam represents a "packed" x and y screen-coordinate. 
    // Given my understanding of how this packing occurs, I can't think
    // of how to construct an LParam such that it would overflow an Int32.
    SomeMethod(x: (int)m.LParam & 65535, y: (int)m.LParam >> 16);

    // More code...

Here's the actual IL for conversions and bit-twiddling:

IL_0092: ldarg.1
IL_0093: call instance native int [System.Windows.Forms]System.Windows.Forms.Message::get_LParam()

// As far as I can tell, this is the only instruction on which overflow could occur
IL_0098: call int32 [mscorlib]System.IntPtr::op_Explicit(native int)

IL_009d: ldc.i4 65535
IL_00a2: and
IL_00a3: ldarg.1

// Same thing here...
IL_00a4: call instance native int [System.Windows.Forms]System.Windows.Forms.Message::get_LParam()
IL_00a9: call int32 [mscorlib]System.IntPtr::op_Explicit(native int)

IL_00ae: ldc.i4.s 16
IL_00b0: shr

, , 64- Message.LParam(IntPtr) Int32. , , - ​​ GET_X_LPARAM GET_Y_PARAM #.

, LPARAM NCHITTEST/NCMOUSEHOVER, , , Int32. ( , 16 16- X-, 16- Y . , , , ).

dev-box .

? , ?

+5
1

, " ".

MSDN:

. LOWORD HIWORD x- y- , . x y, LOWORD HIWORD .

CLR- 2- , "" (, 1); , -1 - 1111.... 1. , 32- ().

EDIT: ( : , ) , , y.

, (x: -1, y: -1)

: x: 0xFFFF, y: 0xFFFF

32- : 0xFFFF FFFF

, : IntPtr ( ? neg y). :

0x0000 0000 FFFF FFFF

4294967295 , Int32.

Y

000.(32 Zeros)..001 ...(other 31 digits) .. 0 

( ?)

0

All Articles