Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.17.173.165] |
|
Сообщ.
#1
,
|
|
|
в оутлуке при попытке получить почтовый адрес элемента вылезает окошко с сообщением, что возможно вирус пытается получить доступ, бла-бла-бла....
хочу это окно закрыть средствами своей программы. Ищу это всплывающее окно, ищу кнопку на этом окне и шлю BM_CLICK. Но ничего не происходит. делаю так: var hMainWnd, hChildWnd: THandle; begin hMainWnd := FindWindow(PAnsiChar('#32770'), PAnsiChar('Microsoft Outlook')); // ищем это окно с сообщением SetActiveWindow(hMainWnd); // ищем кнопку Разрешить и нажимаем ее hChildWnd := FindWindowEx(hMainWnd, 0, PAnsiChar('Button'), PAnsiChar('Разрешить')); // нажимаем SendMessage(hChildWnd, BM_CLICK, 0, 0); // так не срабатывает // так тоже не срабатывает SendMessage(hChildWnd, WM_LBUTTONDOWN, 1, 1); SendMessage(hChildWnd, WM_LBUTTONUP, 1, 1); Отладчиком все вижу - все хендлы получаю нормально. К тому же тут я сократил текст. Там у меня еще и чекбокс переключается и в комбобоксе выбирается максимальное кол-во минут на разрешение. Все это отрабатывает отлично. А вот кнопка нажиматься не хочет. Даже sleep(500) после SetActiveWindow добавлял - реакция та же, т.е. никакая. Лазание по интернетам ничего не дало. Кто-то либо 2 раза посылает BM_CLICK, кто-то шлет DOWN-UP и у всех в итоге срабатывает... Причем правильный вариант именно BM_CLICK, т.к. делает именно DOWN-UP и еще изменяет св-во кнопки на "нажатую" ЧЯДНТ? Добавлено вот здесь у человека один в один проблема с закрытием этого дебильного окна оутлука и в итоге он ее решил с помощью SendInput. Я сделал так (по примеру отсюда): var TmpRect: TRect; TI: TInput; MI: TMouseInput; begin .... // <-- здесь вышеописанный код с получением хендла главного окна и нужной кнопки // ставлю курсор на кнопку GetWindowRect(hChildWnd, TmpRect); // ищу глобальные координаты кнопки SetCursorPos(TmpRect.Left + 10, TmpRect.Top + 10); // ставлю курсор на нее // посылаю нажатие и отпускание мышки над кнопкой MI.dx := TmpRect.Left; MI.dy := TmpRect.Top; MI.mouseData := 0; MI.dwFlags := MOUSEEVENTF_RIGHTDOWN ; MI.time := 10; TI.mi := MI; TI.Itype := INPUT_MOUSE; SendInput(1, TI, SizeOf(TInput)); MI.dwFlags := MOUSEEVENTF_RIGHTUP; TI.mi := MI; SendInput(1, TI, SizeOf(TInput)); результат опять нулевой |
Сообщ.
#2
,
|
|
|
Цитата Voice @ Я сделал так (по примеру отсюда): Пример корявый. Во-первых, тебе нужен не правый клик, а левый - MOUSEEVENTF_LEFTDOWN. Во-вторых, явный косяк в задании координат dx,dy, т.к. по умолчанию в SendInput они означают смещение курсора относительно текущего положения. Поэтому после SetCursorPos нужно задавать dx=dy=0. А для задания абсолютных координат нужны доп.извращения с добавлением флага MOUSEEVENTF_ABSOLUTE и вычислением нормализованных значений dx:=(TmpRect.Left * 65535) div GetSystemMetrics(SM_CXFULLSCREEN) и аналогично dy. В-третьих, доп.мелочи - MI.time лучше устанавливать в 0 или =GetTickCount, и MI.dwExtraInfo:=0. К тому же, не мешало бы добавить некую реальную задержку типа Sleep(100) между посылкой нажатия и отжатия, т.к. если прога ругается на то, "что возможно вирус пытается получить доступ" и не реагирует на BM_CLICK из другого потока, не исключено, что в ней реализована некая защита от примитивных программных нажатий (античит). Но и это может не помочь, если прога различает реальные и программные нажатия через RawInput или низкоуровневый хук на мышиные клики. PS: В данном случае вместо SendInput проще использовать mouse_event. |
Сообщ.
#3
,
|
|
|
Цитата Voice @ хочу это окно закрыть средствами своей программы. Ищу это всплывающее окно, ищу кнопку на этом окне и шлю BM_CLICK. Но ничего не происходит. А если попробовать послать найденному окошку WM_CLOSE ? |
Сообщ.
#4
,
|
|
|
Цитата leo @ Во-первых, тебе нужен не правый клик, а левый - MOUSEEVENTF_LEFTDOWN точно! проглядел... Цитата leo @ Во-вторых, явный косяк в задании координат dx,dy, т.к. по умолчанию в SendInput они означают смещение курсора относительно текущего положения. Поэтому после SetCursorPos нужно задавать dx=dy=0 поставил смещение 0. Теперь заработало, кнопка нажалась, окно закрылось. Спасибо Цитата ЫукпШ @ А если попробовать послать найденному окошку WM_CLOSE ? тогда оутлук не даст прочитать свойства объектов, которые запрашивает мое приложение Остается непонятым, почему BM_CLICK не срабатывает... |
Сообщ.
#5
,
|
|
|
Цитата Voice @ Остается непонятым, почему BM_CLICK не срабатывает... Я же сказал, что это м.б. защита от программных нажатий из других потоков\приложений. Для этого достаточно сделать простой сабклассинг кнопки и в её оконной процедуре проверять, было ли послано сообщение из своего потока или из чужого с помощью функции InSendMessage - если из своего, то сообщение передается в оригинальную\дефолтную процедуру окна кнопки, а если из чужого - просто игнорируется, не обрабатывается. |