Тема: AHK: Узнать состояние системного меню/подменю
Кто-нибудь подскажет, как определить что меню (ahk_class #32768) развёрнуто?
Фокусы с ControlGetFocus/WinWait/WinWaitActive/IfWinActive не проходят.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Кто-нибудь подскажет, как определить что меню (ahk_class #32768) развёрнуто?
Фокусы с ControlGetFocus/WinWait/WinWaitActive/IfWinActive не проходят.
Получилось только проверить на существование:
Loop
IfWinExist , ahk_class #32768
SoundBeep
По нулям.
#Persistent
DllCall("LoadLibrary","Str","oleacc","Ptr"),
SetWinEventHook(0x6, 0x7, 0, RegisterCallback("HookProc", "F"), 0, 0, 0)
Acc_ObjectFromWindow(hWnd, idObject = 0)
{
If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr"
, -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81
, NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
Return ComObjEnwrap(9,pacc,1)
}
Acc_Parent(Acc) {
try parent:=Acc.accParent
return parent?Acc_Query(parent):
}
Acc_Query(Acc) {
try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
return DllCall("SetWinEventHook", UInt, eventMin , UInt, eventMax , Ptr, hmodWinEventProc
, Ptr, lpfnWinEventProc , UInt, idProcess , UInt, idThread, UInt, dwFlags, Ptr)
}
HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
if (Event = 6) ; EVENT_SYSTEM_MENUPOPUPSTART
{
Acc:=Acc_ObjectFromWindow(hWnd), P := Acc.AccName(0)
loop
if ((Acc := Acc_Parent(Acc_Parent(Acc_Parent(Acc)))).AccRole(0)=9)
P:= Acc.AccName(0) "`n" P
Until (Acc.AccRole(0)="")
tooltip % P
}
}
Скрипт будет показывать тултип при открытии любого контекстного меню.
В первой строчке будет указано имя родителя а ниже дочерний, если дочерних несколько то они все будут по порядку в вниз.
#Persistent
global oMenuEvents := {0x6: "EVENT_SYSTEM_MENUPOPUPSTART", 0x7: "EVENT_SYSTEM_MENUPOPUPEND"}
SetWinEventHook(0x6, 0x7, 0, RegisterCallback("HookProc", "F"), 0, 0, 0)
Return
HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
CoordMode, ToolTip
ToolTip % oMenuEvents[event], 10, 10
}
SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
return DllCall("SetWinEventHook", UInt, eventMin , UInt, eventMax , Ptr, hmodWinEventProc
, Ptr, lpfnWinEventProc , UInt, idProcess , UInt, idThread, UInt, dwFlags, Ptr)
}
yalanne, опять AHK-basic, в части установки хука.
teadrinker, А в чем проблема, не везде работать будет?
Да, может не сработать на x64 (размерность неверная), и
DllCall("CoInitialize", Uint, 0)
лишнее, в современной версии инициализируется автоматически.
Исправил. Спасибо, буду знать.
Так и думал, что в тех степях решение.
ОК. Спасибо. А без тултипа банальный MsgBox по хоткею - как?
Как-нибудь так:
global ExistMenu := 0
SetWinEventHook(0x6, 0x7, 0, RegisterCallback("HookProc", "F"), 0, 0, 0)
Return
F11:: MsgBox, % ExistMenu
HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
ExistMenu := event = 6 ? 1 : 0
}
SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
return DllCall("SetWinEventHook", UInt, eventMin , UInt, eventMax , Ptr, hmodWinEventProc
, Ptr, lpfnWinEventProc , UInt, idProcess , UInt, idThread, UInt, dwFlags, Ptr)
}
teadrinker
Благодарю за решение!
Вообще-то у меня и так работает:
F11:: MsgBox, % WinExist("ahk_class #32768") ? 1 : 0
Если мой вариант пригодится с хоткеем то вот:
#Persistent
DllCall("LoadLibrary","Str","oleacc","Ptr"),
Acc_ObjectFromWindow(hWnd, idObject = 0)
{
If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr"
, -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81
, NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
Return ComObjEnwrap(9,pacc,1)
}
Acc_Parent(Acc) {
try parent:=Acc.accParent
return parent?Acc_Query(parent):
}
Acc_Query(Acc) {
try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
F11::
if !(hWnd := WinExist("ahk_class #32768"))
return
Acc:=Acc_ObjectFromWindow(hWnd), P := Acc.AccName(0)
loop
if ((Acc := Acc_Parent(Acc_Parent(Acc_Parent(Acc)))).AccRole(0)=9)
P:= Acc.AccName(0) "`n" P
Until (Acc.AccRole(0)="")
msgbox % P
teadrinker, а на какой системе? На 7-ке не хочет.
yalanne, спасибо, но я предпочту вариант teadrinker, он компактнее.
У меня семёрка как раз. Win 7 64, AHK x64.
Ясно. У меня x32.
Варианты из 2 и 13 сообщений работают на WinXP 32-bit.
Вообще-то у меня и так работает:
F11:: MsgBox, % WinExist("ahk_class #32768") ? 1 : 0
Так работает только со стандартным контекстным меню.
Код же из поста 11 работает везде.
В этом можно удостовериться, нажав правую кнопку мыши в окне фаерфокса.
У меня в факрфоксе никакой не работает, да и не должен, вроде.
Чего-то не пойму. Вроде заработал WinExist. Но я же с него начал проверять! Глюк был какой-то, похоже...
У меня ahk 32 bit и в хроме работает и в фаерфоксе код из 11 поста.
У меня в хроме тоже работает в любой версии AHK код с хуком, в FF не работает ни какой вариант.
Странно. FireFox 41.0.1. Работает, как часы.
Может какие-то плагины у тебя или у меня установлены.
Всплыл ещё нюанс. А как выловить фокус на главном меню, если, к примеру, была нажата кл. Alt или свёрнуто подменю по Esc?
F11:: ToolTip % GetMenubarFocus(WinExist("A"))
GetMenubarFocus(hwnd)
{
static OBJID_MENU := 0xFFFFFFFD
VarSetCapacity(MBI, size := 4*4 + A_PtrSize*4, 0)
NumPut(size, MBI)
DllCall("GetMenuBarInfo", Ptr, hwnd, Int, OBJID_MENU, Int, 0, Ptr, &MBI)
Return *(&MBI + 4*4 + A_PtrSize*3) & 1
}
А зачем всё это нужно? Подозреваю, хотите запустить пункт меню путем отправки окну нажатий клавиш.
Спасибо! Нет, это нужно, чтобы хоткей не работал в момент вызова разных меню.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться