Программно нажмите кнопку на другом приложении (C, Windows)

Я закончил тем, что прокрутил свое собственное StaticServlet. Это поддерживает If-Modified-Since, gzip кодирование, и это должно быть в состоянии служить статическим файлам из военных файлов также. Это не очень трудный код, но это не совсем тривиально также.

код доступен: StaticServlet.java. Не стесняйтесь комментировать.

Обновление: Khurram спрашивает о ServletUtils класс, на который ссылаются в StaticServlet. Это - просто класс со вспомогательными методами, которые я использовал для своего проекта. Единственный метод, в котором Вы нуждаетесь, coalesce (который идентичен функции SQL COALESCE ). Это - код:

public static  T coalesce(T...ts) {
    for(T t: ts)
        if(t != null)
            return t;
    return null;
}

18
задан roalz 13 March 2017 в 19:32
поделиться

11 ответов

  1. Вы уверены, что имя класса «SaveButton» допустимо? Вы получили кнопку handle?
  2. Попробуйте отправлять сообщения в окно ButtonHandle (прямо на кнопку).

Обновление: Я считаю, что это должно работать,

SendMessage(ButtonHandle, BM_CLICK, 0, 0);
19
ответ дан 30 November 2019 в 07:56
поделиться

, возможно, это может помочь: http://www.cplusplus.com/forum/beginner/8806/

2
ответ дан 30 November 2019 в 07:56
поделиться
SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);
SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);

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

3
ответ дан 30 November 2019 в 07:56
поделиться

См. Следующее решение, также вы можете использовать

SendMessage(ButtonHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(ButtonHandle, WM_LBUTTONUP, 0, 0);

или

SendMessage(ButtonHandle, BM_CLICK, 0, 0);

HWND buttonHandle = 0;

BOOL CALLBACK GetButtonHandle(HWND handle, LPARAM)
{
 char label[100];
 int size = GetWindowTextA(handle,label,sizeof(label));
 if(strcmp(label,"&Save") == 0)
 {
  buttonHandle = handle;
  return false;
 }
 return true;
}
void main()
{
 HWND windowHandle = FindWindowA(NULL,"Do you want to Save?");
 if(windowHandle != 0)
 {
  BOOL ret = EnumChildWindows(windowHandle,GetButtonHandle,0);

  if(buttonHandle != 0)
  {
   LRESULT res = SendMessage(buttonHandle,BM_CLICK,0,0);
   //SendMessage(buttonHandle,WM_LBUTTONDOWN,0,0); 
   //SendMessage(buttonHandle,WM_LBUTTONUP,0,0);
  }

 }



}

Примечание: Убедившись в тексте окна, тексте кнопки (проверьте, есть ли пробел в конце заголовка окна)

2
ответ дан 30 November 2019 в 07:56
поделиться

Ошибки отказа в доступе в SendMessage или PostMessage не имеет смысла, если процесс, отправляющий сообщение, не работает с более низким уровнем целостности, чем целевой процесс.

Этого не должно происходить, если процесс, которому принадлежит целевое окно, не запускается «как администратор» или является службой. А службам чертовски сложно создавать окна на интерактивном рабочем столе в Windows 6.

Вы можете прочитать о Уровнях целостности здесь , если они применяются даже удаленно в этой ситуации. Internet Explorer - единственное другое приложение, которое "выбирает"

2
ответ дан 30 November 2019 в 07:56
поделиться

Если вы можете поднять окно, содержащее кнопку, вы можете отправить необработанное событие мыши в позицию в пределах кнопки.

Есть две функции для имитации события мыши SendInput и mouse_event . Я рекомендую использовать функцию mouse_event . Чтобы поднять окно, вы можете использовать ShowWindow . Я не знаю, как получить дескриптор кнопки, но если у вас есть ее hWnd, ее абсолютное положение легко найти с помощью функции GetWindowRect . Попробуйте использовать их, если у вас возникнут проблемы, я буду рад помочь.

Или определите собственный WM в своем приложении окно для обработки запроса на сохранение. WM_CUSTOM или WM_USER (не могу вспомнить, какой) отмечает начало пользовательских оконных сообщений.

1
ответ дан 30 November 2019 в 07:56
поделиться

Когда мне нужно делать такие вещи, я использую SendKeys. Это VB-стиль, и C # предоставляет удобный интерфейс, но для C / C ++ вам придется сделать это < таким образом >. Что в нем приятно, так это то, что вы можете писать сценарии и запускать их вместо жесткого кодирования в своем коде.

1
ответ дан 30 November 2019 в 07:56
поделиться

Вы можете использовать sendkeys (как сказано в tr3) для отправки щелчков мышью, что отличается от использования SendMessage. Он также менее прямой и более хакерский, но полезен для автоматизации (в VBS).

Кроме того, всего лишь предположение, но проблема может заключаться в том, что ваша обработка сообщений где-то нарушена из-за того, что не вызывается член базового класса. Пример:

void CMyClass::OnMessageY(CWnd *cwnd)
{
    CBaseClass::OnMessageY(cwnd);
    //... my code
}
0
ответ дан 30 November 2019 в 07:56
поделиться

если вы уверены, что ButtonHandle - действительный дескриптор, вы можете использовать пару сообщений WM_LBUTTONDOWN и WM_LBUTTONUP вместо сообщения BN_CLICKED

HWND ButtonHandle;
if( (wnd = FindWindow(0, "Do you want to save?")) )
{   
    SendMessage(ButtonHandle, WM_LBUTTONDOWN, MK_LBUTTON, 0);
    SendMessage(ButtonHandle, WM_LBUTTONUP, MK_LBUTTON, 0);
}
0
ответ дан 30 November 2019 в 07:56
поделиться

Подход, не связанный с C: используйте Java и класс java.awt.Robot для перемещения курсора мыши выполнять настоящие щелчки (думаю, в мире Windows для этого тоже есть что-то). Проблема: вы должны знать, где находится ваша кнопка: D

0
ответ дан 30 November 2019 в 07:56
поделиться

Microsoft теперь продвигает Active Accessibility (MSAA) для автоматизации пользовательского интерфейса, (За прошедшие годы его несколько раз переименовывали) см.

К сожалению, у меня нет простого кода, с которого можно начать. Поскольку «SendMessage ()», похоже, не работает для вас, я не знаю другого варианта, кроме «UI Automation»

, я предполагаю, что вы проверили с помощью Spy ++ (установленного с MsDev), что вы отправляете сообщение отправить на правильную кнопку и т. д. - и эта кнопка является стандартными кнопками Windows. Мое первое мгновение сказал бы использовать «SendMessage ()» или «PostMessage ()», но учитывая количество ответов о «SendMessage ()» и тот факт, что он не работает для вас. Я ожидаю, что кто-то идет…

1
ответ дан 30 November 2019 в 07:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: