PostMessage и SendMessage WM_SETCURSOR, WM_LBBUTTONDOWN / UP и т. Д. Все отправляют xPox0, yPos0 - PullRequest
1 голос
/ 07 июля 2011

Я пишу программу на C # для отправки кликов из одного окна в другое. Я использую SendMessage и PostMessage из winapi. SendMessage прекрасно работает для событий клавиатуры, но когда я пытаюсь использовать его для отправки событий мыши, он всегда отправляет координаты мыши 0,0. С помощью spy ++ я могу проверить, что приложение получает события, но значения x и y равны (0,0), и приложение думает, что мышь находится вне экрана NCHITTEST = NOTCLIENT.

Код выглядит следующим образом:

PostMessage(appWin, (int)WMessages.WM_MOUSEMOVE, 0, MakeDword(300, 200));

Где PostMessage объявлено как:

[DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
protected static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam);

Где appWin - дескриптор окна (проверено с помощью spy ++, что оно получает события). Окно не имеет элементов управления вообще. Я также попробовал несколько макросов MakeLParam, MakeDword, сделал это вручную и т. Д. Я использую Windows7.

Я провел большую часть прошлой ночи / этим утром, пытаясь найти проблему, но я не смог. Хотя в Интернете много сообщений о Post / SendMessage, мне удалось найти только то, где возникла подобная проблема, но ответов не было.

Чтобы подвести итог проблемы: Кто-нибудь знает, почему SendMessage будет отправлять правильное сообщение в окно приложения, но вместо того, чтобы передавать ему координаты x и y, всегда передавая (0,0)?

Спасибо!

Ответы [ 3 ]

3 голосов
/ 07 июля 2011

Я думаю, что наконец-то смогу понять, что не так с вашим кодом.

[DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)] 
static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam);

Проблема в том, что long имеет ширину 64 бита в C #.В 32-битном процессе это неверно, поскольку эти параметры должны иметь ширину 32 бита.Я бы ожидал, что вы увидели предупреждение о дисбалансе стека при запуске через отладчик.

Правильное объявление:

static extern bool PostMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam);

Вам определенно не нужно переключаться на нативный C ++код, чтобы заставить это работать.

1 голос
/ 21 февраля 2012

Я пытался ввести ввод мыши с помощью PostMessage / SendMessage, по тем же причинам, что и emist.Один важный недостаток, который здесь не упоминается, заключается в том, что приложения C # (или, может быть, только WPF) требуют, чтобы в манифесте приложения был установлен флаг uiAccess = true .В противном случае сообщения никогда не отправляются.Кроме того, есть препятствия Authenticode , чтобы разрешить это, и Visual Studio откажется запускать отладку, но вы можете подключить отладчик к работающему процессу.Надеюсь, что это поможет всем, кто заходит по этой теме.

0 голосов
/ 07 июля 2011

Отправка ответа на мой вопрос, потому что были сделаны комментарии о том, что это невозможно сделать.

Я не уверен, почему это не работает в C #, возможно, проблема с печатанием / приведением, может быть проблема с тем, как он обрабатывает lparam. В любом случае, я написал тот же код на c ++ и сделал его dll, поэтому теперь я вызываю функцию из dll с помощью обработчика управления и ввода, и он отправляет ввод соответствующим элементам управления. Использование windows api напрямую через c ++ работает нормально.

Спасибо за помощь.

...