Тема: AHK: Активировать приложения на панели задач при наведении курсора.
Навел на значок и приложение моментально активировалось/открылось, будто по нему кликнули.
Возможно ли сделать такое?
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Серый форум → Общение → AutoHotkey → AHK: Активировать приложения на панели задач при наведении курсора.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Навел на значок и приложение моментально активировалось/открылось, будто по нему кликнули.
Возможно ли сделать такое?
По-моему, от этого будет больше проблем, чем пользы. Можно ведь случайно навести.
teadrinker
У меня в Firefox вкладки активируются моментально при наведении и это фантастически удобно, ложные срабатывания бывали, но эргономичность повысилась в разы, поэтому давно уже мечтал сделать аналогичное с панелью задач, но не знал, что AutoHotkey на это способен. Подойдет, конечно же, это не всем, так-же как и пользователям, открывающим по сотне вкладок, не подойдет Auto Activate Tabs.
Malcev
Спасибо, как я предполагал, кто-то уже реализовал такую полезную фичу. Скрипт работает неплохо, но есть некоторые огрехи.
1) Если кого не затруднит, могли бы убрать из скрипта все, кроме клика по панели задач?
2) Возможно ли сделать так, чтобы программы не сворачивались, а только активировались и запускались?
3) И можно ли оставить только один клик по панели задач, сейчас кликает по мере остановок при движении курсора и из-за этого весьма не комфортно, часто приложение активируется/сворачивается одновременно. У меня hover_delay = 20, т.к. нужно чтобы активация была моментальной, ведь в этом весь смысл.
Так подойдёт?
#Persistent
OnExit, Exit
prID := -1
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
hHookMouse := DllCall("SetWindowsHookEx" . (A_IsUnicode ? "W" : "A")
, Int, WH_MOUSE_LL := 14
, Int, RegisterCallback("LowLevelMouseProc", "Fast")
, Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr)
, UInt, 0, Ptr)
Return
Exit:
DllCall("UnhookWindowsHookEx", Ptr, hHookMouse)
ExitApp
LowLevelMouseProc(nCode, wParam, lParam) {
Critical
If wParam = 512
SetTimer, MouseGet, -10
Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam)
}
MouseGet:
MouseGetPos, , , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := -1
Else If ((ID := AccIDUnderMouse()) && ID != prID && (prID := ID))
{
WinActivate % "ahk_id" hShellTray
SendInput ^{LButton}{LControl Up}
}
Return
AccIDUnderMouse() {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) = 0
Return NumGet(varChild,8,"UInt")
}
Хотя зачем так усложнять, если вас и с таймером устраивало:
#Persistent
prID := -1
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
MouseGet:
MouseGetPos, , , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := -1
Else If ((ID := AccIDUnderMouse()) && ID != prID && (prID := ID))
{
WinActivate % "ahk_id" hShellTray
SendInput ^{LButton}{LControl Up}
}
SetTimer, MouseGet, -10
Return
AccIDUnderMouse() {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) = 0
Return NumGet(varChild,8,"UInt")
}
serzh82saratov
К сожалению не работает, не первый, не второй, может потому что у меня Win8.1x64, AutoHotkey v1.1.15.00 (Unicode 64-bit)?
Не знаю, 8 нет.
#Persistent
prID := -1
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
MouseGet:
MouseGetPos, , , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := -1
Else If ((ID := AccIDUnderMouse()) && ID != prID && (prID := ID))
{
WinActivate % "ahk_id" hShellTray
SendInput ^{LButton}{LControl Up}
}
Else If !ID
prID := -1
SetTimer, MouseGet, -10
ToolTip % "ID: " ID
Return
AccIDUnderMouse() {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) = 0
Return NumGet(varChild,8,"UInt")
}
serzh82saratov
Раз скрипт с autohotkey.com работает, значит названия элементов не изменились, правда, у Вас скрипт сложнее. Tooltip-а нет, просто скрипт не запускается, мелькнет в трее и исчезает.
просто скрипт не запускается, мелькнет в трее и исчезает.
Всё время забываю, в любой из скриптов добавь первой строкой:
#Persistent
Я поправил примеры.
serzh82saratov
Ого, идеально, спасибо огромное! И кликает только по иконкам, а не везде, и не сворачивает. На первый взгляд, полный аналог Auto Activate Tabs в Firefox получился.
Немного поправил.
#Persistent
prID := -1
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
MouseGet:
MouseGetPos, , , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := -1
Else If ((ID := AccIDUnderMouse()) && ID != prID && (prID := ID))
{
WinActivate % "ahk_id" hShellTray
SendInput ^{LButton}{LControl Up}
}
Else If !ID
prID := -1
SetTimer, MouseGet, -10
Return
AccIDUnderMouse() {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) = 0
Return NumGet(varChild,8,"UInt")
}
правда, у Вас скрипт сложнее.
А чем сложнее? Пытался упростить, и букафф меньше.
serzh82saratov
Просто это мне, как нубу, не знакомы многие моменты.
Может поможете со скриптом, посылающим один клик при наведении курсора в плейлист Media Player Classic? Пытался сделать что-то вроде этого, но клик залипает.
Loop, 2
{
ControlClick, SysListView322, ahk_class MPC-BE,, Left, 1, NA
Sleep, 10
}
Просто это мне, как нубу, не знакомы многие моменты.
Это и странно, что на взгляд новичка код Lexikos выглядит проще.
Может поможете со скриптом, посылающим один клик при наведении курсора в плейлист Media Player Classic?
У меня такого плеера то нет, но если разберётесь в коде, то всё аналогично.
Запустите этот скрипт, им наглядно видно и AccessibleObject, и остальное необходимое.
SendInput ^{LButton}{LControl Up}
А почему не просто Send {LButton} ?
Ещё (минус?) в том, что кликает не только по кнопкам окон, но и по иконкам быстрого запуска.
А почему не просто Send {LButton} ?
Открой например в проводнике несколько окон, когда у одной кнопки несколько окон, клика будет недостаточно.
Ещё (минус?) в том, что кликает не только по кнопкам окон, но и по иконкам быстрого запуска.
Я так понял что это нужно ТС.
ап:
Если не нужно, то можно проверять в "русиш винде" "АссState = отслеженное" для иконки.
Ясно.
Если не нужно, то можно проверять в "русиш винде" "АссState = отслеженное" для иконки.
А у меня у иконки State — "обычный".
Send
SendInput и SendPlay [с версии 1.0.43]: SendInput и SendPlay используют тот же синтаксис, что и Send, но работают, как правило, быстрее и более надёжно. Кроме того они буферизуют физические нажатия на клавиши и кнопки мыши, которые происходят во время посылки, что не позволяет нажатиям пользователя смешиваться с теми, которые посылает скрипт.
{LControl Up}
Иногда Control залипает, редко но бывает.
А у меня у иконки State — "обычный".
Через Accessible Info Viewer - то обычный.
Через AhkSpy - то отслеженное.
Зависит от того каким кодом извлекаешь. Хотя помнится я всё копировал из Accessible Info Viewer, вообщем можно копать, а можно и не копать, результаты в этих скриптах хоть и отличаются, но стабильно.
А да, кажется в оригинале берётся State - у Parent, у меня из Child.
#Persistent
prID := -1
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
MouseGet:
MouseGetPos, , , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := -1
Else If ((ID := AccIDUnderMouse(accObj)) && ID != prID && (prID := ID))
{
TrayTip, State, % AccGetStateText(accObj.accState(ID))
}
Else If !ID
prID := -1
SetTimer, MouseGet, -10
Return
AccIDUnderMouse(ByRef accObj) {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) = 0
Return NumGet(varChild,8,"UInt"), accObj := ComObjEnwrap(9,pacc,1)
}
AccGetStateText(nState)
{
nSize := DllCall("oleacc\GetStateText", "Uint", nState, "Ptr", 0, "Uint", 0)
VarSetCapacity(sState, (A_IsUnicode?2:1)*nSize)
DllCall("oleacc\GetStateText", "Uint", nState, "str", sState, "Uint", nSize+1)
Return sState
}
Статус меняется при наведении на иконку несколько раз подряд, иногда "отслеженное", иногда "обычный", чаще всего через раз.
serzh82saratov
Спасибо, AhkSpy удобнее стандартного, вот что наваял, но ahk_id непостоянный у MPC. И не получилось, что хотелось, проблема в том, что, когда обращаешься к плееру и наводишь курсор на плейлист, он регулирует громкость, а не скроллит файлы, нужно единожды кликнуть по нему, а этот код многократно кликает при быстром прокручивании и получается двойной клик, который запускает файл.
Можно было бы использовать АНК: Прокрутка окна под курсором мыши без активации окна, но мне не подходит, т.к. колесо во многих программах переназначено.
#Persistent
prID := -1
0xa04f6 := WinExist("ahk_class MPC-BE ahk_exe mpc-be64.exe")
ControlGet, hTaskbar, HWND,, SysListView322, % "ahk_id" 0xa04f6
DllCall("LoadLibrary","Str","oleacc","Ptr")
MouseGet:
MouseGetPos, , , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := -1
Else If ((ID := AccIDUnderMouse()) && ID != prID && (prID := ID))
{
WinActivate % "ahk_id" 0xa04f6
SendInput ^{LButton}
}
Else If !ID
prID := -1
SetTimer, MouseGet, -10
Return
AccIDUnderMouse() {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) = 0
Return NumGet(varChild,8,"UInt")
}
Статус меняется при наведении на иконку несколько раз подряд, иногда "отслеженное", иногда "обычный", чаще всего через раз.
OFF: Кстати, отсюда вывод: если в скриптах используются значения State и Role, то лучше пользоваться не их текстовой интерпретацией, а непосредственно константами, получаемыми через accState и accRole, чтобы скрипт не зависел от языка системы.
Интересно, а пример можно? Непойму, как эти константы извлекаются.
Так вот же:
#Persistent
SetFormat, IntegerFast, H
prID := -1
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
MouseGet:
MouseGetPos, , , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := -1
Else If ((ID := AccIDUnderMouse(accObj)) && ID != prID && (prID := ID))
{
TrayTip, State, % accObj.accState(ID)
}
Else If !ID
prID := -1
SetTimer, MouseGet, -10
Return
AccIDUnderMouse(ByRef accObj) {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) = 0
Return NumGet(varChild,8,"UInt"), accObj := ComObjEnwrap(9,pacc,1)
}
Или вместе с Role:
#Persistent
SetFormat, IntegerFast, H
prID := -1
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
MouseGet:
MouseGetPos, , , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := -1
Else If ((ID := AccIDUnderMouse(accObj)) && ID != prID && (prID := ID))
{
TrayTip, State, % "State = " . accObj.accState(ID) . "`nRole = " . accObj.accRole(ID)
}
Else If !ID
prID := -1
SetTimer, MouseGet, -10
Return
AccIDUnderMouse(ByRef accObj) {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) = 0
Return NumGet(varChild,8,"UInt"), accObj := ComObjEnwrap(9,pacc,1)
}
Так вот же
Ну, что тут скажешь.
Немного поправил.
#Persistent prID := -1 hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe") ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray DllCall("LoadLibrary","Str","oleacc","Ptr") MouseGet: MouseGetPos, , , , hCtrl, 2 If (hCtrl != hTaskbar) prID := -1 Else If ((ID := AccIDUnderMouse()) && ID != prID && (prID := ID)) { WinActivate % "ahk_id" hShellTray SendInput ^{LButton}{LControl Up} } Else If !ID prID := -1 SetTimer, MouseGet, -10 Return AccIDUnderMouse() { If DllCall("oleacc\AccessibleObjectFromPoint" , "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc , "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) = 0 Return NumGet(varChild,8,"UInt") }
Спасибо большущее за этот скрипт, с удовольствием пользуюсь, но есть один неприятный момент, по прошествии дней 10, он отъедает до гигабайта, может сделать, чтобы скрипт перезагружался раз в n-ое количество минут?
И еще, можно ли его еще убыстрить? Если убрать WinActivate % "ahk_id" hShellTray, то реакция вообще моментальная, но правда появляется много проблем.
может сделать, чтобы скрипт перезагружался раз в n-ое количество минут?
30 минут сделал.
И еще, можно ли его еще убыстрить?
Да можно убрать "WinActivate % "ahk_id" hShellTray", но придётся пожертвовать нажатием "Ctrl+LButton". Сейчас добавил перед этим IfWinNotActive, возможно станет чуть быстрее.
#SingleInstance Force
#Persistent
prID := -1
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
SetTimer, Reload, 1800000
MouseGet:
MouseGetPos, , , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := -1
Else If ((ID := AccIDUnderMouse()) && ID != prID && (prID := ID))
{
IfWinNotActive % "ahk_id" hShellTray
WinActivate % "ahk_id" hShellTray
SendInput ^{LButton}{LControl Up}
}
Else If !ID
prID := -1
SetTimer, MouseGet, -10
Return
AccIDUnderMouse() {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) = 0
Return NumGet(varChild,8,"UInt"), ObjRelease(pacc)
}
Reload:
Reload
По моему мнению, этот скрипт идеально подойдет для программы: NPointer. В ней можно управлять курсором: головой или руками и главной проблемой является кликания мышкой, для этого нужно остановиться на месте которое вас интересует и ждать пока появится контекстное меню с выбором клика. Ну в общем смотрите сами.
но придётся пожертвовать нажатием "Ctrl+LButton"
Эврика! Нашёл довольно любопытную для себя штуку. Вообщем пробуем без WinActivate. По моему работает не дурно.
#SingleInstance Force
#Persistent
CoordMode, Mouse, Screen
prID := -1
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
SetTimer, Reload, 1800000
MouseGet:
MouseGetPos, sX, sY , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := -1
Else If ((ID := AccIDUnderMouse()) && ID != prID && (prID := ID))
{
WinGetPos, wX, wY,,, ahk_id %hTaskbar%
poi := (sX - wX) & 0xFFFF | ((sY - wY) & 0xFFFF) << 16
BlockInput On
PostMessage, 0x201, 0x8 | 0x1, poi,, ahk_id %hTaskbar%
Sleep 1
PostMessage, 0x202, 0x8, poi,, ahk_id %hTaskbar%
BlockInput Off
}
Else If !ID
prID := -1
SetTimer, MouseGet, -20
Return
AccIDUnderMouse() {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) = 0
Return NumGet(varChild,8,"UInt"), ObjRelease(pacc)
}
Reload:
Reload
По поводу утечки памяти, как то сам заводил тему. Сюда добавил ObjRelease(pacc), но что то не особо помогло. У самого тогда скрипт память накапливал, но там даже объектов не было. В том случае сошлись на кривости винды, так как у других память не ело. Вообщем тут нужны ещё наблюдатели.
А как вам идея: добавить в скрипт если курсор задержался хоть на какую-то миллисекунду долю времени на определенной области то тогда бы происходил клик, чтобы уменьшить погрешность нажатий?
И вообще было бы замечательно если бы сделать для всего автоматическое нажатие.
Для браузера для папок или для мест, где можно нажать. А нажатия совершались только после маленькой остановки на объекте интересующий вас. Стандартное наведение на вкладку или на ссылку или строчку ввода, ярлык на рабочем столе и другие. Такое возможно?
serzh82saratov
Респект, надеюсь перезагрузка решит эту проблему, так-то утечка не особенно беспокоит ибо небольшая, просто на днях напрочь зависла система, т.к. есть второе нужное приложение, которое утекает значительно быстрее и вместе они добили систему без файла подкачки.
Второй вариант работает сверх реактивно, так-же как первый без WinActivate, и даже решена одна проблема - без WinActivate, не активируются приложения, если на первом плане запущенное с административными правами, но к сожалению, приложение по повторному клику сворачивается, в чем как раз смысл WinActivate. Я, кстати, использую только SendInput {LButton}.
HideGenius
А не в курсе, есть ли такая программа, чтобы, например, показал ладонь на камеру и она нажала программируемую для каждого приложения клавишу? Например, показал ладонь при просмотре кино в видеоплеере, нажался пробел (пауза) и т.д.
А не в курсе, есть ли такая программа, чтобы, например, показал ладонь на камеру и она нажала программируемую для каждого приложения клавишу? Например, показал ладонь при просмотре кино в видеоплеере, нажался пробел (пауза) и т.д.
Есть программа управляющая сугубо плеерами и видеоплеером как на компьютере так и в браузере. Показываешь Лодонь = стоп, палец вправо = видео или музыка следующая или премотка ну и соответственно палец влево все наоборот.
Меня больше интересует так сказать автокликер на подобии вашего скрипта только кликать он будет на все что можно нажать, но после задержки на объекте. Возможно такое?
но к сожалению, приложение по повторному клику сворачивается, в чем как раз смысл WinActivate.
Ну по мне, так это логичнее при использовании. Но если это не устраивает, то:
Я, кстати, использую только SendInput {LButton}.
уже не важно. Только WinActivate и остаётся. Если я точно понял, что тебе требуется.
Мне вот непонарвилось, что при выборе незапущенного приложения, происходит запуск и повторный клик, поправил:
#SingleInstance Force
#Persistent
prID := -1
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
SetTimer, Reload, 1800000
MouseGet:
MouseGetPos, , , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := 0
Else If ((ID := AccChildPos(mX, mY)) && ID != prID && (prID := ID))
{
WinGetPos, wX, wY,,, ahk_id %hTaskbar%
poi := (mX - wX) & 0xFFFF | ((mY - wY) & 0xFFFF) << 16
BlockInput On
PostMessage, 0x201, 0x8 | 0x1, poi,, ahk_id %hTaskbar%
Sleep 1
PostMessage, 0x202, 0x8, poi,, ahk_id %hTaskbar%
BlockInput Off
}
Else If !ID
prID := 0
SetTimer, MouseGet, -20
Return
AccChildPos(byref mX, byref mY) {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) != 0
Return
If !(Child := NumGet(varChild,8,"UInt"))
Return
Acc := ComObjEnwrap(9, pacc, 1)
Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), 0, 0, Child)
mX := pt & 0xFFFF, mY := pt >> 32
Return NumGet(x,0,"int") "x" NumGet(y,0,"int")
}
Reload:
Reload
Меня больше интересует так сказать автокликер на подобии вашего скрипта только кликать он будет на все что можно нажать, но после задержки на объекте. Возможно такое?
Ну смотря что считать объектом.
Ну смотря что считать объектом.
Все на что можно нажать. Кнопки в вк меню, строки ввода, вкладки, программы на рабочем столе, файлы в папках все что может быть так сказать "кликабельное" на компьютере и браузере,в файлах папок. Можно сделать исключительно для браузера или чисто компьютера чтобы в браузере бездействовало или возможность выбора с чем хочешь работать.
Увы, но не в каждой программе можно определить, что под мышкой.
HideGenius
Скрипт не мой, а от уважаемого serzh82saratov, но конечно возможно, просто одинарный клик при остановках мыши.
serzh82saratov
Да, я уже смирился с потерей скорости, тоже пробовал без WinActivate и иногда при быстром наведении не срабатывало, но спасибо большое Вам. Потестирую крайний вариант, все-таки к хорошему привыкаешь реактивно.
Кстати, можно просто запретить сворачивание приложений через TaskBar, осталось придумать как.
Увы, но не в каждой программе можно определить, что под мышкой.
Пока что можно сделать для работы со стандартными окнами компьютера. А для браузера сделать для вкладок и нажатия на ссылку и другие активные кнопки или чтобы не мучиться простое кликания после задержки курсора после движения.
Но думаю для этого нужно создать новую тему и так как аналогов я не нашел, поэтому думаю будущее есть за этим. Плюс можно будет вам сотрудничать с разработчиками программ контроля компьютера с помощью веб камеры (которая становится популярным) поскольку они до сих пор не решили проблемы кликания и скроллинга, но научили управлять курсором с помощью камеры.
или чтобы не мучиться простое кликания после задержки курсора после движения.
#Persistent
OnExit, Exit
SetFormat, IntegerFast, h
hHookMouse := DllCall("SetWindowsHookEx"
, Int, WH_MOUSE_LL := 14
, Int, RegisterCallback("LowLevelMouseProc", "Fast")
, Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr)
, UInt, 0, Ptr)
Return
Exit:
DllCall("UnhookWindowsHookEx", Ptr, hHookMouse)
ExitApp
LowLevelMouseProc(nCode, wParam, lParam)
{
if wParam in 0x200,0x20A,0x20E ; WM_MOUSEMOVE,WM_MOUSEWHEEL,WM_MOUSEHWHEEL
SetTimer, Click, -500
Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam)
Click:
Click
Return
}
Кстати, можно просто запретить сворачивание приложений через TaskBar, осталось придумать как.
Надо как то определять, какое окно принадлежит определённой кнопке на панели задач.
Может и есть варианты какие то http://stackoverflow.com/questions/2262 … 43#2262843. Я не знаю, на teadrinker одна надежда, он как то подобное с треем провернул.
serzh82saratov
Ну если не сложно, то было бы прекрасно, совместить сверх скорость с удобством.
Я не знаю, на teadrinker одна надежда
Работа с кнопками панели задач сейчас очень сложна, тут без RAW-интерфейсов не обойтись, так что в ближайшее время вряд ли.
приложение по повторному клику сворачивается, в чем как раз смысл WinActivate.
Вроде придумал:
#SingleInstance Force
#Persistent
#NoEnv
ListLines Off
SetBatchLines -1
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
SetTimer, Reload, 1800000
MouseGet:
MouseGetPos, , , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := 0
Else If ((ID := AccChildPos(mX, mY, active)) && ID != prID && (prID := ID) && !active)
{
BlockInput On
WinGetPos, wX, wY,,, ahk_id %hTaskbar%
poi := (mX - wX) & 0xFFFF | ((mY - wY) & 0xFFFF) << 16
PostMessage, 0x201, 0x8 | 0x1, poi,, ahk_id %hTaskbar%
Sleep 1
PostMessage, 0x202, 0x8, poi,, ahk_id %hTaskbar%
BlockInput Off
}
Else If !ID
prID := 0
SetTimer, MouseGet, -20
Return
AccChildPos(byref mX, byref mY, byref active) {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) != 0
Return
If !(Child := NumGet(varChild,8,"UInt"))
Return
Acc := ComObjEnwrap(9, pacc, 1)
Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), 0, 0, Child)
mX := pt & 0xFFFF, mY := pt >> 32
active := Acc.accState(Child) = 1073741960 ? 1 : 0
Return NumGet(x,0,"int") "x" NumGet(y,0,"int")
}
Reload:
Reload
Кстати ещё можно определять, одно или несколько окон висит на кнопке, так что вариантов много. Например если одно из нескольких окон кнопки уже активно, то посылать ктрл+клик для активации следующего окна (код ниже), или просто клик для вывода списка окон этой кнопки.
#SingleInstance Force
#Persistent
#NoEnv
ListLines Off
SetBatchLines -1
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
SetTimer, Reload, 1800000
MouseGet:
MouseGetPos, , , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := 0
Else If ((ID := AccChildPos(mX, mY, active, several)) && ID != prID && (prID := ID)) && (!active || (active && several))
{
BlockInput On
WinGetPos, wX, wY,,, ahk_id %hTaskbar%
poi := (mX - wX) & 0xFFFF | ((mY - wY) & 0xFFFF) << 16
PostMessage, 0x201, 0x8 | 0x1, poi,, ahk_id %hTaskbar%
Sleep 1
PostMessage, 0x202, 0x8, poi,, ahk_id %hTaskbar%
BlockInput Off
}
Else If !ID
prID := 0
SetTimer, MouseGet, -20
Return
AccChildPos(byref mX, byref mY, byref active, byref several) {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) != 0
Return
If !(Child := NumGet(varChild,8,"UInt"))
Return
Acc := ComObjEnwrap(9, pacc, 1)
Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), 0, 0, Child)
mX := pt & 0xFFFF, mY := pt >> 32
active := Acc.accState(Child) = 1073741960 ? 1 : 0
several := Acc.accRole(Child) = 57 ? 1 : 0
Return NumGet(x,0,"int") "x" NumGet(y,0,"int")
}
Reload:
Reload
serzh82saratov
Огого, ну Вы мастер, и правда работает. О_о Он даже не кликает повторно по уже открытому и окно не мелькает, как в первоначальном варианте.
Обнаружилась проблема, бывает отваливается эта возможность, т.е. опять начинает сворачивать, после перезагрузки скрипта все норм. Надо посмотреть как на практике будет, может перезагрузка каждые 5 мин решит проблему.
Вы пользуетесь 7+ Taskbar Tweaker?
Обнаружилась проблема, бывает отваливается эта возможность
Ни разу у себя не заметил. У вас винда какая?
Вы пользуетесь 7+ Taskbar Tweaker?
А что это?
serzh82saratov
8.1 x64, происходит без закономерностей, т.е. без повторов от того же действия. Нужно потестировать.
7+ Taskbar Tweaker это маст хэв твик для панели задач Windows, попробуйте, что называется "палю годноту". Можно убрать группировку по ID приложений, можно каждый ярлык настроить отдельно, где показывать label, можно скрыть эскиз, громкость/сворачивание колесом мыши и т.д. Кстати, разработчик русскоговорящий.
http://habrahabr.ru/post/174593/
http://rammichael.com/7-taskbar-tweaker
8.1 x64, происходит без закономерностей
У меня 7. Если глюк появится, и начнётся постоянный отказ фичи, то запусти AhkSpy, и смотри что в AccInfo - State - code, наведя мышь на кнопку.
http://habrahabr.ru/post/174593/
Для себя не нашёл ничего нужного.
serzh82saratov
Ок, попробую задетектить.
Просто, когда не знал про AHK, эти фичи стали откровением.
State code до поломки:
1073741960
State code после поломки:
1074790540 (приложение развернуто)
1074790532 (приложение свернуто)
Поломка происходила как и простот при вызове приложения кликом, так и при комбинации Win+цифра, но не повторяется.
1074790540 (приложение развернуто)
Приложение развернуто и активно, и при повторном наведении всё же происходит клик?
1074790532 (приложение свернуто)
В смысле свернуто и активно?
Поломка происходила как и простот при вызове приложения кликом, так и при комбинации Win+цифра, но не повторяется
Что значит не повторяется?
Приложение развернуто и активно, и при повторном наведении всё же происходит клик?
Да, скрипт как-бы ломается после чего-то и начинает вести себя как вчерашний из 37 поста, т.е. без WinActivate.
В смысле свернуто и активно?
Да, работает, но свернуто.
Что значит не повторяется?
Имеется ввиду, что скрипт может сломаться от открытия нового приложения, но повторить это не удается, он может так-же сломаться, но позже. Пытался выяснить причину, думал курсор наезжает на промежуток между ярлыками, или попадает в самый низ, но пока не получилось. Когда работает все правильно, в обоих состояниях код 1073741960.
Да, работает, но свернуто.
Вы уверены что окно именно свёрнуто и при этом активно? Если это даже так, то "ненужный" клик ведь разворачивает окно?
он может так-же сломаться, но позже
Он может сломатся, а потом правильно заработать?
Когда работает все правильно, в обоих состояниях код 1073741960.
попробуйте заменить строку
active := Acc.accState(Child) = 1073741960 ? 1 : 0
на
s := Acc.accState(Child)
active := (s = 1073741960 || s = 1074790540 || s = 1074790532) ? 1 : 0
serzh82saratov
Вы уверены что окно именно свёрнуто и при этом активно? Если это даже так, то "ненужный" клик ведь разворачивает окно?
Не совсем понимаю, что имеется ввиду под активно, я про: запустил браузер и просто свернул, а не закрыл. Да, сворачивает и разворачивает, т.е. все как обычно.
Он может сломатся, а потом правильно заработать?
Нет, только после перезагрузки вручную.
попробуйте заменить строку
Ту все еще интересней, я просто навожу курсор на 4 приложения, т.е. переключаю, и ломается, но уже полностью, т.е. наведением курсора не разворачивается, но не запущенные запускаются. И стоит кликнуть вручную по свернутому, как опять работает.
В этот раз удалось задетектить причину с помощью OSD, когда происходит поломка, панель задач становится TopMost, т.е. OSD оказывается за ней, ощущение, что ломает клик по панели задач за иконками.
Ahk Spy показывает 532 у всех окон и свернутых и развернутых, но 540 у окна которое стоит первым за самим Ahk Spy. Ну и 960 когда все работает, но при запущенном Ahk Spy ломается очень быстро.
я про: запустил браузер и просто свернул, а не закрыл. Да, сворачивает и разворачивает, т.е. все как обычно.
Ну так если оно свёрнуто то клик должен быть, и он есть.
Ту все еще интересней
Попробуйте так
s := Acc.accState(Child)
ToolTip % s, 1, 1
active := (s = 1073741960 || s = 1074790540) ? 1 : 0
AhkSpy тут для отладки ненужен. После замены приведите здесь полный код.
OSD оказывается за ней, ощущение, что ломает клик по панели задач за иконками.
Не понял.
serzh82saratov
Ну так если оно свёрнуто то клик должен быть, и он есть.
Но при этом оно и сворачивает, чего быть не должно.
Попробуйте так
Ого, пока не ломается, в Tooltip-е задетектил новые коды 1074790408 и 1073741832, но все работает.
#SingleInstance Force
#Persistent
#NoEnv
ListLines Off
SetBatchLines -1
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
SetTimer, Reload, 1800000
MouseGet:
MouseGetPos, , , , hCtrl, 2
If (hCtrl != hTaskbar)
prID := 0
Else If ((ID := AccChildPos(mX, mY, active)) && ID != prID && (prID := ID) && !active)
{
BlockInput On
WinGetPos, wX, wY,,, ahk_id %hTaskbar%
poi := (mX - wX) & 0xFFFF | ((mY - wY) & 0xFFFF) << 16
PostMessage, 0x201, 0x8 | 0x1, poi,, ahk_id %hTaskbar%
Sleep 1
PostMessage, 0x202, 0x8, poi,, ahk_id %hTaskbar%
BlockInput Off
}
Else If !ID
prID := 0
SetTimer, MouseGet, -20
Return
AccChildPos(byref mX, byref mY, byref active) {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", 0*DllCall("GetCursorPos","Int64*",pt)+pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) != 0
Return
If !(Child := NumGet(varChild,8,"UInt"))
Return
Acc := ComObjEnwrap(9, pacc, 1)
Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), 0, 0, Child)
mX := pt & 0xFFFF, mY := pt >> 32
s := Acc.accState(Child)
ToolTip % s, 1, 1
active := (s = 1073741960 || s = 1074790540) ? 1 : 0
Return NumGet(x,0,"int") "x" NumGet(y,0,"int")
}
Reload:
Reload
Не понял.
Поставьте OSD над панелью задач и кликните по ней, OSD окажется за ней, я хотел, кстати, по этому поводу спросить в теме по OSD, можно ли ее сделать TopMost даже над таскбаром.
В 7+ Taskbar Tweaker даже есть опция Disable_TopMost.
By default, the taskbar is always on top. This option allows you to change this behavior.
0 - Always on top (default)
1 - Not always on top, but not overlapped by maximized windows
2 - Not always on top, and overlapped by maximized windows
Ого, пока не ломается
Значит когда
1074790532 (приложение свернуто)
всё таки надо кликать.
я хотел, кстати, по этому поводу спросить в теме по OSD, можно ли ее сделать TopMost даже над таскбаром.
В той теме.
Оптимизировано:
#SingleInstance Force
#Persistent
#NoEnv
hShellTray := WinExist("ahk_class Shell_TrayWnd ahk_exe explorer.exe")
ControlGet, hTaskbar, HWND,, MSTaskListWClass1, % "ahk_id" hShellTray
DllCall("LoadLibrary","Str","oleacc","Ptr")
SetTimer, Reload, 1800000
Check:
If (DllCall("WindowFromPoint", "int64", 0*DllCall("GetCursorPos", "Int64*" ,pt) + pt, "Ptr") != hTaskbar)
prID := 0
Else If ((ID := AccNeedInfo(pt, active, several)) && ID != prID && (prID := ID)) && (!active || several)
{
BlockInput On
WinGetPos, wX, wY,,, ahk_id %hTaskbar%
poi := ((pt & 0xFFFF) - wX) & 0xFFFF | ((pt >> 32) - wY) & 0xFFFF << 16
PostMessage, 0x201, 0x8 | 0x1, poi,, ahk_id %hTaskbar%
Sleep 10
PostMessage, 0x202, 0x8, poi,, ahk_id %hTaskbar%
Sleep 10
BlockInput Off
}
Else If !ID
prID := 0
SetTimer, Check, -20
Return
AccNeedInfo(pt, byref active, byref several) {
If DllCall("oleacc\AccessibleObjectFromPoint"
, "Int64", pt, "Ptr*", pacc
, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild) != 0
|| !(Child := NumGet(varChild,8,"UInt"))
Return
Acc := ComObjEnwrap(9, pacc, 1)
Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), 0, 0, Child)
active := ((s := Acc.accState(Child)) = 1073741960 || s = 1074790540) ? 1 : 0
several := Acc.accRole(Child) = 57 ? 1 : 0
Return NumGet(x,0,"int") "x" NumGet(y,0,"int")
}
Reload:
Reload
serzh82saratov
Удивительно конечно, Вы всё-таки смогли это сделать, думал это невозможно. Спасибо большое.
В новой версии еще и решена назойливая проблема первого варианта, т.к. я использовал SendInput {LButton}, при быстром наведении он добавочно кликал за пределами панели задач и, например, выделял текст в браузере.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться