Enable/disable external menuitem

Get help with using AutoHotkey and its commands and hotkeys
func
Posts: 47
Joined: 20 May 2016, 20:52

Enable/disable external menuitem

23 Jul 2017, 16:40

I'm trying to enable/disable/grey out menu items for default windows style menus, in external programs, such as notepad.exe in the example below

but for some reason it's not working. I think my "EnableMenuItem" dllcall has wrong parameters, such as the 0x00000001L part, or maybe my "GetSubMenu" dllcall last parameter of "1" is not correct, what am I missing?

Code: Select all

#SingleInstance,Force

; Find main window.
WinGet, main_window, ID, ahk_exe notepad.exe

; Get the menu.
menu_bar := DllCall("GetMenu", "uint", main_window)
sub_menu := DllCall("GetSubMenu", "uint", menu_bar, "int", 1)

DllCall("EnableMenuItem", "UInt", sub_menu, "UInt", 1, "UInt", 0x00000001L) ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms647636(v=vs.85).aspx

DllCall("DrawMenuBar", "UInt", main_window) ; refresh/redraw the menu so changes are visible
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Enable/disable external menuitem

23 Jul 2017, 17:58

In my tests, I was able to permanently change the status of menu items in all submenus, except for some in the Edit submenu.

A reason might be that some of those menu items have to be regularly updated, e.g. whether to enable/disable check/uncheck an item, based on whether: undo is available (Undo), text is selected (Cut/Copy/Delete), text is on the clipboard (Paste), the Edit control is empty (Find.../Find Next).

It appeared that the only items that remained disabled in the Edit submenu were: Replace..., Select All, Time/Date.

It appeared that the menu item appearances were updated immediately, even while the menu was shown. Cheers.

Code: Select all

q:: ;Notepad (Windows 7) - disable/enable menu item
WinGet, hWnd, ID, ahk_class Notepad
;using 1-based indices:
vMenuID := 1, vMenuItemID := 7 ;File, Print...
;vMenuID := 2, vMenuItemID := 13 ;Edit, Select All
;vMenuID := 3, vMenuItemID := 1 ;Format, Word Wrap
;vMenuID := 4, vMenuItemID := 1 ;View, Status Bar
;vMenuID := 5, vMenuItemID := 3 ;Help, About Notepad

hMenuBar := DllCall("user32\GetMenu", Ptr,hWnd, Ptr)
hSubMenu := DllCall("user32\GetSubMenu", Ptr,hMenuBar, Int,vMenuID-1, Ptr)
;MF_ENABLED := 0x0, MF_GRAYED := 0x1, MF_DISABLED := 0x2
;MF_BYCOMMAND := 0x0 ;MF_BYPOSITION := 0x400
DllCall("EnableMenuItem", Ptr,hSubMenu, UInt,vMenuItemID-1, UInt,0x403)
;DllCall("DrawMenuBar", Ptr,hWnd)

ToolTip disabled
Sleep 3000
DllCall("EnableMenuItem", Ptr,hSubMenu, UInt,vMenuItemID-1, UInt,0x400)
;DllCall("DrawMenuBar", Ptr,hWnd)
ToolTip enabled
Sleep 2000
ToolTip
return
Last edited by jeeswg on 23 Jul 2017, 23:18, edited 3 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
func
Posts: 47
Joined: 20 May 2016, 20:52

Re: Enable/disable external menuitem

23 Jul 2017, 18:09

Thank you, that's perfect, guess I just didn't understand the conversion of MF_ENABLED from the 0x00000001L to 0x0 thing
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Enable/disable external menuitem

23 Jul 2017, 23:41

For disabling sysmenu (alt-space menu) items see:
event hooks and blocking min/max/restore/close - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 24#p160424

DllCall just expects a number, it can't handle a trailing L. I've seen it in C++, it looks a bit curious, the L usage. Trouble with the L is either an understandable newbie thing, copying and pasting and expecting it to work, or an understandable veteran thing, expecting it to work like other languages, one extreme or the other.

I tested the XP versions of WordPad and Paint, and they always refresh the menus. Although you will see menu items disabled temporarily, if you disable items while a menu is showing. (I use Windows 7 but I copied the XP versions over.)

Code: Select all

q:: ;disable items
w:: ;enable items
;MF_ENABLED := 0x0, MF_GRAYED := 0x1, MF_DISABLED := 0x2
;MF_BYCOMMAND := 0x0 ;MF_BYPOSITION := 0x400
vFlags := InStr(A_ThisHotkey, "q") ? 0x403 : 0x400
WinGet, hWnd, ID, A
hMenuBar := DllCall("user32\GetMenu", Ptr,hWnd, Ptr)
Loop, 15
{
	hSubMenu := DllCall("user32\GetSubMenu", Ptr,hMenuBar, Int,A_Index-1, Ptr)
	Loop, 30
		DllCall("EnableMenuItem", Ptr,hSubMenu, UInt,A_Index-1, UInt,vFlags)
}
return
[EDIT:] Menu items can be referred to by command ID or by position. This is the significance of MF_BYCOMMAND and MF_BYPOSITION. For ID see:
Get Info from Context Menu (x64/x32 compatible) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=31971
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask For Help”

Who is online

Users browsing this forum: apilone, Flipeador, GraffFort, Skrell, Smile_, twiz and 37 guests