Вопрос

Как получить координаты сообщения wm_nchittest в коде C#?
Я хотел бы получить самый быстрый путь, потому что производительность - это требование.

Это было полезно?

Решение

От 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);

Другие советы

Вплоть до этого утра я бы согласился на 100% с ответом Томаса Левеска, я вытащил ту же информацию из MSDN, и код (казалось бы,) работал отлично. Тем не менее, есть один случай, когда это укусит вас, мне потребовалось три часа, чтобы найти причину сегодня днем.

Симптом, который у меня был, заключался в том, что на одной из моих машин разработки, в IDE VS2010, мой контроль был выбирался только нажав, когда я нажимал на него в определенной Y-позиции. Очень маленькие элементы управления в верхней части формы не были выбирались, нажав вообще. Размер области, которая не была кликабельной, выглядела идентично размеру IDE, окружающего дизайнера Windows Forms, поэтому сначала я подумал, что у меня была какая-то странная малоизвестная проблема дизайна. Самым запутанным битом было то, что именно тот же проект (проверенный из TFS на другой машине) не будет показывать такое поведение.

Вот что происходит:

Считайте, что у вас есть настройка двойного монитора, как показано здесь (извините за немецкий скриншот, у меня нет английской ОС под рукой):

Double monitor setup

Как видите, верхний левый угол монитора 2 находится в координатах (1280, -256). Если вы используете решение, показанное выше, вы получите y из -за чего -то вроде 65505, если мышь действительно составляет -30. Это потому, что позиции хранятся как высокий и низкий порядок WORD Lparam. Итак, делаю (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());

Я знаю, что на этот вопрос уже ответил и все, кроме ...

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

System.Drawing.Point теперь имеет конструктор, специально разработанный для принятия этого точного значения. Строго говоря, я думаю, что это, вероятно, самый простой путь.

Честно говоря, я понятия не имею, существовал ли этот конструктор, когда были опубликованы другие ответы.

Что все сказано, это, вероятно, не Быстрее Потому что ответ Такрля почти наверняка - то, что вышеупомянутый конструктор в любом случае делает внутренне.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top