26

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

Можно через массивы.
Вам уже когда-то писали что-то подобное.

27

Re: 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)
}
Win10x64, AHK v1.1.25

28

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

becauseim пишет:

Malcev, а можно ли сделать проверку выделенного пункта по его имени, а не порядковому расположению?

Читайте внимательно это тему, в ней уже был код.
Только его надо слегка модифицировать - посылать сообщение WM_INITMENU, WM_INITMENUPOPUP.

becauseim пишет:

Также, быть может, возможно объединить две функции?

Возможно.

29

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

Malcev, спасибо! И как же их объединить?

Win10x64, AHK v1.1.25

30

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

В коде из четвертого поста не нашел упоминание WM_INITMENU, для замены на WM_INITMENUPOPUP.

Win10x64, AHK v1.1.25

31

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

Там надо вставить

SendMessage, 0x117, hMenu, SubMenuPos,, ahk_id %hWin% ; WM_INITMENUPOPUP

перед

Return GetMenuItemInfo(hMenu, SubMenuPos, MIIM_STATE) & 0x8 ? 1 : 0
becauseim пишет:

И как же их объединить?

Передавайте номера всех меню в одном параметре через какой-нибудь разделитель, а в функции их парсьте.

32

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

Malcev, спасибо, работает! Но у меня не работает подменю. Ввожу так:

MsgBox, % GetMenuItemCheckState(WinExist("ahk_class Premiere Pro"), "Window|Workspaces|Timeline	Alt+Shift+3")

Передавайте номера всех меню в одном параметре через какой-нибудь разделитель, а в функции их парсьте.

Думал, можно как-то задать условие, что если последний параметр не задан, то заменить в конце ф-ии SubMenu2 на SubMenu.

Win10x64, AHK v1.1.25

33

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

Да, у 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
   }
}
becauseim пишет:

Думал, можно как-то задать условие, что если последний параметр не задан, то заменить в конце ф-ии SubMenu2 на SubMenu.

Можно и так. Делайте.

34 (изменено: becauseim, 2017-09-26 02:23:01)

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

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")
Win10x64, AHK v1.1.25

35

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

Проверяйте значение StrReplace(GetMenuItemInfo(hMenu, A_Index - 1, MIIM_STRING), "&")
Может не так вписали название пункта.

36

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

Malcev, не понял на счет проверки StrReplace(GetMenuItemInfo(hMenu, A_Index - 1, MIIM_STRING), "&").
У Вас так работает?

MsgBox, % GetMenuItemCheckState(WinExist("ahk_class Premiere Pro"), "Window|Workspaces|Import Workspace from Projects")
Win10x64, AHK v1.1.25

37

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

У меня работает.
Возможно вы не то исправили.
StrReplace(GetMenuItemInfo(hMenu, A_Index - 1, MIIM_STRING), "&") - это обращение к функции.
Что она возвращает можно посмотреть с помощью msgbox.

38

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

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
}
Win10x64, AHK v1.1.25

39

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

becauseim, почитайте про функции, как они работают и что  возвращают.
Потом попробуйте понять алгоритм скрипта.
А не работает у вас, потому что вы не сделали то, что я написал в 33 посте.

40

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

Malcev, ф-ия сложная мне для понимания.
Да, я в какой-то момент вернул ф-ию в первоначальный вид, сам того не заметив. Теперь все работает. Спасибо!

Win10x64, AHK v1.1.25

41

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

А я не имел в виду именно эту функцию, а функции вообще.
Если вы поймете как они работают, то и понимать чужие скрипты будет проще.
Тем более справка имеется на русском.

42

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

Malcev, добавьте, пожалуйста, чувствительность к названию выбираемого пункта, т.к. при смене его расположения в списке также меняется и название, а именно хоткей. Или же не брать в название все, что идет после большого пробела (Tab).

Win10x64, AHK v1.1.25

43

Re: AHK: WinMenuSelectItem Проверка состояния переключателя пункта меню

Сделайте это сами.
Перебор пунктов меню и их сравнение с вашим идет в коде из 33 поста.