diff --git a/button_windows.c b/button_windows.c index 39fb8e0a..0c9dafd5 100644 --- a/button_windows.c +++ b/button_windows.c @@ -23,6 +23,13 @@ static BOOL onWM_NOTIFY(uiControl *c, WPARAM wParam, LPARAM lParam, void *data, return FALSE; } +static void onWM_DESTROY(uiControl *c, void *data) +{ + struct button *b = (struct button *) data; + + uiFree(b); +} + // from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing #define buttonHeight 14 @@ -70,7 +77,8 @@ uiControl *uiNewButton(const char *text) p.hInstance = hInstance; p.onWM_COMMAND = onWM_COMMAND; p.onWM_NOTIFY = onWM_NOTIFY; - p.onCommandNotifyData = b; + p.onWM_DESTROY = onWM_DESTROY; + p.onCommandNotifyDestroyData = b; p.preferredSize = preferredSize; p.data = b; b->c = uiWindowsNewControl(&p); diff --git a/newcontrol_windows.c b/newcontrol_windows.c index eff4c9ad..98956faf 100644 --- a/newcontrol_windows.c +++ b/newcontrol_windows.c @@ -8,7 +8,8 @@ struct uiSingleHWNDControl { HWND hwnd; BOOL (*onWM_COMMAND)(uiControl *, WPARAM, LPARAM, void *, LRESULT *); BOOL (*onWM_NOTIFY)(uiControl *, WPARAM, LPARAM, void *, LRESULT *); - void *onCommandNotifyData; + void (*onWM_DESTROY)(uiControl *, void *); + void *onCommandNotifyDestroyData; void (*preferredSize)(uiControl *, int, int, LONG, intmax_t *, intmax_t *); void *data; }; @@ -56,16 +57,18 @@ static LRESULT CALLBACK singleSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, switch (uMsg) { case msgCOMMAND: - if ((*(c->onWM_COMMAND))((uiControl *) c, wParam, lParam, c->onCommandNotifyData, &lResult) != FALSE) + if ((*(c->onWM_COMMAND))((uiControl *) c, wParam, lParam, c->onCommandNotifyDestroyData, &lResult) != FALSE) return lResult; break; case msgNOTIFY: - if ((*(c->onWM_NOTIFY))((uiControl *) c, wParam, lParam, c->onCommandNotifyData, &lResult) != FALSE) + if ((*(c->onWM_NOTIFY))((uiControl *) c, wParam, lParam, c->onCommandNotifyDestroyData, &lResult) != FALSE) return lResult; break; - case WM_NCDESTROY: - // TODO call an onDestroy handler + case WM_DESTROY: + (*(c->onWM_DESTROY))((uiControl *) c, c->onCommandNotifyDestroyData); uiFree(c); + break; + case WM_NCDESTROY: if ((*fv_RemoveWindowSubclass)(hwnd, singleSubclassProc, uIdSubclass) == FALSE) logLastError("error removing Windows control subclass in singleSubclassProc()"); break; @@ -96,7 +99,8 @@ uiControl *uiWindowsNewControl(uiWindowsNewControlParams *p) c->onWM_COMMAND = p->onWM_COMMAND; c->onWM_NOTIFY = p->onWM_NOTIFY; - c->onCommandNotifyData = p->onCommandNotifyData; + c->onWM_DESTROY = p->onWM_DESTROY; + c->onCommandNotifyDestroyData = p->onCommandNotifyDestroyData; c->preferredSize = p->preferredSize; c->data = p->data; diff --git a/ui_windows.h b/ui_windows.h index cbbe8596..c86e6a95 100644 --- a/ui_windows.h +++ b/ui_windows.h @@ -23,8 +23,10 @@ struct uiWindowsNewControlParams { // Note that these are only issued if they come from the uiControl itself; notifications from children of the uiControl (such as a header control) will be received normally. BOOL (*onWM_COMMAND)(uiControl *c, WPARAM wParam, LPARAM lParam, void *data, LRESULT *lResult); BOOL (*onWM_NOTIFY)(uiControl *c, WPARAM wParam, LPARAM lParam, void *data, LRESULT *lResult); - // This is the data parameter to both of the above. - void *onCommandNotifyData; + // This is called in WM_DESTROY. + void (*onWM_DESTROY)(uiControl *c, void *data); + // This is the data parameter to all three of the above. + void *onCommandNotifyDestroyData; // This function is called when ui needs to know how to rearrange controls in a window. // baseX and baseY are the base units used to convert between dialog units and pixels.