using System; class Program { public static void Main() { Console.WriteLine("IntPtr.Size: {0}", IntPtr.Size); Console.WriteLine(); // Two rounds, with positive and with negative numbers long test1 = 0x12340000 /* y */ | 0x00005678 /* x */; long test2 = 0xDCBA0000 /* y */ | 0x00009876 /* x */; foreach (long temp in new[] { test1, test2}) { long test = temp; if (IntPtr.Size == 8) { // We "pad" the number so that all the 64 bits are full and a // standard (int)xy conversion will fail. test = unchecked((long)((ulong)test | 0xFFFFFFFF00000000ul)); } IntPtr xy = (IntPtr)test; int x = unchecked((short)(long)xy); int y = unchecked((short)((long)xy >> 16)); // Other way, more similar to WinAPI ushort loword = unchecked((ushort)(ulong)xy); ushort hiword = unchecked((ushort)((ulong)xy >> 16)); int x2 = unchecked((int)(short)loword); int y2 = unchecked((int)(short)hiword); Console.WriteLine("xy: {0:X}", unchecked((ulong)(long)xy)); Console.WriteLine("x: {0:X}, decimal: {1}, other way: {2:X}, ushort other way: {3:X}", x, x, x2, unchecked((ushort)x2)); Console.WriteLine("y: {0:X}, decimal: {1}, other way: {2:X}, ushort other way: {3:X}", y, y, y2, unchecked((ushort)y2)); Console.WriteLine(); } } }