diff --git a/unix/menu.c b/unix/menu.c index 69c0dfc9..8e760502 100644 --- a/unix/menu.c +++ b/unix/menu.c @@ -340,4 +340,5 @@ void freeMenubar(GtkWidget *mb) i = 0; gtk_container_foreach(GTK_CONTAINER(mb), freeMenu, &i); + // no need to worry about destroying any widgets; destruction of the window they're in will do it for us } diff --git a/windows/menu.c b/windows/menu.c index 2aa02a0b..6409ca86 100644 --- a/windows/menu.c +++ b/windows/menu.c @@ -1,8 +1,7 @@ // 24 april 2015 #include "uipriv_windows.h" -// TODO window destruction - +// TODO turn this into struct menu ** static struct menu *menus = NULL; static uintmax_t len = 0; static uintmax_t cap = 0; @@ -12,6 +11,7 @@ static WORD curID = 100; // start somewhere safe struct menu { uiMenu m; WCHAR *name; + // TODO turn into struct menuItem ** struct menuItem *items; uintmax_t len; uintmax_t cap; @@ -326,3 +326,39 @@ found: // then run the event (*(item->onClicked))(umi, w, item->onClickedData); } + +static void freeMenu(struct menu *m, HMENU submenu) +{ + uintmax_t i; + struct menuItem *item; + uintmax_t j; + + for (i = 0; i < m->len; i++) { + item = &m->items[i]; + for (j = 0; j < item->len; j++) + if (item->hmenus[j] == submenu) + break; + if (j >= item->len) + complain("submenu handle %p not found in freeMenu()", submenu); + for (; j < item->len - 1; j++) + item->hmenus[j] = item->hmenus[j + 1]; + item->hmenus[j] = NULL; + item->len--; + } +} + +void freeMenubar(HMENU menubar) +{ + uintmax_t i; + MENUITEMINFOW mi; + + for (i = 0; i < len; i++) { + ZeroMemory(&mi, sizeof (MENUITEMINFOW)); + mi.cbSize = sizeof (MENUITEMINFOW); + mi.fMask = MIIM_SUBMENU; + if (GetMenuItemInfoW(menubar, i, TRUE, &mi) == 0) + logLastError("error getting menu to delete item references from in freeMenubar()"); + freeMenu(&menus[i], mi.hSubMenu); + } + // no need to worry about destroying any menus; destruction of the window they're in will do it for us +} diff --git a/windows/uipriv_windows.h b/windows/uipriv_windows.h index 01fc0f23..b610571d 100644 --- a/windows/uipriv_windows.h +++ b/windows/uipriv_windows.h @@ -77,3 +77,4 @@ extern const char *initContainer(HICON, HCURSOR); extern HMENU makeMenubar(void); extern const uiMenuItem *menuIDToItem(UINT_PTR); extern void runMenuEvent(WORD, uiWindow *); +extern void freeMenubar(HMENU); diff --git a/windows/window.c b/windows/window.c index 0e8f9820..47de1d08 100644 --- a/windows/window.c +++ b/windows/window.c @@ -86,7 +86,9 @@ static void windowDestroy(uiControl *c) // now destroy the bin // the bin has no parent, so we can just call uiControlDestroy() uiControlDestroy(uiControl(w->bin)); - // TODO menus + // now free the menubar, if any + if (w->menubar != NULL) + freeMenubar(w->menubar); // now destroy ourselves if (DestroyWindow(w->hwnd) == 0) logLastError("error destroying uiWindow in windowDestroy()");