Menu, MenuName, Delete and separator lines in submenus

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
iPhilip
Posts: 819
Joined: 02 Oct 2013, 12:21

Menu, MenuName, Delete and separator lines in submenus

Post by iPhilip » 05 Oct 2022, 14:21

[Moderator's note: Topic moved from Bug Reports.]

I believe there is a problem with the deletion of separator lines in submenus when the Menu, MenuName, Delete command is used to delete the menu and all submenus. Apparently, separator lines in the submenus are not deleted. The code below (based on Example #2) demonstrates the problem. After launching the script, press #z to show the menu and notice the residual separator lines at the bottom of the submenu.

Code: Select all

#NoEnv
; Create the popup menu by adding some items to it.
Start:
Menu, MyMenu, Add, Item1, MenuHandler
Menu, MyMenu, Add, Item2, MenuHandler
Menu, MyMenu, Add  ; Add a separator line.

; Create another menu destined to become a submenu of the above menu.
Menu, Submenu1, Add, Item1, MenuHandler
Menu, Submenu1, Add
Menu, Submenu1, Add, Item2, MenuHandler
Menu, Submenu1, Add
Menu, Submenu1, Add, Item3, MenuHandler

; Create a submenu in the first menu (a right-arrow indicator). When the user selects it, the second menu is displayed.
Menu, MyMenu, Add, My Submenu, :Submenu1

Menu, MyMenu, Add  ; Add a separator line below the submenu.
Menu, MyMenu, Add, Item3, MenuHandler  ; Add another menu item beneath the submenu.
return  ; End of script's auto-execute section.

MenuHandler:
MsgBox You selected %A_ThisMenuItem% from the menu %A_ThisMenu%.
return

#z::  ; i.e. press the Win-Z hotkey to show the menu.
   ; Menu, Submenu1, Delete  ; With this line, separator lines in the submenu are properly deleted.
   Menu, MyMenu, Delete
   Gosub, Start
   Menu, MyMenu, Show
return
The same issue occurs with AutoHotkey v2:

Code: Select all

; Create the popup menu by adding some items to it.
MyMenu := Menu()
Submenu1 := Menu()
CreateMenu

CreateMenu() {
   MyMenu.Add "Item 1", MenuHandler
   MyMenu.Add "Item 2", MenuHandler
   MyMenu.Add  ; Add a separator line.

   ; Create another menu destined to become a submenu of the above menu.
   Submenu1.Add "Item A", MenuHandler
   Submenu1.Add
   Submenu1.Add "Item B", MenuHandler
   Submenu1.Add
   Submenu1.Add "Item C", MenuHandler

   ; Create a submenu in the first menu (a right-arrow indicator). When the user selects it, the second menu is displayed.
   MyMenu.Add "My Submenu", Submenu1

   MyMenu.Add  ; Add a separator line below the submenu.
   MyMenu.Add "Item 3", MenuHandler  ; Add another menu item beneath the submenu.
}

MenuHandler(Item, *) {
    MsgBox "You selected " Item
}

#z::  ; i.e. press the Win-Z hotkey to show the menu.
{
   ; Submenu1.Delete  ; With this line, separator lines in the submenu are properly deleted.
   MyMenu.Delete
   CreateMenu
   MyMenu.Show
}
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Menu, MenuName, Delete and separator lines in submenus

Post by just me » 06 Oct 2022, 04:13

... Deleting a menu also causes the current Win32 menu of its parent and submenus to be destroyed, to be recreated later as needed.
I.e. the internal AHK structures for the submenu remain unchanged. Menu, MyMenu, Add, MyItem for an existing item will update the item in this case. This is not possible for unnamed items like separator lines, so they still are added.

iPhilip
Posts: 819
Joined: 02 Oct 2013, 12:21

Re: Menu, MenuName, Delete and separator lines in submenus

Post by iPhilip » 08 Oct 2022, 13:13

just me wrote:
06 Oct 2022, 04:13
I.e. the internal AHK structures for the submenu remain unchanged. Menu, MyMenu, Add, MyItem for an existing item will update the item in this case. This is not possible for unnamed items like separator lines, so they still are added.
Thank you, @just me, That helps.
just me wrote:
06 Oct 2022, 04:13
... Deleting a menu also causes the current Win32 menu of its parent and submenus to be destroyed...
The code below seems to demonstrate that submenus are not destroyed:

Code: Select all

; Create the popup menu by adding some items to it.
Menu, MyMenu, Add, Item1, MenuHandler
Menu, MyMenu, Add, Item2, MenuHandler
Menu, MyMenu, Add  ; Add a separator line.

; Create another menu destined to become a submenu of the above menu.
Menu, Submenu1, Add, Item1, MenuHandler
Menu, Submenu1, Add, Item2, MenuHandler

; Create a submenu in the first menu (a right-arrow indicator). When the user selects it, the second menu is displayed.
Menu, MyMenu, Add, My Submenu, :Submenu1

Menu, MyMenu, Add  ; Add a separator line below the submenu.
Menu, MyMenu, Add, Item3, MenuHandler  ; Add another menu item beneath the submenu.

; ----
Menu, MyMenu, Delete  ; This destroys the MyMenu menu and, according to the documentation, the Submenu1 menu as well.
Menu, Submenu1, Show  ; The Submenu1 menu still exists.
; ----

return  ; End of script's auto-execute section.

MenuHandler:
MsgBox You selected %A_ThisMenuItem% from the menu %A_ThisMenu%.
return
Perhaps, the documentation needs to be updated?
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: Menu, MenuName, Delete and separator lines in submenus

Post by lexikos » 08 Oct 2022, 23:54

Read the links for "Win32 menu". The submenu itself and the Win32 menu of the submenu are not the same thing. The documentation does not claim that the submenu itself is deleted or destroyed, or that any of its items are permanently deleted. What it says is that the Win32 menu will be destroyed and recreated.

The submenu items are not being deleted, as just me explained.

If you do not show the menu, add it to a GUI or call MenuGetHandle prior to deleting the menu, there won't even be a Win32 menu to destroy.

If you do not call MenuGetHandle, it is unlikely to matter whether the Win32 menu is destroyed or not. With simple use of the menu such as what you've demonstrated, there is no observable difference. You might notice if you've added the standard items anywhere other than the top of the menu, since that's where they are placed if the Win32 menu is recreated (but that isn't relevant if you explicitly delete the menu itself).

This shows that the Win32 menus of the target and sub-menu are deleted:

Code: Select all

Menu Sub, Add, Item, Q
Menu Target, Add, This is Target, Q
Menu Target, Add, Sub menu, :Sub
Menu Parent, Add, This is Parent, Q
Menu Parent, Add, Target menu, :Target
parent := MenuGetHandle("Parent"), target := MenuGetHandle("Target"), sub := MenuGetHandle("Sub")
Menu Target, Delete
MsgBox % DllCall("IsMenu", "ptr", parent) DllCall("IsMenu", "ptr", target) DllCall("IsMenu", "ptr", sub)
Q:
ExitApp
This shows one case where a parent menu can be destroyed:

Code: Select all

Menu Sub, Add, Item, Q
Menu Target, Add, This is Target, Q
Menu Target, Add, Sub menu, :Sub
Menu Parent, Add, This is Parent, Q
Menu Parent, Add, Target menu, :Target
parent := MenuGetHandle("Parent"), target := MenuGetHandle("Target"), sub := MenuGetHandle("Sub")
Menu Parent2, Add, Target menu, :Target
MenuGetHandle("Parent2") ; Create the Win32 menu
Menu Parent2, Add, Target menu, Q
MsgBox % DllCall("IsMenu", "ptr", parent) DllCall("IsMenu", "ptr", target) DllCall("IsMenu", "ptr", sub)
Q:
ExitApp

Delete in v2 is basically equivalent to DeleteAll in v1. It deletes all items, leaving the menu itself intact with no items. The v2 menus are carefully designed to ensure that the Win32 menus are not destroyed before the Menu object. There should be nothing in the v2 documentation to indicate that Delete will affect a submenu.

Post Reply

Return to “Ask for Help (v1)”