2010-12-17 32 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的答案几乎肯定是上述構造函數在內部所做的。