Pop Up Menu Question

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • Pop Up Menu Question

    Hello,

    I am developing an application which makes use of several pop up menus that are built on-the-fly. The menus are created using:

    MENU_Handle hMenu = MENU_CreateEx(0, 0, 0, 0, WM_UNATTACHED, 0, MENU_CF_VERTICAL, 0);

    and populated:

    static void prvAddEntry(MENU_Handle hMenu, const char *label, U16 id, U16 flags) {
    MENU_ITEM_DATA entry;

    entry.pText = label;
    entry.Id = id;
    entry.Flags = flags;
    entry.hSubmenu = 0;

    MENU_AddItem(hMenu, &entry);
    }

    If I need to display the menu, then calling:

    MENU_Popup(hMenu, hDialog, 0, 0, 0, 0, 0);
    WM_SetFocus(hMenu);

    shows the menu and gives it keyboard focus. The problem I am having occurs when I come to delete the menu. The manual states that the menu will not be automatically deleted, but when I call WM_DeleteWindow(hMenu) I get a bus fault exception with a PC in GUI_ALLOC_h2p and link register in WM__GetTopLevelLayer.

    What is the correct way to delete a pop up menu widget and free the resources that have been allocated?

    Regards,

    Craig
  • Hello,

    Unfortunately I do not know exactly how you are going to use the MENU widget. I changed the WIDGET_PopupMenu.c sample to delete the widget every time the background was clicked. This works well. Please refer to the function _OpenPopup() in the attached application.

    Best regards,
    Adrian
    Files
  • Hello Adrian,

    I have adapted your exemplar code to test in my application:

    typedef struct {
    char * sText;
    U16 Id;
    U16 Flags;
    } MENU_ITEM;

    static MENU_ITEM _aMenuItems[] = {
    {"New game", 1, 0},
    {"Pass", 2, 0},
    {0, 0, MENU_IF_SEPARATOR},
    {"Exit", 3, 0},
    };

    static void _AddMenuItem(MENU_Handle hMenu, MENU_Handle hSubmenu, const char* pText, U16 Id, U16 Flags) {
    MENU_ITEM_DATA Item;

    Item.pText = pText;
    Item.hSubmenu = hSubmenu;
    Item.Flags = Flags;
    Item.Id = Id;
    MENU_AddItem(hMenu, &Item);
    }

    static void _testCode(void) {
    MENU_Handle hMenu;
    int i;

    hMenu = MENU_CreateEx(0, 0, 0, 0, WM_UNATTACHED, 0, MENU_CF_VERTICAL, 0);
    for (i = 0; i < GUI_COUNTOF(_aMenuItems); i++) {
    _AddMenuItem(hMenu, 0, _aMenuItems.sText, _aMenuItems[i].Id, _aMenuItems[i].Flags);
    }

    WM_DeleteWindow(hMenu);
    }

    As you see in _testCode(), I simply create the menu and delete the window that is returned. When stepping through the function, hMenu is a positive integer (in the last test it was 53) and the code aborts on the WM_DeleteWindow() call. My exception handler returns the following output:

    *** Bus Fault Exception ***
    R0: 0x01cc0458, R1: 0xc1801f38, R2: 0xc1801f38, R3: 0x20029cb0
    SP: 0x2000d618, LR: 0x0806f4f1, PC: 0x0807b342, PSR: 0x41000000
    Bus Fault Cause:
    Data Bus Error at LR
    Address: 0x01cc045c

    where the Link Register (LR) is given the symbol WM__GetTopLevelLayer by addr2line and the Program Counter (PC) is GUI_ALLOC_h2p. The address that is returned in the Bus Fault Address Register (0x01cc045c) is not in the addressable space.

    My main application is a state machine in which each state creates its own dynamic dialog window. When states are transitioned, the dialog window is destroyed by calling WM_DeleteWindow() and the new dialog is created. I have created a dozen or so states and their associated dialog boxes and everything works except cleaning up the pop-up menu.

    Any help you can offer in resolving this issue will be gratefully received.

    Regards,

    Craig
  • Hello Craig,

    As far as I can see the function WM__GetTopLevelLayer() is called only in case the application uses more than one layer. Could you please verify if there is memory used for a layer which is not or not completely addressable?

    Best regards,
    Adrian
  • Hello Adrian,

    Have you any thoughts on this problem? I am still struggling to see how to free the resources allocated to a pop-up menu. I have isolated the issue to just two lines of code. Simply creating the menu and deleting it straight away causes the bus fault when WM_DeleteWindow is called:

    MENU_Handle hMenu = MENU_CreateEx(0, 0, 0, 0, WM_UNATTACHED, 0, MENU_CF_VERTICAL, 0);
    WM_DeleteWindow(hMenu);

    However, if the menu is attached to a window:

    MENU_Handle hMenu = MENU_CreateEx(0, 0, 0, 0, WM_HBKWIN, 0, MENU_CF_VERTICAL, 0);
    WM_DeleteWindow(hMenu);

    then no bus fault occurs.

    What is the correct way to create a pop-up menu that may or may not be displayed before deletion?

    Regards,

    Craig

    The post was edited 1 time, last by craig.stracey ().

  • Hello Adrian,

    I have checked (and double checked) the linker, etc. I have been very generous with stack sizes, memory pools and frame buffers. In total emWin has been allocated over 12MB of RAM. I have confirmed that task stacks and the emWin memory pool have not over run.

    Do you have any idea why I see the issue if the menu is created with a parent window of WM_UNATTACHED, but not if the parent window is WM_HBKWIN?

    Regards,

    Craig
  • Hello Adrian,

    Some further investigation shows that it is a problem with deleting menus that are currently not displayed. If I have a menu with four submenus (the submenus have item Ids of 100..103) then the following function call will delete the menu without faulting:

    void menuDestroy(MENU_Handle hMenu) {
    uint8_t i;

    MENU_Popup(hMenu, WM_HBKWIN, 0, 0, 0, 0, 0);

    for(i = 100; i < 104; i++) {
    MENU_ITEM_DATA item;

    MENU_GetItem(hMenu, i, &item);

    MENU_Popup(item.hSubmenu, WM_HBKWIN, 0, 0, 0, 0, 0);
    }

    WM_DeleteWindow(hMenu);
    }

    If I do not call MENU_Popup() then a bus fault occurs. Can this be fixed?

    Regards,

    Craig
  • Hello Craig,

    Thank you for providing the information. I will step into this and try to find out if this problem is caused by the MENU widget. Unfortunately I can not tell you when I will be able to have a look at this, so this might take a while.

    Best regards,
    Adrian
  • Hello,

    I had nearly the same problem.

    I’m using a Desktop like GUI creating and destroying FRAMEWIN-Widgets.

    Everything works fine, until I included a Menu widget in one Frame Window.

    On closing the FameWin the whole application stalls (Hardfault) anywhere In GUI_ALLOC_h2p()

    I strip everything down to just creating the menu and deleting it with the same result as craig.stracey

    After a long time of debugging I found this thread and his workaround with opening all sub menus before deleting works for me.

    Thanks to craig.stracey :thumbsup: :thumbsup: :thumbup: :thumbup:

    I’m using the Pre compiled library for STM32F7 Microcontroller with OS support (STemWin528_CM7_OS_Keil_ot.lib).
    Target hardware is the STM32F7-Discovery-Board.

    Are there any Updates on this issue from your side?

    Regards
    Christian

    The post was edited 1 time, last by mc_meyer ().

  • I figured out, that the easiest way to implement that workaround is to setup a callback for all menu widgets that only catches the WM_DELETE Message. Then calling MENU_POPUP(pMsg->hWin,WM_HBKWIN,0,0,0,0,0);
    (Did i miss the Function MENUE_SetDefaultCalback() !? or why doesnt it exist?);

    C Source Code

    1. void cbMenue(WM_MESSAGE * pMsg)
    2. {
    3. switch(pMsg->MsgId)
    4. {
    5. case WM_DELETE:
    6. MENU_Popup(pMsg->hWin,WM_HBKWIN,0,0,0,0,0);
    7. break;
    8. default:
    9. MENU_Callback(pMsg);
    10. break;
    11. }
    12. }
    Display All


    Now I can use the Menu as supposed.
    but I think someone should have a look in the sorce code to investigate that behaviour.

    Regards
    Christian

    The post was edited 1 time, last by mc_meyer ().