- Run this script & Open Notepad
Go to the View menu, and toggle the Status Bar
If the status bar is on, a checkmark will appear next to the menu item, this script tries to detect whether the status bar menu item is checked
The problem is it can only determine checked/nonchecked status after the menu is open, how can I alter the code to detect the checked status while the menu is closed/hidden?Please don't assume that just because I'm using the notepad status bar example, that all I'm trying to do is determine if the notepad status bar is on/off, I'm not. I'm trying to detect if menu items are checked/unchecked.
#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 Answers
I don't think there is direct solution for checking if menu items are checked/unchecked without actually opening that menu. So you need indirect ways to do that.
You can check registry keys that menus are changing. For example, from here: Notepad in HKEY_CURRENT_USER\Software\Microsoft\Notepad
should have registry key for Status Bar. I think many other software is changing registry according to changes from menu. You can use RegRead command for reading current value of registry key.
Also some software can change .ini
file according the changes done from menus. You can use IniRead command for reading values in .ini
files.
Use ImageSearch command to search for images on the screen that can be changed by menus. For example, you can search the unique part of Status Bar of Notepad by ImageSearch command. For example this part:
There are many other ways to check the for changes done by menus (opens new window, creates file, etc). Focus on what menu changes can change in system and check for these changes.
Also, always use AutoHotkey and its documenatation from http://ahkscript.org/ (current uptodate version, new official website)! AutoHotkey and its documentation from autohotkey.com is outdated and you may have some problems using them!
CheckMenuItem
orGetMenuItemInfo
. IfCheckMenuItem
returns-1
, the menu doesn't exist yet. - Joe DF