Как получить информацию о движении мыши, когда курсор находится вне экрана
[пожалуйста, смотрите обновление в конце]
Я старый пользователь переполнения стека (как большинство разработчиков на Земле), но это мой первый вопрос здесь.
Я пытаюсь использовать "воздушную мышь" для игр (указывая на экран), но поскольку сенсор мыши представляет собой гироскоп, есть некоторые проблемы с перемещением за пределы экрана, которые я хотел бы попытаться устранить с помощью программного обеспечения.
С помощью этой гироскопической мыши, когда пользователь перемещает руку, указывающую за пределы экрана, курсор останавливается на пределе экрана, что не составляет проблемы. Однако, когда он отодвигает руку назад, независимо от расстояния до экрана, курсор немедленно перемещается на экране. Это вызывает огромную разницу между реальным положением воздушной мыши и курсором.
Это можно исправить с помощью простого управления количеством пикселей и направлением перемещения за пределы экрана в сочетании с некоторой обработкой событий. Если бы я суммировал количество "закадровых" пикселей, пройденных в -X, +X, -Y и +Y, можно было бы предотвратить / отменить событие перемещения мыши - или установить курсор на предыдущую позицию на краю экрана - пока элемент управления не скажет мне, что физическая мышь указывает назад на экран. Просто тогда я позволю курсору свободно двигаться.
Может быть, это не так полезно, но это интересная проблема, и посмотреть, как это работает, будет чертовски весело!
В настоящее время, основываясь на этом замечательном проекте, я могу просто указать, когда мышь находится вне экрана, но не может контролировать, насколько далеко и в каком направлении она движется, чтобы правильно реализовать то, что я пытаюсь. Мне кажется, что такая информация была бы слишком низкоуровневой для моего текущего знания Windows.
Итак, чтобы быть ясным: как я могу, в C# (другие языки приняты, но я должен был бы многому научиться;), получить любую информацию о "дельта-положении" или направлении движения, когда курсор находится на пределе экрана?
При всем моем уважении, я не заинтересован в использовании различных видов контроллеров, а также в ответах "вы не должны этого делать". Мне нужно решить эту проблему с этими элементами, и было бы здорово сделать эту работу!
ОБНОВИТЬ:
Хорошо, вот мой прогресс до сих пор.
Чтобы получить необработанные данные мыши и узнать о движении мыши "вне экрана", мне пришлось зарегистрировать свое приложение, используя некоторые функции Windows API, для получения сообщений WM_INPUT.
На основе очень старого кода, который я нашел, я смог получить необработанные данные мыши и реализовать именно то, что хотел. За исключением того факта, что этот код основан на обратном вызове WdnProc, и поэтому он работает только тогда, когда мое приложение имеет фокус. И мне нужно, чтобы он также работал, когда фокус находится в другом месте - в конце концов, я пытаюсь улучшить наведение, обеспечиваемое гироскопической мышью, для сторонних игр.
Кажется, что я должен использовать ловушку ( хороший пример здесь), но я понятия не имею, как подключить входные сообщения. Пытался объединить код из двух ссылок выше, но для первой требуется сообщение.LParam, которое передается в WdnProc - которое кажется недоступным при простом перехватывании событий мыши.
Теперь я вышел из своей лиги, чтобы добиться реального прогресса. Есть идеи?
1 ответ
Одно из самых простых решений - получить позицию курсора и затем определить его движение независимо от того, где находится курсор, - использовать Win32 API из user32.dll
,
Вот простой код, который получает позицию курсора каждые 10 мс с использованием таймера в приложении Windows Form C# и отображает его в качестве заголовка окна.
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;
public partial class Form1 : Form
{
Timer timer = new Timer();
public Form1()
{
InitializeComponent();
timer.Interval = 10;
timer.Tick += Timer_Tick;
timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
// do here whatever you want to do
// just for testing...
GetCursorPos(out Point lpPoint);
this.Text = lpPoint.X + ", " + lpPoint.Y;
}
[DllImport("user32.dll")]
public static extern bool GetCursorPos(out Point p);
}