Что нового

Послать комманду в contextmenu

wisenlucky

Новичок
Сообщения
36
Репутация
0
Добрый день.

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

Вариант 1:
Код:
Mouseclick("Left",$TargetWindowX,$TargetWindowY,1,5)
Sleep(250)
Mouseclick("Right",$TargetWindowX,$TargetWindowY,1,5)
Sleep(250)
Mousemove($TargetWindowX+20,$TargetWindowY+100,10)
Sleep(250)
Mouseclick("Left",$TargetWindowX+20,$TargetWindowY+100,2,5)
sleep(250)


Вариант 2:
Код:
Mouseclick("Left",$TargetWindowX,$TargetWindowY,1,5)
Sleep(250)
Send('+{F10}')
Sleep(250)
Send('v'); shortcut к нужному мне пункту меню
sleep(250)
send("{ENTER}")


Вариант 3: Комбинации предыдущих, дублирование комманд, увеличение sleep()

В целом оба варианта работают, но примерно 1 из 10 сбоит (вызывается контекстное меню, но не выбирается нужный пункт или выбираем, но почему-то не нажимается).

Какие есть варианты, чтобы заставить подобный скрипт работать со 100% надежностью?
У меня появилась мысль вызвать контекстное меню и послать команду через winapi функции. Но не могу понять как через ControlViewer получить handle контекстного меню - ведь когда я нажимаю на ControlViewer контекстное меню закрыватся. Спасите, пожалуйста, мой мозг от взрыва. Он может быть ещё полезен для сообщества.
 

---Zak---

Скриптер
Сообщения
455
Репутация
120
Тут недавно в фирме перенастраивал "Mozilla Thunderbird"

Мышкой тыркать я не стал, но суть в следующем - все/большинство меню имею привязку к кнопкам (ALT+?)
3w7gqEAESNU.jpg

Допустим хотит попасть в "Инструменты" - нужно отправить "ALT+и"
А чтобы попасть дальше в "Параметры учетной записи..." - "ALT+м"

В итоге у меня получилось зайти в меню через:
Код:
ControlSend("Mozilla Thunderbird", "", "", "{ALT}+и+м")


ЗЫ: ну вдруг чем помогу))))
 
Автор
W

wisenlucky

Новичок
Сообщения
36
Репутация
0
Ну у меня это описано в варианте 2. Через shortcut (Shift+F10) вызывал меню, а потом V = вызывает "View Source". но этот вариант тоже не работает в 100% :(
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
wisenlucky [?]
В последнем MouseClick() отсутствует +20 и мышь смещается влево. Попробуйте вообще убрать координаты. Тогда клик будет в текущей точке, куда мышь уже перемещена
Код:
Mouseclick("Left")

Вариант 2: ... Вариант 3: ...
Без самой программы сложно что-то сказать.

Для ожидания окна с меню используйте
Код:
WinWait("[class:#32768]")

А handle контекстного меню можно получить так
Код:
_SendMessage(WinGetHandle("[class:#32768]"), 0x01E1, 0, 0) ;MN_GETHMENU
и потом использовать его в функциях GuiMenu.au3
 
Автор
W

wisenlucky

Новичок
Сообщения
36
Репутация
0
Попробуйте вообще убрать координаты. Тогда клик будет в текущей точке, куда мышь уже перемещенаКод:
Код:
Mouseclick("Left")
Разве не надёжней прописывать координаты, на случай - если вдруг случайно сдвинул мышь?

А что значит этот параметр?

_SendMessage(WinGetHandle("[class:#32768]"), 0x01E1, 0, 0) ;MN_GETHMENU
- эта команда почему-то возвращает 0 :(
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
wisenlucky [?]
Разве не надёжней прописывать координаты, на случай - если вдруг случайно сдвинул мышь?
Ну, это риторический вопрос... при написании координат можно ошибиться ;)
эта команда почему-то возвращает 0
Может у вас меню нестандартное?
Запустите Au3Info.exe, отключите опцию "Options -> Freeze (Ctrl+Alt+F)", вызовите контекстное меню и наведите на него курсор мыши. Если класс окна не #32768, то меню нестандартное.
 
Автор
W

wisenlucky

Новичок
Сообщения
36
Репутация
0
Может у вас меню нестандартное?
Запустите Au3Info.exe, отключите опцию "Options -> Freeze (Ctrl+Alt+F)", вызовите контекстное меню и наведите на него курсор мыши. Если класс окна не #32768, то меню нестандартное.
Стандартное. Спасибо за совет с отключением Freeze ;)
Класс окна #32768. Просто я пробовал увидиеть это значение через
Код:
MsgBox()
, а сработало только через
Код:
ConsoleWrite()
:stars:

А подскажите ещё пожалуйста такой момент. Мое меню имеет такой вид:
doJKcN6.png
.
Нужно выбрать четвертый пункт (View Source). Какую функцию из библиотеки GuiMenu.au3 стоит использовать?
Сам пока не смог разобраться.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
wisenlucky [?]
нужно выбрать четвертый пункт (View Source). Какую функцию из библиотеки GuiMenu.au3 стоит использовать.
Никакую :smile: Готовой функции в этой библиотеке нет.
Варианты:
1. Узнать координаты при помощи _GUICtrlMenu_GetItemRect() и кликнуть мышью.
2. Узнать ассоциативное значение при помощи _GUICtrlMenu_GetItemData() и отправить его программе через SendMessage().
3. Или просто
Код:
WinWait("[class:#32768]")
Send("{down 4}{enter}")
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
wisenlucky
Еще можно попробовать такую функцию:
Код:
WinMenuSelectItem()

В справке пример есть.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Yuriy [?]
Еще можно попробовать такую функцию:
Данная функция работает только в главном меню приложения (если оно есть). Во всплывающем меню - не работает.
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
InnI
Ну да. У автора первая строка кода - клик левой кнопки.
Вот я и подумал про обычное меню.
 
Автор
W

wisenlucky

Новичок
Сообщения
36
Репутация
0
InnI сказал(а):
Я думаю, он так окно активирует. Т.к. правой он кликает в этом же месте.
Именно так.

Буду разбираться с этими вариантами:
InnI сказал(а):
Варианты:
1. Узнать координаты при помощи _GUICtrlMenu_GetItemRect() и кликнуть мышью.
2. Узнать ассоциативное значение при помощи _GUICtrlMenu_GetItemData() и отправить его программе через SendMessage().
т.к. Send, Mouseclick не всегда срабатвают. Спасибо за наводку :ok: Хотя
...кликнуть мышью...
смущает. Думаю могу получить тот же результат.


Добавлено:
Сообщение автоматически объединено:

Кажется придумал решение.
После выбора пункта меню должно появится новое окно. Далее у меня используется функция
Код:
Winwait()
. И скрипт висит, если окно так и не открылось.
Вместо этого сделаю цикл в котором буду использовать функцию
Код:
WinExists()
. Если в течение нескольких попыток окно так и не появится - повторю процедуру с тыканием мыши. :smile:
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
wisenlucky [?]
Если в течение нескольких попыток окно так и не появится
У функции WinWait() третий параметр - время ожидания окна. Фактически это тоже самое, что несколько попыток WinExists(). Частота опроса настраивается через
Код:
Opt("WinWaitDelay", 250)
 
Верх