AutoHotKey获取关闭/隐藏菜单项的状态(已选中/未选中)

时间:2014-09-07 16:48:23

标签: autohotkey

  1. 运行此脚本&打开记事本
  2. 转到“查看”菜单,然后切换状态栏
    如果状态栏打开,菜单项旁边会出现一个复选标记,此脚本会尝试检测是否已检查状态栏菜单项。 问题是它只能在菜单打开后确定已检查/未检查状态,如何在菜单关闭/隐藏时更改代码以检测已检查状态?

    请不要认为仅仅因为我使用记事本状态栏示例,我尝试做的就是确定记事本状态栏是否开启,I&#39 ;不是。我试图检测菜单项是否已选中/取消选中。

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

1 个答案:

答案 0 :(得分:1)

我不认为有直接的解决方案来检查菜单项是否被选中/取消选中,而不实际打开该菜单。所以你需要间接的方法来做到这一点。

您可以检查菜单正在更改的注册表项。例如,来自hereHKEY_CURRENT_USER\Software\Microsoft\Notepad中的记事本应具有状态栏的注册表项。我认为许多其他软件正在根据菜单的变化更改注册表。您可以使用RegRead命令读取注册表项的当前值。

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

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

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

此外,始终使用来自http://ahkscript.org/的AutoHotkey及其文档(当前最新版本,新官方网站)! Autohotkey.com上的AutoHotkey及其文档已过时,使用它们可能会遇到一些问题!