Search code examples
visual-prolog

How to get the text of a menu item with its ID


I have an old visual prolog project in which I have to change the text of a menu during runtime.
This is what I've done to change the text:

menu_setText(Win, id_menu, NewMenuText)

This works fine, however, when I want to enable/disable this menu, the following does not work (meaning the menu item doesn't change its state):

menu_Enable(Win, id_menu, b_true)

After some search, I found that:

Under MS-Windows, submenus can not be referred to by a resource identifier. If the menu entry for a submenu, needs to enabled, disabled, checked or have the text changed. it is necessary to use a special versions of the menu_Enable, menu_Check and menu_SetText predicates, which specify the text of the menu entry instead of the constant.
menu_Enable(WinHandle, String, BOOLEAN)
menu_Check(WinHandle, String, BOOLEAN)
menu_SetText(WinHandle, String, NewString)

The weird thing is that in my case, menu_setText works just fine with the constant where menu_Enable requires the text itself. (yes I tested menu_Enable with the initial text of the menu item, but when the text changes then everything breaks)

Here comes my question:

How can I enable/disable a menu when I know its ID but not its name ?
If not possible directly, how can I get the current name of a menu when I know its ID ?

In case this helps, this project is opened and compiled with VIP52 (since before the year 2001).


Solution

  • I finally found a workaround that solves my problem, but I'm still not really satisfied, so if anyone comes up with a better answer, I'll take it !

    I declared:

    txt_menu(menu_tag,string)
    

    And then called:

    txt_menu(id_menu, MenuText),
    menu_setText(Win, MenuText, NewText),
    retractAll(txt_menu(id_menu,_)),
    assert(txt_menu(id_menu,NewText)),
    menu_Update(Win)
    

    whenever I have to change the text of a menu item, and this can easily be transformed into a menu_setTextById predicate as such:

    menu_setTextById(Win, MenuId, NewText):-
        txt_menu(MenuId, MenuText),
        menu_setText(Win, MenuText, NewText),
        retractAll(txt_menu(MenuId,_)),
        assert(txt_menu(MenuId, NewText)),
        menu_Update(Win).
    

    with the usage:

    menu_setTextById(Win, id_menu, "My new text menu").
    

    Noted that if I ever have the need to have several windows with menus, I'll have to add the Window Id to my txt_menu clause.


    The main problem with this workaround is that I can't use & in the new text menu because if my menu has "&Menu" as text (meaning that M will be underlined), then trying to use menu_setText(Win,"&Menu","New Menu") will break because "&Menu" is not found.

    So I'd need to remove any ampersand from the string before trying to use it in such predicates.