如何在C#中读取Win32 WM_MOVE lParam x,y坐标?

时间:2018-03-14 22:22:13

标签: c# winapi pinvoke

我正在尝试从WM_MOVE win32消息中读取lParam x和y坐标并获取奇怪的值。我需要以某种方式从lParam IntPtr中提取它们。

https://msdn.microsoft.com/en-us/library/windows/desktop/ms632631(v=vs.85).aspx

由于

3 个答案:

答案 0 :(得分:1)

除了Simon Mourier已发布的内容(涵盖了许多标准宏)之外,此方法还会从Point()返回message.LParam

  

MSDN suggests使用GET_X_LPARAMGET_Y_LPARAM宏   (在WindowsX.h中定义)提取坐标,警告   LOWORDHIWORD返回的错误结果   宏(在WinDef.h中定义),因为它们返回unsigned   整数。
这些是建议的宏的定义:

#define GET_X_LPARAM(lp)    ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp)    ((int)(short)HIWORD(lp))

重要的是必须对这些值进行签名,因为辅助监视器会将负值作为坐标返回。

public static Point PointFromLParam(IntPtr lParam)
{
    return new Point((int)(lParam) & 0xFFFF, ((int)(lParam) >> 16) & 0xFFFF);
}

答案 1 :(得分:0)

Windows消息中的坐标通常是两个带符号的16位数字,打包成32位数字。

理想情况下,您应将这些数据提取为模拟GET_X_LPARAM / GET_Y_LPARAM宏的带符号数字:

IntPtr lparam = (IntPtr) 0xfffeffff; // -1 x -2 example coordinate
uint lparam32 = (uint) lparam.ToInt64(); // We want the bottom unsigned 32-bits
short x = (short) (((uint)lparam32) & 0xffff);
short y = (short) ((((uint)lparam32) >> 16) & 0xffff);  

Console.WriteLine(string.Format("coordinates: {0} x {1}", x, y));

对于WM_MOVE,你也可以将它们提取为无符号数字(ushort),因为客户区永远不会是负数。

答案 2 :(得分:0)

.NET参考源是一个金矿。在内部System.Windows.Forms.NativeMethods+Util class中,您将找到这些助手,与WM_MOVE文档(高阶词= HIWORD,低阶词= LOWORD等)的说法相同。

public static int MAKELONG(int low, int high) {
    return (high << 16) | (low & 0xffff);
}

public static IntPtr MAKELPARAM(int low, int high) {
    return (IntPtr) ((high << 16) | (low & 0xffff));
}

public static int HIWORD(int n) {
    return (n >> 16) & 0xffff;
}

public static int HIWORD(IntPtr n) {
    return HIWORD( unchecked((int)(long)n) );
}

public static int LOWORD(int n) {
    return n & 0xffff;
}

public static int LOWORD(IntPtr n) {
    return LOWORD( unchecked((int)(long)n) );
}

public static int SignedHIWORD(IntPtr n) {
    return SignedHIWORD( unchecked((int)(long)n) );
}

public static int SignedLOWORD(IntPtr n) {
    return SignedLOWORD( unchecked((int)(long)n) );
}

public static int SignedHIWORD(int n) {
    int i = (int)(short)((n >> 16) & 0xffff);
    return i;
}

public static int SignedLOWORD(int n) {
    int i = (int)(short)(n & 0xFFFF);
    return i;
}