2010-12-17 30 views

回答

11

从MSDN:

的wParam
不使用此参数。

lParam的
低位字指定 光标的x坐标。 坐标相对于屏幕左上角的 。
高位字指定光标的y坐标 。 坐标相对于屏幕左上角的 。

所以你只需要从中提取低阶和高阶字消息的lParam

int x = lParam.ToInt32() & 0x0000FFFF; 
int y = (int)((lParam.ToInt32() & 0xFFFF0000) >> 16) 
Point pos = new Point(x, y); 

我不会太担心性能,因为这些操作都只是有点水平算术...

请注意,这些坐标是相对于屏幕。如果你想坐标相对于对照组(或形式),你可以使用PointToClient方法:

Point relativePos = theControl.PointToClient(pos); 
+0

它完美的作品!非常感谢! – Vercas 2010-12-17 14:23:12

+2

考虑看下一个答案。在分配它们以支持多监视器设置(具有负坐标)之前,TL; DR,将'x'和'y'转换为'(短)'。 – Gman 2013-06-19 14:52:09

12

直到今天早上,我已经同意100%,与托马斯Levesques答案,我把从同一个信息msdn和代码(似乎)完美地工作。但是,有一件事情会让你感到吃惊,我花了三个小时才找到今天下午的原因。

我遇到的症状是,在我的一台开发机器上,在VS2010 IDE中,我的控件只能在某个y位置单击时选择。表单顶部的非常小的控件无法通过点击进行选择。不可点击区域的大小看起来与围绕Windows窗体设计器的IDE大小相同,所以起初我以为我有一些奇怪的鲜为人知的DesignMode问题。最容易混淆的是,完全相同的项目(在不同的机器上检出TFS)不会显示这种行为。

这里发生了什么:

考虑你有如下所示的双显示器设置(抱歉德国截图,我没有在手的英文OS):

Double monitor setup

如您所见,显示器2的左上角位于坐标(1280,-256)处。如果你使用上面的解决方案,如果鼠标真的在-30,你会得到类似65505的东西。这是因为仓位被存储为LParam的高位和低位WORD。所以,做(lParam.ToInt32() & 0xFFFF0000) >> 16会给你y位的正确位。但是,将此转换为int会产生65505,因为您正在转换为错误的数据类型。

解决方案:

int x = (short)(lParam.ToInt32() & 0x0000FFFF); 
int y = (short)((lParam.ToInt32() & 0xFFFF0000) >> 16); 
Point pos = new Point(x, y); 

铸造到short给你正确的位置值。我也投了x,因为你可以用第二台显示器放在主显示器上的方式来安排显示器,因此x位置也会有同样的问题。

我最近发现其中一个Point的构造函数会帮你工作。所以,简单的版本是:

Point pos = new Point(lParam.ToInt32()); 
+0

我确实有2台显示器(多台显示器FTW!),我将研究这一点。这对用户来说是一个巨大的问题。 – Vercas 2011-06-17 20:01:22

+0

@Vercas请做。我很好奇,如果我的设置非常不寻常,因为我从来没有在其他地方看到过这个提及,我真的无法想象我是唯一看到这个的人。无论如何,两台显示器可以按照不会发生的方式排列,如果两台显示器的尺寸和方向相同,并且从左到右排列,那么您只能获得一个2560x1024px的大平面(在我的示例中)。由于在任何监视器位置都没有负面坐标,所以这不成问题。有趣的是,我只是昨天以这种方式旋转了我的第二台显示器:) – takrl 2011-06-17 20:56:03

+0

是的,我敢肯定,这是确切的问题,当Windows获得多个显示器支持时,会添加'GET_X_LPARAM'和'GET_Y_LPARAM'宏以解决问题(大约Win 98)。你不应该继续使用'LOWORD'和'HIWORD'宏。 (显然这个宏的愚蠢必须转换为.NET,但我认为一个解释是有用的。) – 2012-02-17 17:07:26

7

我知道这个问题已经回答所有,但...

Point p = new Point(m.LParam.ToInt32()); 

System.Drawing.Point现在有专门用来接受这个精确值构造。严格地说,我认为这可能是最简单的方式。

说实话,我不知道这个构造函数在其他答案发布时是否存在。

大家都说,这可能不是更快,因为takrl的答案几乎肯定是上述构造函数在内部所做的。