Нажмите кнопку «ОК» в окне сообщения, используя WINAPI в С#.

Я пытаюсь нажать кнопку "ОК" в окне сообщения формы окна С# с помощью winapi. Ниже приведен код, над которым я работаю.

private const int WM_CLOSE = 16;
private const int BN_CLICKED = 245;

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

[DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  string  windowTitle);

//this works
hwnd = FindWindow(null, "Message");
if(hwnd!=0)
      SendMessage(hwnd, WM_CLOSE, 0, IntPtr.Zero);

//this doesn't work.
hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "Button", "ok");
SendMessage((int)hwndChild, BN_CLICKED, 0, IntPtr.Zero);

Хотя я получаю значение в hwndChild, оно не распознает BN_CLICKED. Я не уверен, что мне не хватает. любая помощь?

Я пытаюсь закрыть кнопку окна сообщения другого приложения, и это то, что я делаю. Но я все еще что-то упускаю.

IntPtr hwndChild = IntPtr.Zero;
hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero,' '"Button", "OK");
SendMessage((int)hwndChild, WM_COMMAND, (BN_CLICKED '<<16) | IDOK, hwndChild);

person Virus    schedule 19.02.2013    source источник
comment
Поскольку вы используете C#, вы также можете использовать пространство имен System.Windows.Automation. Вот пример, когда нажимает кнопку 7 в калькуляторе. Просто измените Калькулятор на Сообщение и 7 на ОК.   -  person Raymond Chen    schedule 19.02.2013


Ответы (2)


BN_CLICKED — это не сообщение. Вам необходимо отправить сообщение WM_COMMAND, содержащее уведомление BN_CLICKED и идентификатор кнопки в wParam и дескриптор кнопки в lParam.

Родительское окно кнопки получает этот код уведомления через сообщение WM_COMMAND.

private const uint WM_COMMAND = 0x0111;
private const int BN_CLICKED = 245;
private const int IDOK = 1;

[DllImport("user32.dll", CharSet=CharSet.Auto)]
        public static extern int SendMessage(IntPtr hWnd, uint msg, int wParam, IntPtr lParam);

[DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  string  windowTitle);

SendMessage(hwndChild, WM_COMMAND, (BN_CLICKED << 16) | IDOK, hwndChild);
person Dark Falcon    schedule 19.02.2013
comment
Не могли бы вы привести пример? Я плохо разбираюсь в этом. и как WM_CLOSE работает с отправкой сообщения. - person Virus; 19.02.2013
comment
@Virus: Потому что WM_CLOSE — это сообщение, как и WM_COMMAND. Как я уже заметил, BN_CLICKED не является сообщением. Пожалуйста, смотрите пример. - person Dark Falcon; 19.02.2013

Наконец, это работает для меня. Первый щелчок, вероятно, активирует окно, а второй щелчок нажимает кнопку.

SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);
SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);
person Virus    schedule 19.02.2013
comment
Спасибо, у меня возникла проблема с нажатием кнопки внутри диалогового окна. Ваше решение щелкнуть дважды помогло мне. Как вы сказали, 1-й щелчок активирует окно, а второй - отправляет сообщение, чтобы щелкнуть. - person Peter M.; 12.12.2014