До этого утра я бы согласился на 100% с ответом Томаса Левеска, я извлек ту же информацию из msdn, и код (казалось бы) работал отлично.Однако есть один случай, когда вас это укусит, мне потребовалось три часа, чтобы найти причину сегодня днем.
Симптом, который у меня был, заключался в том, что на одной из моих машин разработки в IDE VS2010 мой контрольбыл выбран только при нажатии, когда я нажал на него в определенной позиции у.Очень маленькие элементы управления в верхней части формы вообще не могли быть выбраны щелчком мыши.Размер области, на которую нельзя было щелкнуть мышью, выглядел идентично размеру среды IDE, окружающей дизайнер Windows Forms, поэтому сначала я подумал, что у меня возникла странная малоизвестная проблема DesignMode.Самым запутанным моментом было то, что точно такой же проект (извлеченный из TFS на другом компьютере) не продемонстрировал бы такое поведение.
Вот что происходит:
Предположим, у вас двойная настройка мониторакак показано здесь (извините за скриншот на немецком, у меня под рукой нет английской ОС):
![Double monitor setup](https://i.stack.imgur.com/76AmU.jpg)
Как видите, верхний левый угол монитора 2в координатах (1280, -256).Если вы используете решение, показанное выше, вы получите что-то вроде 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());