Программно нажмите кнопку на другом приложении (C, Windows)
Я пытаюсь использовать следующий код, чтобы нажать кнопку в другом приложении:
HWND ButtonHandle;
if( (wnd = FindWindow(0, "Do you want to save?")) )
{
ButtonHandle = FindWindowEx(wnd, 0, "SaveButton", "&Save");
SendMessage(wnd, WM_COMMAND, MAKEWORD(GetDlgCtrlID(ButtonHandle), BN_CLICKED ), (LPARAM)ButtonHandle);
}
Это не работает. Я попробовал передать разные ручки в MAKEWORD и изменить WPARM и LPARAM, но ничего.
Любые идеи о том, как нажать кнопку в другом окне приложения?
Код оценен.
Спасибо.
EDIT:
Причина, по которой он не работает, разрешает работать. Я отправил PostMessage(), и результатом была ошибка с GetLastError() = 5 (или Access Denied).
Любые идеи?
EDIT2 Я не хочу быть грубым, но, пожалуйста, пожалуйста, я уже искал все API, включая получение и настройку регионов для кнопки, а затем отправку кнопки вниз и кнопку вверх, получение идентификатор управления, получение идентификатора класса и еще миллион.
Причина, по которой я задал этот вопрос, в первую очередь, состоит в том, что я уже исчерпал свой поиск в Интернете.
Если вы знаете ответ PLEASE POST CODE, не предлагайте API и его, покажите мне, как этот API решает проблему. Это не сложно.
Спасибо.
РЕДАКТИРОВАТЬ 3: Ответ на вопрос был выбран автоматически, когда награда закончилась. Вопрос остается без ответа.
Ответы
Ответ 1
- Вы уверены, что имя класса "SaveButton" действительно? Вы получаете кнопку
ручка?
- Попробуйте отправить сообщения в окно ButtonHandle (прямо на кнопку).
Обновление: Я считаю, что это должно работать,
SendMessage(ButtonHandle, BM_CLICK, 0, 0);
Ответ 2
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
возможно, это может помочь:
http://www.cplusplus.com/forum/beginner/8806/
Ответ 4
См. следующее решение, также вы можете использовать
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);
}
}
}
Примечание:
Убедитесь, что текст окна, текст кнопки (проверьте, есть ли место в конце заголовка окна)
Ответ 5
Отказано в доступе к ошибкам в SendMessage или PostMessage, не имеет смысла, если процесс отправки сообщения не выполняется на более низком уровне целостности, чем целевой процесс.
Это не должно происходить, если процесс, которому принадлежит целевое окно, запускается "asAdministrator" или является службой. И его чертовски сложно обслуживать создание окон на интерактивном рабочем столе с Windows 6 и выше.
Вы можете немного прочитать о Уровнях целостности здесь, если они применимы даже в отдаленной ситуации к этой ситуации. Internet Explorer - единственное другое приложение, которое "выбирает" в модели безопасности целостности, намеренно снижая уровень целостности самого себя, чтобы более эффективно работать с песочницей.
Ответ 6
Если вы можете поднять окно, содержащее кнопку, вы можете отправить необработанное событие мыши в позицию в пределах границ кнопки.
Есть две функции для имитации события мыши SendInput и mouse_event
. Я рекомендую использовать функцию mouse_event
. Чтобы поднять окно, вы можете использовать ShowWindow. Я не знаю, как получить ручку кнопки, но если у вас есть hWnd, легко найти ее абсолютное положение, используя GetWindowRect, Попробуйте использовать их, если у вас возникнут какие-либо проблемы, я буду рад помочь.
Или определите пользовательский WM в своем окне приложения для обработки запроса на сохранение. WM_CUSTOM
или WM_USER
(не помню, какой из них) обозначает начало пользовательских оконных сообщений.
Ответ 7
Когда я должен делать такие вещи, я использую SendKeys. Это VB-ish, а С# - хороший интерфейс для использования, но для C/С++ вам придется это сделать < таким образом > , Приятно, что вы можете писать сценарии и запускать их вместо жесткого кодирования в своем коде.
Ответ 8
Microsoft теперь предлагает Active Accessibility (MSAA) для автоматизации пользовательского интерфейса,
(Он был переименован несколько раз за эти годы)
см.
Извините, у меня нет простого кода, чтобы вы начали. Поскольку "SendMessage()" , похоже, не работает для вас, я не знаю другого варианта, кроме "Автоматизации пользовательского интерфейса"
Я предполагаю, что вы проверили с Spy ++ (установленным с MsDev), что вы отправляете сообщение правильной кнопке и т.д., и что кнопка является стандартными кнопками Windows. Мое первое мгновение скажет использование "SendMessage()" или "PostMessage()", но с учетом числа ответов о "SendMessage()" и факте, что он не работает для вас. Я ожидаю, что кто-то продолжит...
Ответ 9
Вы можете использовать sendkeys (как указано tr3) для отправки щелчков мыши, что отличается от использования SendMessage. Он также менее прямой и более хакерский, но полезен для автоматизации (в VBS).
Кроме того, просто догадка, но проблема может заключаться в том, что некоторая ошибка обработки сообщений не вызвана тем, что вы не вызываете элемента базового класса. Пример:
void CMyClass::OnMessageY(CWnd *cwnd)
{
CBaseClass::OnMessageY(cwnd);
//... my code
}
Ответ 10
если вы уверены, что 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);
}
Ответ 11
Не-C-подход: используйте Java и класс java.awt.Robot, чтобы переместить мышь вокруг реальных кликов (я думаю, в этом тоже есть что-то в Windows World).
Проблема: вы должны знать, где находится ваша кнопка: D