2010-12-17 17 views

Antwort

11

Von MSDN:

WParam
Dieser Parameter wird nicht verwendet.

lParam
Das niederwertige Wort spezifiziert die des Cursors x-Koordinate. Die Koordinate ist relativ zur oberen linken Ecke des Bildschirms.
Das höherwertige Wort gibt die Y-Koordinate des Cursors an. Die Koordinate ist relativ zur oberen linken Ecke des Bildschirms.

So brauchen Sie nur die niedrige Ordnung und hohe Ordnung Worte aus der Botschaft der lParam zu extrahieren:

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

mich über die Leistung zu viele Sorgen nicht, da diese Operationen nur Bit-Ebene sind arithmetisch ...

Beachten Sie, dass diese Koordinaten relativ zum Bildschirm sind. Wenn Sie mit einer Steuerkoordinaten relativ wollen (oder Form), können Sie die PointToClient Methode verwenden:

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

Es funktioniert perfekt! Ich danke dir sehr! – Vercas

+2

Betrachten Sie die nächste Antwort. TL; DR, lege 'x' und' y' auf '(kurz)', bevor du sie für die Unterstützung von Multi-Monitor-Setups (die negative Koordinaten haben) zugewiesen hast. – Gman

12

Bis zu diesem Morgen, würde ich 100% mit Thomas Levesques Antwort vereinbart haben, ich die gleichen Informationen gezogen aus msdn und der Code (scheinbar) hat perfekt funktioniert. Aber es gibt einen Fall, in dem dich das beißen wird. Ich brauchte drei Stunden, um den Grund für diesen Nachmittag zu finden.

Das Symptom, das ich hatte, war, dass auf einem meiner Entwicklungsmaschinen, innerhalb der VS2010 IDE, meine Kontrolle nur durch Klicken ausgewählt wurde, wenn ich auf eine bestimmte Y-Position klickte. Sehr kleine Steuerelemente am oberen Rand des Formulars konnten durch Klicken überhaupt nicht ausgewählt werden. Die Größe der Region, die nicht anklickbar war, sah identisch mit der Größe der IDE um den Windows Forms-Designer aus, so dass ich zuerst dachte, ich hätte ein seltsames wenig bekanntes DesignMode-Problem. Das verwirrendste Bit war, dass genau das gleiche Projekt (aus TFS auf einem anderen Computer ausgecheckt) dieses Verhalten nicht zeigte.

Hier ist, was passiert:

Betrachten Sie einen doppelten Monitor-Setup haben, wie hier gezeigt (sorry für den Deutsch-Screenshot, Ich habe kein Englisch OS zur Hand haben):

Double monitor setup

Wie Sie sehen können, befindet sich die obere linke Ecke von Monitor 2 in Koordinaten (1280, -256). Wenn Sie die oben gezeigte Lösung verwenden, erhalten Sie ein y von etwa 65505, wenn die Maus wirklich bei -30 ist. Dies liegt daran, dass die Positionen als WORD von LParam mit hoher und niedriger Ordnung gespeichert werden. Wenn Sie also (lParam.ToInt32() & 0xFFFF0000) >> 16 tun, erhalten Sie die korrekten Bits für die y-Position. Wenn Sie dies in int umwandeln, ergibt dies 65505, da Sie in den falschen Datentyp umgewandelt haben.

Lösung:

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

zu short Casting gibt Ihnen die richtigen Positionswerte. Ich habe auch das x gewirkt, da Sie Ihre Monitore so arrangieren können, dass der zweite Monitor vom Hauptmonitor übrig bleibt und somit die x-Position das gleiche Problem hat.

Ich habe kürzlich festgestellt, dass einer der Konstrukteure von Point wird für Sie arbeiten. So ist die kurze Version ist:

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

Ich habe 2 Monitore (mehrere Monitore FTW!) Und ich werde das untersuchen. Dies wäre ein großes Problem für die Benutzer. – Vercas

+0

@Vercas Bitte tun. Ich bin neugierig, ob mein Setup so ungewöhnlich ist, da ich das nirgendwo anders gesehen habe, und ich kann mir wirklich nicht vorstellen, dass ich der Einzige bin, der das sieht. Jedenfalls können zwei Monitore so angeordnet werden, dass dies nicht der Fall ist. Wenn sie die gleiche Größe und Ausrichtung haben und von links nach rechts angeordnet sind, erhalten Sie nur eine große Ebene (in meinem Beispiel) 2560x1024px. Da es in keiner der Monitorpositionen negative Koordinaten gibt, ist dies kein Problem. Lustigerweise habe ich gestern meinen zweiten Monitor nur auf diese Weise gedreht :) – takrl

+0

Ja, ich bin mir ziemlich sicher, dass dies genau das Problem ist, dass die Makros 'GET_X_LPARAM' und' GET_Y_LPARAM' hinzugefügt wurden, wenn Windows mehrere Monitore unterstützt (ca. Win 98). Sie sollten nicht nur die 'LOWORD'- und' HIWORD'-Makros verwenden. (Offensichtlich muss diese Makro-Dummheit in .NET übersetzt werden, aber ich dachte, eine Erklärung wäre nützlich.) –

7

Ich weiß, diese Frage wurde bereits beantwortet und alle, aber ...

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

System.Drawing.Point hat nun einen Konstruktor speziell diesen exakten Wert zu akzeptieren entworfen . Genau genommen denke ich, dass dies wahrscheinlich der einfachste Weg ist.

Um ganz ehrlich zu sein, ich habe keine Ahnung, ob dieser Konstruktor überhaupt existierte, als die anderen Antworten gepostet wurden.

Das alles gesagt, dies ist wahrscheinlich nicht schneller, weil takrl die Antwort ist fast sicher, was der oben erwähnte Konstruktor intern tut sowieso.

Verwandte Themen