Autohotkey 自动热键关闭/隐藏菜单项';s状态(已选中/未选中) 运行此脚本并打开记事本

Autohotkey 自动热键关闭/隐藏菜单项';s状态(已选中/未选中) 运行此脚本并打开记事本,autohotkey,Autohotkey,转到“视图”菜单,并切换状态栏 如果状态栏处于打开状态,菜单项旁边将出现一个复选标记,此脚本将尝试检测是否选中状态栏菜单项 问题是它只能在菜单打开后确定选中/未选中状态,如何在菜单关闭/隐藏时更改代码以检测选中状态 请不要因为我使用的是记事本状态栏示例,就认为我要做的只是确定记事本状态栏是否打开/关闭,而不是打开/关闭。我试图检测菜单项是否已选中/未选中 #persistent settitlematchmode, 2 Loop, { WinGet, hWnd, ID, Notepad hMe

转到“视图”菜单,并切换状态栏
如果状态栏处于打开状态,菜单项旁边将出现一个复选标记,此脚本将尝试检测是否选中状态栏菜单项
问题是它只能在菜单打开后确定选中/未选中状态,如何在菜单关闭/隐藏时更改代码以检测选中状态

请不要因为我使用的是记事本状态栏示例,就认为我要做的只是确定记事本状态栏是否打开/关闭,而不是打开/关闭。我试图检测菜单项是否已选中/未选中

#persistent
settitlematchmode, 2
Loop, 
{
WinGet, hWnd, ID, Notepad
hMenu := DllCall("GetMenu", "UPtr", hWnd)
MenuAndIndex := GetMenuAndIndex(hMenu, "View", "Status Bar")
State := GetMenuState(MenuAndIndex*)
if (State.Checked)
    {
    tooltip, View -> Status Bar is checked
    }
else
tooltip, View -> Status Bar is unchecked
}

; ------------------FUNCTIONS BELOW -----------------

GetMenuState(hMenu, Index)
{
    State := DllCall("GetMenuState", "UPtr", hMenu, "UInt", Index, "UInt", 0x400)
    if (State == -1)
        return False
    return {"CHECKED": State&0x8, "DISABLED": State&0x2, "GRAYED": State&0x2
    , "HILITE": State&0x80, "MENUBARBREAK": State&0x20, "MENUBREAK": State&0x40
    , "OWNERDAW": State&0x100, "POPUP": State&0x10, "SEPARATOR": State&0x800}
}

GetMenuAndIndex(hMenu, p*)
{
    CurrentMenu := hMenu
    For each, MenuName in p
    {
        if SubMenu
            CurrentMenu := SubMenu
        Count := DllCall("GetMenuItemCount", "UPtr", CurrentMenu)
        Loop, % Count
        {
            Index := A_Index - 1
            Name := GetMenuString(CurrentMenu, Index)
            if (RegExReplace(Name, "&|\t.*") = MenuName)
            {
                SubMenu := DllCall("GetSubMenu", "UPtr", CurrentMenu, "UInt", Index)
                if SubMenu
                    Continue, 2
                else
                    return [CurrentMenu, Index]
            }
        }
        return "Item not found"
    }
    return [CurrentMenu, Index]
}

GetMenuString(hMenu, Index)
{
        VarSetCapacity(Name, 256, 0)
        DllCall("GetMenuString", "UPtr", hMenu, "UInt", Index
        , "Str", Name, "Int", 128, "UInt", 0x400)
        return Name
}

我不认为有直接的解决方案可以在不打开菜单的情况下检查菜单项是否被选中。所以你需要间接的方法来做到这一点

您可以检查菜单正在更改的注册表项。例如,
HKEY\u CURRENT\u USER\Software\Microsoft\Notepad
中的from:Notepad应具有状态栏的注册表项。我认为许多其他软件正在根据菜单的更改来更改注册表。您可以使用该命令读取注册表项的当前值

另外,一些软件可以根据菜单中所做的更改来更改
.ini
文件。您可以使用该命令读取
.ini
文件中的值

使用命令在屏幕上搜索可通过菜单更改的图像。例如,您可以通过命令搜索记事本状态栏的唯一部分。例如,此部分:

还有许多其他方法可以检查菜单所做的更改(打开新窗口、创建文件等)。关注系统中可能发生的菜单更改,并检查这些更改

此外,始终使用自动热键及其文档(最新版本,新官方网站)!AutoHotkey及其AutoHotkey.com上的文档已过时,您可能在使用它们时遇到一些问题

试试看。如果
CheckMenuItem
返回
-1
,则该菜单尚不存在。