ERROR_PROC_NOT_FOUND при вызове PInvoke для SendMessageW - PullRequest
2 голосов
/ 12 мая 2011

Мне нужно автоматизировать стороннюю программу, и единственное действие - смоделировать нажатие на некоторые кнопки.

Я делаю это, находя HWND дескриптор кнопки с EnumChildWindows. Когда я нашел «окно» (кнопка), я пытаюсь отправить ему BM_CLICK с помощью SendMessageW. Это работает, мои тесты показывают, что кнопка действительно думает, что она нажата.

Проблема возникает в моей обработке ошибок. Сообщение BM_CLICK не дает обратной связи, поэтому я не знаю, было ли оно нажато. Я думал, что должен быть усердным и проверить любые коды ошибок, хотя с Marshal.GetLastWin32Error.

Это возвращает ERROR_PROC_NOT_FOUND, что не совсем то, что я ожидал бы от успешной обработки сообщений.

Я импортирую SendMessageW следующим образом:

[DllImport("User32.dll", 
           CharSet = CharSet.Unicode, 
           CallingConvention = CallingConvention.Winapi, 
           SetLastError = true)]
public static extern IntPtr SendMessageW(
     HandleRef hWnd, 
     UInt32 Msg, 
     UIntPtr wParam, 
     IntPtr lParam);

Код звонка:

User32.SendMessageW(
    buttonHandle,
    (uint)ButtonControlMessages.BM_CLICK, // value of BM_CLICK = 0x00F5.
    UIntPtr.Zero,
    IntPtr.Zero);

int error = Marshal.GetLastWin32Error();
if (error != ErrorCodes.ERROR_SUCCESS) // love the name of this error code.
    throw new Win32Exception(error);

Мои тесты просто используют простые Windows Forms с прикрепленной кнопкой. Таким образом, я могу достать ручку через button.Handle. На него нажимают; может быть, эта ошибка совершенно не связана?

Конечно, было бы неплохо избавиться от этого, но я бы хотел каким-то образом быть уверенным, что вызов SendMessageW, по крайней мере, не закончился.

Я на Windows 7 x86-32 с .NET 4.

1 Ответ

3 голосов
/ 12 мая 2011

Соглашение о вызовах должно быть Stdcall, но, поскольку это значение по умолчанию, вы можете просто отбросить его.

Я думаю, что ваш SendMessage P / Invoke выглядит немного странно, но это, вероятно, не является причиной проблемы,В любом случае я бы сделал это так:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

Я думаю, что здесь происходит то, что SendMessage() работает, но не назначает последнюю ошибку.Единственное, что в документации для SendMessage() упоминается об ошибках:

Когда UIPI блокирует сообщение, последняя ошибка, полученная с помощью GetLastError, устанавливается равной 5 (доступ запрещен).

Возвращаемое значение для SendMessage() зависит от отправленного сообщения.В случае BM_CLICK, очевидно, сообщение не отправлено.Другими словами, вы просто не получаете никакой обратной связи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...