/// <summary> /// 重载Win32窗口消息处理,目的是把Win32消息的参数转成C#可识别的参数 /// </summary> /// <param name="hWnd">Win32窗口句柄</param> /// <param name="msg">消息号</param> /// <param name="wParam">参数1</param> /// <param name="lParam">参数2</param> /// <param name="handled">返回能否已处理该消息,假如设为true,则在C++端不再接收该消息</param> /// <returns>返回消息处理结果,一般正常返回IntPtr.Zero</returns> protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { switch (msg) { case 0x0201: // WM_LBUTTONDOWN case 0x0204: // WM_RBUTTONDOWN case 0x0207: // WM_MBUTTONDOWN { // 鼠标被按下 int v0 = wParam.ToInt32(); int v1 = lParam.ToInt32(); bool ctrl = (v0 & 0x0008) == 0x0008; int x = (int)(v1 & 0xffff); int y = (int)((v1 & 0xffff0000) >> 16); MouseButton btn = MouseButton.Left; if (msg == 0x0201) btn = MouseButton.Left; else if (msg == 0x0204) btn = MouseButton.Right; else if (msg == 0x0207) btn = MouseButton.Middle; if (DoMouseDown != null) handled = DoMouseDown(hwnd, btn, x, y, 0, ctrl); } break;
这段代码看不懂,主要想知道x y为什么要那样运算,运算之后的结果又代表什么意思
这是鼠标按下的一个事件
解决方案
50
上面对 消息的说明 很明确 在lparam 中保存的是 x 和 y 坐标
就如同你看到的 windows 消息的结构包含为 (hWnd,MSG,WParam,LParam)
hwnd 是窗口句柄
msg 是消息类型 也就是 WM_XXXX 之类的
wParam 和 lParam 是消息的附带参数 更具 WM_XXX 的类型而决定这两个值是什么
例如上面 WM_MBUTTONDOWN 既然是一个点击 那么就必须包含坐标
而坐标也就只能用那两个多出来的 wParam 和 lParam 来表示
但是上面的文档说了 wParam 的参数有其他意义 那么坐标就只能用lParam来表示了
由于坐标是 x y 两个参数 而 lParam 一个变量无法表示两个值
所以说 只能把 lParam 才分 原因是lParam本身是一个int占用4个字节 所以说 当成两个 2字节来使用
2字节用来表示x 2字节用来表示y 这样就搞定了
49
假如经常用这些东西 本人装一个离线版本的 msdn 方便查询
例如上面是 一个 WM_GETTEXT 消息 可以用来获取某个控件的 text
上面的 wParam 和 lParam 所表示的意思又不一样了
lParam 此时则是一个缓存 例如说 你可能需要传入一个 byte[]
而wParam 此时则是 你需要获取多少个字节 一般传入的是 byte[] 的大小