From 071ebcf5be6a0c62f502901e1713cc7ba82fac47 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Thu, 30 Oct 2014 10:42:59 -0400 Subject: [PATCH] Fixed Windows Spinbox sizing for now. --- basicctrls_windows.c | 26 ++++++++++++++++++++++++-- spinbox_windows.go | 30 ++++++++++++++++++++++++------ winapi_windows.h | 2 +- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/basicctrls_windows.c b/basicctrls_windows.c index b75633e..eefd4f8 100644 --- a/basicctrls_windows.c +++ b/basicctrls_windows.c @@ -161,5 +161,27 @@ void setGroupSubclass(HWND hwnd, void *data) xpanic("error subclassing Group to give it its own event handler", GetLastError()); } -// provided for cgo's benefit -LPWSTR xUPDOWN_CLASSW = UPDOWN_CLASSW; +HWND newUpDown(HWND prevUpDown) +{ + HWND hwnd; + HWND parent; + + parent = msgwin; // for the first up-down + if (prevUpDown != NULL) { + parent = GetParent(prevUpDown); + if (parent == NULL) + xpanic("error getting parent of old up-down in Spinbox resize for new up-down", GetLastError()); + if (DestroyWindow(prevUpDown) == 0) + xpanic("error destroying previous up-down in Spinbox resize", GetLastError()); + } + hwnd = CreateWindowExW(0, + UPDOWN_CLASSW, L"", + // no WS_VISIBLE; we set visibility ourselves + WS_CHILD | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_HOTTRACK | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, + // this is important; it's necessary for autosizing to work + 0, 0, 0, 0, + parent, NULL, hInstance, NULL); + if (hwnd == NULL) + xpanic("error creating up-down control for Spinbox", GetLastError()); + return hwnd; +} diff --git a/spinbox_windows.go b/spinbox_windows.go index 6d6cb5e..42f21b4 100644 --- a/spinbox_windows.go +++ b/spinbox_windows.go @@ -14,6 +14,8 @@ import "C" type spinbox struct { hwndEdit C.HWND hwndUpDown C.HWND + // updown state + updownVisible bool } func newSpinbox() Spinbox { @@ -21,12 +23,8 @@ func newSpinbox() Spinbox { s.hwndEdit = C.newControl(editclass, C.textfieldStyle | C.ES_NUMBER, C.textfieldExtStyle) - s.hwndUpDown = C.newControl(C.xUPDOWN_CLASSW, - C.UDS_ALIGNRIGHT | C.UDS_ARROWKEYS | C.UDS_HOTTRACK | C.UDS_NOTHOUSANDS | C.UDS_SETBUDDYINT, - 0) - C.SendMessageW(s.hwndUpDown, C.UDM_SETBUDDY, C.WPARAM(uintptr(unsafe.Pointer(s.hwndEdit))), 0) - C.SendMessageW(s.hwndUpDown, C.UDM_SETRANGE32, 0, 100) - C.SendMessageW(s.hwndUpDown, C.UDM_SETPOS32, 0, 0) + s.updownVisible = true // initially shown + s.remakeUpDown() return s } @@ -35,6 +33,23 @@ func (s *spinbox) setParent(p *controlParent) { C.controlSetParent(s.hwndUpDown, p.hwnd) } +// an up-down control will only properly position itself the first time +// stupidly, there are no messages to force a size calculation, nor can I seem to reset the buddy window to force a new position +// alas, we have to make a new up/down control each time :( +// TODO we'll need to store a copy of the current position and range for this +func (s *spinbox) remakeUpDown() { + // destroying the previous one and setting the parent properly is handled here + s.hwndUpDown = C.newUpDown(s.hwndUpDown) + // for this to work, hwndUpDown needs to have rect [0 0 0 0] + C.moveWindow(s.hwndUpDown, 0, 0, 0, 0) + C.SendMessageW(s.hwndUpDown, C.UDM_SETBUDDY, C.WPARAM(uintptr(unsafe.Pointer(s.hwndEdit))), 0) + C.SendMessageW(s.hwndUpDown, C.UDM_SETRANGE32, 0, 100) + C.SendMessageW(s.hwndUpDown, C.UDM_SETPOS32, 0, 0) + if s.updownVisible { + C.ShowWindow(s.hwndUpDown, C.SW_SHOW) + } +} + func (s *spinbox) preferredSize(d *sizing) (width, height int) { // TODO return 20, 20 @@ -42,6 +57,7 @@ func (s *spinbox) preferredSize(d *sizing) (width, height int) { func (s *spinbox) resize(x int, y int, width int, height int, d *sizing) { C.moveWindow(s.hwndEdit, C.int(x), C.int(y), C.int(width), C.int(height)) + s.remakeUpDown() } func (s *spinbox) nTabStops() int { @@ -53,10 +69,12 @@ func (s *spinbox) nTabStops() int { func (s *spinbox) containerShow() { C.ShowWindow(s.hwndEdit, C.SW_SHOW) C.ShowWindow(s.hwndUpDown, C.SW_SHOW) + s.updownVisible = true } // TODO be sure to modify this when we add Show()/Hide() func (s *spinbox) containerHide() { C.ShowWindow(s.hwndEdit, C.SW_HIDE) C.ShowWindow(s.hwndUpDown, C.SW_HIDE) + s.updownVisible = false } diff --git a/winapi_windows.h b/winapi_windows.h index 48b0a54..0c8cc23 100644 --- a/winapi_windows.h +++ b/winapi_windows.h @@ -75,7 +75,7 @@ extern void setTextFieldSubclass(HWND, void *); extern void textfieldSetAndShowInvalidBalloonTip(HWND, WCHAR *); extern void textfieldHideInvalidBalloonTip(HWND); extern void setGroupSubclass(HWND, void *); -extern LPWSTR xUPDOWN_CLASSW; +extern HWND newUpDown(HWND); // init_windows.c extern HINSTANCE hInstance;