Есть тестовый проект, который просто перемещает мышь через mouse_event на 100 пикселей вперед и низ. Но координаты после выполнения этого метода получаются совсем не такими, как я ожидал. Помогите найти ошибку
Код:
using System;
using System.Runtime.InteropServices;
namespace mouse_move_test
{
class Program
{
const int ABSOLUTE = 0x00008000;
const int MOVE = 0x00000001;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetCursorPos(out MousePoint lpMousePoint);
public static MousePoint GetCursorPosition()
{
MousePoint currentMousePoint;
var gotPoint = GetCursorPos(out currentMousePoint);
if (!gotPoint) { currentMousePoint = new MousePoint(0, 0); }
return currentMousePoint;
}
[DllImport("user32.dll")]
private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
[StructLayout(LayoutKind.Sequential)]
public struct MousePoint
{
public int X;
public int Y;
public MousePoint(int x, int y)
{
X = x;
Y = y;
}
}
static void Main(string[] args)
{
int dt = 100;
// Тест относительных координат
Console.WriteLine($"Тест относительных координат");
for (int i = 0; i < 3; i++)
{
var pos = GetCursorPosition();
Console.WriteLine($"{pos.X} {pos.Y} - текущая позиция");
Console.WriteLine($"{pos.X + dt} {pos.Y + dt} - ожидание");
mouse_event(MOVE, dt, dt, 0, 0);
pos = GetCursorPosition();
Console.WriteLine($"{pos.X} {pos.Y} - реальность");
Console.WriteLine();
}
// Тест абсолютных координат
Console.WriteLine($"Тест абсолютных координат");
for (int i = 0; i < 3; i++)
{
var pos = GetCursorPosition();
Console.WriteLine($"{pos.X} {pos.Y} - текущая позиция");
Console.WriteLine($"{pos.X + dt} {pos.Y + dt} - ожидание");
mouse_event(MOVE | ABSOLUTE, pos.X + dt, pos.Y + dt, 0, 0);
pos = GetCursorPosition();
Console.WriteLine($"{pos.X} {pos.Y} - реальность");
Console.WriteLine();
}
Console.ReadLine();
}
}
}
Вывод в консоль:
Тест относительных координат
0 0 - текущая позиция
100 100 - ожидание
155 155 - реальность
155 155 - текущая позиция
255 255 - ожидание
409 409 - реальность
409 409 - текущая позиция
509 509 - ожидание
664 664 - реальность
Тест абсолютных координат
664 664 - текущая позиция
764 764 - ожидание
22 12 - реальность
22 12 - текущая позиция
122 112 - ожидание
3 1 - реальность
3 1 - текущая позиция
103 101 - ожидание
3 1 - реальность
upd. Я правда пытаюсь) Приложение WPF. Я постараюсь привести упрощенные методы, мб это поможет Есть хук мыши
private int MouseHookProc(int nCode, int wParam, IntPtr lParam)
{
if (nCode >= 0)
{
Console.WriteLine($"wParam {wParam}");
return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}
}
Если я вызываю код mouse_event(0x00000001, 100, 100, 0, 0); Я получаю в лог wParam 512 Если использую код SetCursorPos(100, 100); То ничего не перехватывается. Что касается SendMessage с ним у меня были какие-то проблемы. Кажется, не работает в играх
dpi у меня 96, как я выяснил. А у координат прирост 50%. Где-то есть масштаб 150% который я пока не знаю как достать
mouse_eventработает в логических пикселях,SetCursorPosиGetCursorPos- в физических. У вас масштаб на мониторе не 100%, поэтому вы получаете такие спецэффекты. Вы можете иMOVEиспользовать, но придется пересчитывать координаты через фактическое значение dpi в отношении к стандартному - 96dpi. То есть ваше значение dpi - 148dpi (но это не точно), его так же можно получить из Win API. Но лучше ничего не пересчитывать, а использовать сразу подходящий метод Win API. – aepot Aug 12 '22 at 11:11mouse_eventустарел, когда я еще был маленьким, актуальный метод Win API для управления клавиатурой и мышью -SendInput. Если хотите правильно реализовать, используйте его, но сразу предупреждаю, он не так прост. Вот пример, для начала. – aepot Aug 12 '22 at 11:15SetCursorPos не хукается как смена позицииТак я вам дал ссылку на код, где все движения реализованы. И на координаты и на смещение. Посмотрите внимательно. Готовый класс, берите и пользуйтесь. Сложно чтоли получитьGetCursorPos, добавить к нему смещение и вызватьSetCursorPos? – aepot Aug 12 '22 at 11:27SendInput, как я советовал ранее. – aepot Aug 12 '22 at 12:55await Task.Delay()не используйтеThread.Sleep. – aepot Aug 12 '22 at 14:05