1

Тема: AHK: Узнать состояние системного меню/подменю

Кто-нибудь подскажет, как определить что меню (ahk_class #32768) развёрнуто?
Фокусы с ControlGetFocus/WinWait/WinWaitActive/IfWinActive не проходят.

2

Re: AHK: Узнать состояние системного меню/подменю

Получилось только проверить на существование:

Loop
IfWinExist , ahk_class #32768
SoundBeep

3

Re: AHK: Узнать состояние системного меню/подменю

По нулям.

4 (изменено: yalanne, 2015-10-05 18:06:12)

Re: AHK: Узнать состояние системного меню/подменю

#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
    }
}

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

5

Re: AHK: Узнать состояние системного меню/подменю

#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)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

6 (изменено: teadrinker, 2015-10-05 17:51:52)

Re: AHK: Узнать состояние системного меню/подменю

yalanne, опять AHK-basic, в части установки хука.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7

Re: AHK: Узнать состояние системного меню/подменю

teadrinker, А в чем проблема, не везде работать будет?

8

Re: AHK: Узнать состояние системного меню/подменю

Да, может не сработать на x64 (размерность неверная), и

DllCall("CoInitialize", Uint, 0)

лишнее, в современной версии инициализируется автоматически.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

9

Re: AHK: Узнать состояние системного меню/подменю

Исправил. Спасибо, буду знать.

10

Re: AHK: Узнать состояние системного меню/подменю

Так и думал, что в тех степях решение.
ОК. Спасибо. А без тултипа банальный MsgBox по хоткею - как?

11

Re: AHK: Узнать состояние системного меню/подменю

Как-нибудь так:

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)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

12

Re: AHK: Узнать состояние системного меню/подменю

teadrinker
Благодарю за решение!

13

Re: AHK: Узнать состояние системного меню/подменю

Вообще-то у меня и так работает:

F11:: MsgBox, % WinExist("ahk_class #32768") ? 1 : 0
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

14 (изменено: yalanne, 2015-10-05 19:17:30)

Re: AHK: Узнать состояние системного меню/подменю

Если мой вариант пригодится с хоткеем то вот:

+ F11
#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

15

Re: AHK: Узнать состояние системного меню/подменю

teadrinker, а на какой системе? На 7-ке не хочет.


yalanne, спасибо, но я предпочту вариант teadrinker, он компактнее.

16

Re: AHK: Узнать состояние системного меню/подменю

У меня семёрка как раз. Win 7 64, AHK x64.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

17

Re: AHK: Узнать состояние системного меню/подменю

Ясно. У меня x32.

18

Re: AHK: Узнать состояние системного меню/подменю

Варианты из 2 и 13 сообщений работают на WinXP 32-bit.

19

Re: AHK: Узнать состояние системного меню/подменю

teadrinker пишет:

Вообще-то у меня и так работает:

F11:: MsgBox, % WinExist("ahk_class #32768") ? 1 : 0

Так работает только со стандартным контекстным меню.
Код же из поста 11 работает везде.
В этом можно удостовериться, нажав правую кнопку мыши в окне фаерфокса.

20

Re: AHK: Узнать состояние системного меню/подменю

У меня в факрфоксе никакой не работает, да и не должен, вроде.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

21

Re: AHK: Узнать состояние системного меню/подменю

Чего-то не пойму. Вроде заработал WinExist. Но я же с него начал проверять! Глюк был какой-то, похоже...

22

Re: AHK: Узнать состояние системного меню/подменю

У меня ahk 32 bit и в хроме работает и в фаерфоксе код из 11 поста.

23

Re: AHK: Узнать состояние системного меню/подменю

У меня в хроме тоже работает в любой версии AHK код с хуком, в FF не работает ни какой вариант.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

24 (изменено: Malcev, 2015-10-05 21:58:54)

Re: AHK: Узнать состояние системного меню/подменю

Странно. FireFox 41.0.1. Работает, как часы.
Может какие-то плагины у тебя или у меня установлены.

25 (изменено: Flasher, 2015-10-06 01:47:18)

Re: AHK: Узнать состояние системного меню/подменю

Всплыл ещё нюанс. А как выловить фокус на главном меню, если, к примеру, была нажата кл. Alt или свёрнуто подменю по Esc?

26

Re: AHK: Узнать состояние системного меню/подменю

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
}

А зачем всё это нужно? Подозреваю, хотите запустить пункт меню путем отправки окну нажатий клавиш.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

27

Re: AHK: Узнать состояние системного меню/подменю

Спасибо! Нет, это нужно, чтобы хоткей не работал в момент вызова разных меню.