Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню
Можно через массивы.
Вам уже когда-то писали что-то подобное.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Серый форум → Общение → AutoHotkey → AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Можно через массивы.
Вам уже когда-то писали что-то подобное.
Malcev, а можно ли сделать проверку выделенного пункта по его имени, а не порядковому расположению? Т.е. для тех случаев, когда порядковое положение заданного пункта часто меняется.
Также, быть может, возможно объединить две функции? Т.е. если подменю не задано (четвертый параметр в ф-ии SelectMenuSub), то проверять третий параметр.
SelectMenuSub(program, SubMenuNumber, SubMenuNumber2, ItemNumber){
Hwnd := WinExist(program)
MainMenu := DllCall("GetMenu", UInt, Hwnd)
SubMenu := DllCall("GetSubMenu", UInt, MainMenu, Int, SubMenuNumber)
SubMenu2 := DllCall("GetSubMenu", UInt, SubMenu, Int, SubMenuNumber2)
SendMessage, 0x117, SubMenu2, ItemNumber,, ahk_id %Hwnd% ; WM_INITMENUPOPUP
return DllCall("GetMenuState", UInt, SubMenu2, UInt, ItemNumber, UInt, 0x400)
}
SelectMenu(program, SubMenuNumber, ItemNumber){
Hwnd := WinExist(program)
MainMenu := DllCall("GetMenu", UInt, Hwnd)
SubMenu := DllCall("GetSubMenu", UInt, MainMenu, Int, SubMenuNumber)
SendMessage, 0x117, SubMenu, ItemNumber,, ahk_id %Hwnd% ; WM_INITMENUPOPUP
return DllCall("GetMenuState", UInt, SubMenu, UInt, ItemNumber, UInt, 0x400)
}
Malcev, а можно ли сделать проверку выделенного пункта по его имени, а не порядковому расположению?
Читайте внимательно это тему, в ней уже был код.
Только его надо слегка модифицировать - посылать сообщение WM_INITMENU, WM_INITMENUPOPUP.
Также, быть может, возможно объединить две функции?
Возможно.
Malcev, спасибо! И как же их объединить?
В коде из четвертого поста не нашел упоминание WM_INITMENU, для замены на WM_INITMENUPOPUP.
Там надо вставить
SendMessage, 0x117, hMenu, SubMenuPos,, ahk_id %hWin% ; WM_INITMENUPOPUP
перед
Return GetMenuItemInfo(hMenu, SubMenuPos, MIIM_STATE) & 0x8 ? 1 : 0
И как же их объединить?
Передавайте номера всех меню в одном параметре через какой-нибудь разделитель, а в функции их парсьте.
Malcev, спасибо, работает! Но у меня не работает подменю. Ввожу так:
MsgBox, % GetMenuItemCheckState(WinExist("ahk_class Premiere Pro"), "Window|Workspaces|Timeline Alt+Shift+3")
Передавайте номера всех меню в одном параметре через какой-нибудь разделитель, а в функции их парсьте.
Думал, можно как-то задать условие, что если последний параметр не задан, то заменить в конце ф-ии SubMenu2 на SubMenu.
Да, у teadrinkerа в функции ошибка.
Надо это
Loop % DllCall("GetMenuItemCount", Ptr, hMenu)
if StrReplace(GetMenuItemInfo(hMenu, A_Index - 1, MIIM_STRING), "&") = A_LoopField && SubMenuPos := A_Index - 1
break
заменить на
Loop % DllCall("GetMenuItemCount", Ptr, hMenu)
{
if StrReplace(GetMenuItemInfo(hMenu, A_Index - 1, MIIM_STRING), "&") = A_LoopField
{
SubMenuPos := A_Index - 1
break
}
}
Думал, можно как-то задать условие, что если последний параметр не задан, то заменить в конце ф-ии SubMenu2 на SubMenu.
Можно и так. Делайте.
Malcev, заменил, но подменю по-прежнему не работает:
MsgBox, % GetMenuItemCheckState(WinExist("ahk_class Premiere Pro"), "Window|Workspaces|Timeline Alt+Shift+3")
Так работает:
MsgBox, % GetMenuItemCheckState(WinExist("ahk_class Premiere Pro"), "Window|Lumetri Color Shift+9")
Проверяйте значение StrReplace(GetMenuItemInfo(hMenu, A_Index - 1, MIIM_STRING), "&")
Может не так вписали название пункта.
Malcev, не понял на счет проверки StrReplace(GetMenuItemInfo(hMenu, A_Index - 1, MIIM_STRING), "&").
У Вас так работает?
MsgBox, % GetMenuItemCheckState(WinExist("ahk_class Premiere Pro"), "Window|Workspaces|Import Workspace from Projects")
У меня работает.
Возможно вы не то исправили.
StrReplace(GetMenuItemInfo(hMenu, A_Index - 1, MIIM_STRING), "&") - это обращение к функции.
Что она возвращает можно посмотреть с помощью msgbox.
Malcev, получаю пустое окно:
MsgBox, % StrReplace(GetMenuItemInfo(hMenu, A_Index - 1, MIIM_STRING), "&")
GetMenuItemCheckState(hWin, path)
{
static MIIM_STRING := 0x40, MIIM_STATE := 0x1
Loop, parse, path, |
{
hMenu := A_Index = 1 ? DllCall("GetMenu", Ptr, hWin, Ptr) : DllCall("GetSubMenu", Ptr, hMenu, Int, SubMenuPos)
SubMenuPos := ""
Loop % DllCall("GetMenuItemCount", Ptr, hMenu)
if StrReplace(GetMenuItemInfo(hMenu, A_Index - 1, MIIM_STRING), "&") = A_LoopField && SubMenuPos := A_Index - 1
break
if (SubMenuPos = "") {
MsgBox, % "Не найден пункт меню """ A_LoopField """ по пути """ path """"
Return
}
}
SendMessage, 0x117, hMenu, SubMenuPos,, ahk_id %hWin% ; WM_INITMENUPOPUP
Return GetMenuItemInfo(hMenu, SubMenuPos, MIIM_STATE) & 0x8 ? 1 : 0
}
GetMenuItemInfo(hMenu, ItemNumber, TypeOfInfo)
{
static MIIM_STRING := 0x40, MIIM_STATE := 0x1
VarSetCapacity(MENUITEMINFO, size := 4*4 + A_PtrSize*8, 0)
NumPut(size, MENUITEMINFO)
NumPut(TypeOfInfo, MENUITEMINFO, 4)
DllCall("GetMenuItemInfo", Ptr, hMenu, UInt, ItemNumber, UInt, 1, Ptr, &MENUITEMINFO)
if (TypeOfInfo & MIIM_STRING) {
nChars := NumGet(MENUITEMINFO, 4*4 + A_PtrSize*6, "UInt") + 1
if (nChars > 1) {
VarSetCapacity(buff, nChars * (A_IsUnicode ? 2 : 1), 0)
NumPut(&buff, MENUITEMINFO, 4*4 + A_PtrSize*5)
NumPut(nChars, MENUITEMINFO, 4*4 + A_PtrSize*6)
DllCall("GetMenuItemInfo", Ptr, hMenu, UInt, A_Index - 1, UInt, 1, Ptr, &MENUITEMINFO)
info := StrGet(&buff)
}
}
if (TypeOfInfo & MIIM_STATE)
info := NumGet(MENUITEMINFO, 4*3, "Int")
Return info
}
becauseim, почитайте про функции, как они работают и что возвращают.
Потом попробуйте понять алгоритм скрипта.
А не работает у вас, потому что вы не сделали то, что я написал в 33 посте.
Malcev, ф-ия сложная мне для понимания.
Да, я в какой-то момент вернул ф-ию в первоначальный вид, сам того не заметив. Теперь все работает. Спасибо!
А я не имел в виду именно эту функцию, а функции вообще.
Если вы поймете как они работают, то и понимать чужие скрипты будет проще.
Тем более справка имеется на русском.
Malcev, добавьте, пожалуйста, чувствительность к названию выбираемого пункта, т.к. при смене его расположения в списке также меняется и название, а именно хоткей. Или же не брать в название все, что идет после большого пробела (Tab).
Сделайте это сами.
Перебор пунктов меню и их сравнение с вашим идет в коде из 33 поста.
Чтобы отправить ответ, вы должны войти или зарегистрироваться