From b6055d8a3557a589a6acc24741074459b9a4f811 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Mon, 27 Oct 2014 10:41:10 -0400 Subject: [PATCH] Fixed Group on Windows not sending events to children. I /think/ we're done with container madness on the Windows backend... --- basicctrls_windows.c | 33 +++++++++++++++++++++++++++++++++ group_windows.go | 25 +++++++++---------------- winapi_windows.h | 1 + 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/basicctrls_windows.c b/basicctrls_windows.c index 8947187..8a4cc9a 100644 --- a/basicctrls_windows.c +++ b/basicctrls_windows.c @@ -127,3 +127,36 @@ void textfieldHideInvalidBalloonTip(HWND hwnd) if (SendMessageW(hwnd, EM_HIDEBALLOONTIP, 0, 0) == FALSE) xpanic("error hiding TextField.Invalid() balloon tip", GetLastError()); } + +static LRESULT CALLBACK groupSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR id, DWORD_PTR data) +{ + LRESULT lResult; + RECT r; + + if (sharedWndProc(hwnd, uMsg, wParam, lParam, &lResult)) + return lResult; + switch (uMsg) { + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: + // don't use the WINDOWPOS rect here; the coordinates of the controls have to be in real client coordinates + if (GetClientRect(hwnd, &r) == 0) + xpanic("error getting client rect of Group for resizing its child Control", GetLastError()); + groupResized((void *) data, r); + // and chain up + return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam); + case WM_NCDESTROY: + if ((*fv_RemoveWindowSubclass)(hwnd, groupSubProc, id) == FALSE) + xpanic("error removing Group subclass (which was for its own event handler)", GetLastError()); + return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam); + default: + return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam); + } + xmissedmsg("Group", "groupSubProc()", uMsg); + return 0; // unreached +} + +void setGroupSubclass(HWND hwnd, void *data) +{ + if ((*fv_SetWindowSubclass)(hwnd, groupSubProc, 0, (DWORD_PTR) data) == FALSE) + xpanic("error subclassing Group to give it its own event handler", GetLastError()); +} diff --git a/group_windows.go b/group_windows.go index 8666b99..18a3cc6 100644 --- a/group_windows.go +++ b/group_windows.go @@ -2,6 +2,10 @@ package ui +import ( + "unsafe" +) + // #include "winapi_windows.h" import "C" @@ -9,7 +13,6 @@ type group struct { *controlSingleHWNDWithText child Control margined bool - chainresize func(x int, y int, width int, height int, d *sizing) } func newGroup(text string, control Control) Group { @@ -21,11 +24,10 @@ func newGroup(text string, control Control) Group { child: control, } g.fpreferredSize = g.xpreferredSize - g.chainresize = g.fresize - g.fresize = g.xresize g.fnTabStops = control.nTabStops // groupbox itself is not tabbable but the contents might be g.SetText(text) C.controlSetControlFont(g.hwnd) + C.setGroupSubclass(g.hwnd, unsafe.Pointer(g)) control.setParent(&controlParent{g.hwnd}) return g } @@ -75,19 +77,10 @@ func (g *group) xpreferredSize(d *sizing) (width, height int) { return int(r.right - r.left), int(r.bottom - r.top) } -func (g *group) xresize(x int, y int, width int, height int, d *sizing) { - // first, chain up to the container base to keep the Z-order correct - g.chainresize(x, y, width, height, d) - - // now resize the child container - var r C.RECT - - // pretend that the client area of the group box only includes the actual empty space - // container will handle the necessary adjustments properly - r.left = 0 - r.top = 0 - r.right = C.LONG(width) - r.bottom = C.LONG(height) +//export groupResized +func groupResized(data unsafe.Pointer, r C.RECT) { + g := (*group)(unsafe.Pointer(data)) + d := beginResize(g.hwnd) if g.margined { // see above marginRectDLU(&r, groupYMarginTop, groupYMarginBottom, groupXMargin, groupXMargin, d) diff --git a/winapi_windows.h b/winapi_windows.h index a7ee19e..f1a22a1 100644 --- a/winapi_windows.h +++ b/winapi_windows.h @@ -74,6 +74,7 @@ extern void checkboxSetChecked(HWND, BOOL); extern void setTextFieldSubclass(HWND, void *); extern void textfieldSetAndShowInvalidBalloonTip(HWND, WCHAR *); extern void textfieldHideInvalidBalloonTip(HWND); +extern void setGroupSubclass(HWND, void *); // init_windows.c extern HINSTANCE hInstance;