diff --git a/container_windows.go b/container_windows.go index 31963e0..02da760 100644 --- a/container_windows.go +++ b/container_windows.go @@ -89,13 +89,13 @@ const ( paddingDialogUnits = 4 ) -func (w *window) beginResize() (d *sizing) { +func beginResize(hwnd C.HWND) (d *sizing) { var baseX, baseY C.int var internalLeading C.LONG d = new(sizing) - C.calculateBaseUnits(w.hwnd, &baseX, &baseY, &internalLeading) + C.calculateBaseUnits(hwnd, &baseX, &baseY, &internalLeading) d.baseX = baseX d.baseY = baseY d.internalLeading = internalLeading diff --git a/tab_windows.c b/tab_windows.c index 9a9908a..081129c 100644 --- a/tab_windows.c +++ b/tab_windows.c @@ -10,6 +10,8 @@ static LRESULT CALLBACK tabSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l { NMHDR *nmhdr = (NMHDR *) lParam; LRESULT r; + RECT resizeRect; + WINDOWPOS *wp; switch (uMsg) { case msgNOTIFY: @@ -27,6 +29,17 @@ static LRESULT CALLBACK tabSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam); case msgTabCurrentTabHasChildren: return (LRESULT) tabTabHasChildren((void *) data, SendMessageW(hwnd, TCM_GETCURSEL, 0, 0)); + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: + wp = (WINDOWPOS *) lParam; + resizeRect.left = wp->x; + resizeRect.top = wp->y; + resizeRect.right = wp->x + wp->cx; + resizeRect.bottom = wp->y + wp->cy; + tabGetContentRect(hwnd, &resizeRect); + tabResized((void *) data, resizeRect); + // and chain up + return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam); case WM_NCDESTROY: if ((*fv_RemoveWindowSubclass)(hwnd, tabSubProc, id) == FALSE) xpanic("error removing Tab subclass (which was for its own event handler)", GetLastError()); diff --git a/tab_windows.go b/tab_windows.go index 7203166..fc36d6a 100644 --- a/tab_windows.go +++ b/tab_windows.go @@ -20,6 +20,7 @@ type tab struct { tabs []*container children []Control chainresize func(x int, y int, width int, height int, d *sizing) + current int } func newTab() Tab { @@ -28,6 +29,7 @@ func newTab() Tab { 0) // don't set WS_EX_CONTROLPARENT here; see uitask_windows.c t := &tab{ controlSingleHWND: newControlSingleHWND(hwnd), + current: -1, } t.fpreferredSize = t.xpreferredSize t.chainresize = t.fresize @@ -61,7 +63,9 @@ func tabChanging(data unsafe.Pointer, current C.LRESULT) { //export tabChanged func tabChanged(data unsafe.Pointer, new C.LRESULT) { t := (*tab)(data) - t.tabs[int(new)].show() + t.current = int(new) + // TODO resize the new tab + t.tabs[t.current].show() } //export tabTabHasChildren @@ -89,27 +93,22 @@ func (t *tab) xpreferredSize(d *sizing) (width, height int) { return width, height + int(C.tabGetTabHeight(t.hwnd)) } -// a tab control contains other controls; size appropriately +// no need to resize the other controls; we do that in tabResized() which is called by the tab subclass handler func (t *tab) xresize(x int, y int, width int, height int, d *sizing) { - // first, chain up to the container base to keep the Z-order correct + // just chain up to the container base to keep the Z-order correct t.chainresize(x, y, width, height, d) - - // now resize the children - var r C.RECT - - // figure out what the rect for each child is... - // the tab contents are children of the tab itself, so ignore x and y, which are relative to the window! - r.left = C.LONG(0) - r.top = C.LONG(0) - r.right = C.LONG(width) - r.bottom = C.LONG(height) - C.tabGetContentRect(t.hwnd, &r) - // and resize tabs - // don't resize just the current tab; resize all tabs! - for i, _ := range t.tabs { - // because each widget is actually a child of the Window, the origin is the one we calculated above - t.tabs[i].resize(int(r.left), int(r.top), int(r.right - r.left), int(r.bottom - r.top), d) - // TODO get the actual client rect - t.children[i].resize(int(0), int(0), int(r.right - r.left), int(r.bottom - r.top), d) - } +} + +//export tabResized +func tabResized(data unsafe.Pointer, r C.RECT) { + t := (*tab)(data) + if t.current == -1 { // nothing to do + return + } + d := beginResize(t.hwnd) + // only need to resize the current tab; we resize new tabs when the tab changes in tabChanged() above + // because each widget is actually a child of the Window, the origin is the one we calculated above + t.tabs[t.current].resize(int(r.left), int(r.top), int(r.right - r.left), int(r.bottom - r.top), d) + // TODO get the actual client rect + t.children[t.current].resize(int(0), int(0), int(r.right - r.left), int(r.bottom - r.top), d) } diff --git a/window_windows.c b/window_windows.c index a4eefb3..8f618ab 100644 --- a/window_windows.c +++ b/window_windows.c @@ -28,7 +28,8 @@ static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA if (FillRect((HDC) wParam, &r, windowBackground) == 0) xpanic("error filling WM_PRINTCLIENT DC with window background color", GetLastError()); return lResult; - case WM_SIZE: + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: if (GetClientRect(hwnd, &r) == 0) xpanic("error getting client rect for Window in WM_SIZE", GetLastError()); windowResize(data, &r); diff --git a/window_windows.go b/window_windows.go index 8537be8..85a8c83 100644 --- a/window_windows.go +++ b/window_windows.go @@ -86,7 +86,7 @@ func (w *window) SetMargined(margined bool) { //export windowResize func windowResize(data unsafe.Pointer, r *C.RECT) { w := (*window)(data) - d := w.beginResize() + d := beginResize(w.hwnd) if w.margined { marginRectDLU(r, marginDialogUnits, marginDialogUnits, marginDialogUnits, marginDialogUnits, d) }