From efd94b25280ff49688ed3a41cbb525cd4b5bd881 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sat, 18 Apr 2015 14:16:06 -0400 Subject: [PATCH] Continued implementing Windows lifetime code. Now for uiTab. --- windows/parent.c | 12 +++++++++++- windows/window.c | 14 +++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/windows/parent.c b/windows/parent.c index 491ebe6b..f9d5a263 100644 --- a/windows/parent.c +++ b/windows/parent.c @@ -102,6 +102,7 @@ struct parent { intmax_t marginTop; intmax_t marginRight; intmax_t marginBottom; + BOOL canDestroy; }; static LRESULT CALLBACK parentWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -158,7 +159,8 @@ static LRESULT CALLBACK parentWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA pp = (struct parent *) (p->Internal); switch (uMsg) { case WM_NCDESTROY: - // no need to explicitly destroy children; they're already gone by this point (and so are their data structures; they clean up after themselves) + if (!pp->canDestroy) + complain("attempt to destroy uiParent at %p before uiParentDestroy()", p); uiFree(p->Internal); uiFree(p); break; // fall through to DefWindowPocW() @@ -215,6 +217,14 @@ static void parentDestroy(uiParent *pp) { struct parent *p = (struct parent *) (pp->Internal); + // first destroy the main control, if any + if (p->mainControl != NULL) { + uiControlDestroy(p->mainControl); + p->mainControl = NULL; + } + // then mark that we are ready to destroy + p->canDestroy = TRUE; + // and finally destroy if (DestroyWindow(p->hwnd) == 0) logLastError("error destroying uiParent window in parentDestroy()"); } diff --git a/windows/window.c b/windows/window.c index eb6a552f..181a9f95 100644 --- a/windows/window.c +++ b/windows/window.c @@ -9,6 +9,7 @@ struct window { int (*onClosing)(uiWindow *, void *); void *onClosingData; int margined; + BOOL canDestroy; }; #define uiWindowClass L"uiWindowClass" @@ -42,10 +43,11 @@ static LRESULT CALLBACK uiWindowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPA return 0; case WM_CLOSE: if (!(*(w->onClosing))(uiWindow(w), w->onClosingData)) - return 0; - break; // fall through to DefWindowProcW() + uiWindowDestroy(uiWindow(w)); + return 0; // we destroyed it already case WM_DESTROY: - // no need to free the child ourselves; it'll destroy itself after we leave this handler + if (!w->canDestroy) + complain("attempt to destroy uiWindow at %p before uiWindowDestroy()", w); uiFree(w); break; // fall through to DefWindowProcW() } @@ -78,6 +80,12 @@ static void windowDestroy(uiWindow *ww) { struct window *w = (struct window *) ww; + // first destroy the content + uiParentDestroy(w->content); + // then mark that we're ready to destroy + w->canDestroy = TRUE; + // and finally destroy + // TODO check for errors DestroyWindow(w->hwnd); }