summaryrefslogtreecommitdiff
path: root/prefsize_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'prefsize_windows.go')
-rw-r--r--prefsize_windows.go122
1 files changed, 122 insertions, 0 deletions
diff --git a/prefsize_windows.go b/prefsize_windows.go
index cb44f2c..07a633f 100644
--- a/prefsize_windows.go
+++ b/prefsize_windows.go
@@ -71,6 +71,7 @@ var stdDlgSizes = [nctypes]dlgunits{
var (
_selectObject = gdi32.NewProc("SelectObject")
+ _getTextExtentPoint32 = gdi32.NewProc("GetTextExtentPoint32W")
_getTextMetrics = gdi32.NewProc("GetTextMetricsW")
_getWindowDC = user32.NewProc("GetWindowDC")
_releaseDC = user32.NewProc("ReleaseDC")
@@ -149,6 +150,127 @@ func muldiv(ma int, mb int, div int) int {
return int(int32(r1))
}
+// List Boxes do not dynamically handle horizontal scrollbars.
+// We have to manually handle this ourselves.
+// TODO make this run on the main thread when we switch to uitask taking function literals
+// TODO this is inefficient; some caching would be nice
+func recalcListboxWidth(hwnd _HWND) {
+ var size _SIZE
+
+ ret := make(chan uiret)
+ defer close(ret)
+ uitask <- &uimsg{
+ call: _sendMessage,
+ p: []uintptr{
+ uintptr(hwnd),
+ uintptr(_LB_GETCOUNT),
+ uintptr(0),
+ uintptr(0),
+ },
+ ret: ret,
+ }
+ r := <-ret
+ if r.ret == uintptr(_LB_ERR) { // failure
+ panic(fmt.Errorf("error getting number of items for Listbox width calculations: %v", r.err))
+ }
+ n := int(r.ret)
+ uitask <- &uimsg{
+ call: _getWindowDC,
+ p: []uintptr{uintptr(hwnd)},
+ ret: ret,
+ }
+ r = <-ret
+ if r.ret == 0 { // failure
+ panic(fmt.Errorf("error getting DC for Listbox width calculations: %v", r.err))
+ }
+ dc := _HANDLE(r.ret)
+ uitask <- &uimsg{
+ call: _selectObject,
+ p: []uintptr{
+ uintptr(dc),
+ uintptr(controlFont),
+ },
+ ret: ret,
+ }
+ r = <-ret
+ if r.ret == 0 { // failure
+ panic(fmt.Errorf("error loading control font into device context for Listbox width calculation: %v", r.err))
+ }
+ hextent := uintptr(0)
+ for i := 0; i < n; i++ {
+ uitask <- &uimsg{
+ call: _sendMessage,
+ p: []uintptr{
+ uintptr(hwnd),
+ uintptr(_LB_GETTEXTLEN),
+ uintptr(_WPARAM(i)),
+ uintptr(0),
+ },
+ ret: ret,
+ }
+ r := <-ret
+ if r.ret == uintptr(_LB_ERR) {
+ panic("UI library internal error: LB_ERR from LB_GETTEXTLEN in what we know is a valid listbox index (came from LB_GETSELITEMS)")
+ }
+ str := make([]uint16, r.ret)
+ uitask <- &uimsg{
+ call: _sendMessage,
+ p: []uintptr{
+ uintptr(hwnd),
+ uintptr(_LB_GETTEXT),
+ uintptr(_WPARAM(i)),
+ uintptr(_LPARAM(unsafe.Pointer(&str[0]))),
+ },
+ ret: ret,
+ }
+ r = <-ret
+ if r.ret == uintptr(_LB_ERR) {
+ panic("UI library internal error: LB_ERR from LB_GETTEXT in what we know is a valid listbox index (came from LB_GETSELITEMS)")
+ }
+ // r.ret is still the length of the string; this time without the null terminator
+ uitask <- &uimsg{
+ call: _getTextExtentPoint32,
+ p: []uintptr{
+ uintptr(dc),
+ uintptr(unsafe.Pointer(&str[0])),
+ r.ret,
+ uintptr(unsafe.Pointer(&size)),
+ },
+ ret: ret,
+ }
+ r = <-ret
+ if r.ret == 0 { // failure
+ panic(fmt.Errorf("error getting width of item %d text for Listbox width calculation: %v", i, r.err))
+ }
+ if hextent < uintptr(size.cx) {
+ hextent = uintptr(size.cx)
+ }
+ }
+ uitask <- &uimsg{
+ call: _releaseDC,
+ p: []uintptr{
+ uintptr(hwnd),
+ uintptr(dc),
+ },
+ ret: ret,
+ }
+ r = <-ret
+ if r.ret == 0 { // failure
+ panic(fmt.Errorf("error releasing DC for Listbox width calculations: %v", r.err))
+ }
+ uitask <- &uimsg{
+ call: _sendMessage,
+ p: []uintptr{
+ uintptr(hwnd),
+ uintptr(_LB_SETHORIZONTALEXTENT),
+ hextent,
+ uintptr(0),
+ },
+ ret: ret,
+ }
+ <-ret
+}
+
type _SIZE struct {
cx int32 // originally LONG
cy int32