From 063293456d929ffab90b8b8c9e609083644b04a1 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sat, 15 Feb 2014 14:03:46 -0500 Subject: [PATCH] More error handling reduction. --- sysdata.go | 8 +++--- sysdata_windows.go | 66 ++++++++++++++++++++++++++-------------------- todo.md | 1 + winerrors.md | 3 +++ 4 files changed, 45 insertions(+), 33 deletions(-) diff --git a/sysdata.go b/sysdata.go index 4f5c017..b3b3898 100644 --- a/sysdata.go +++ b/sysdata.go @@ -30,7 +30,7 @@ func (c *cSysData) setRect(x int, y int, width int, height int) error { func (c *cSysData) isChecked() bool { panic(runtime.GOOS + " sysData does not define isChecked()") } -func (c *cSysData) text() (string, error) { +func (c *cSysData) text() string { panic(runtime.GOOS + " sysData does not define text()") } func (c *cSysData) append(string) error { @@ -39,13 +39,13 @@ func (c *cSysData) append(string) error { func (c *cSysData) insertBefore(string, int) error { panic(runtime.GOOS + " sysData does not define insertBefore()") } -func (c *cSysData) selectedIndex() (int, error) { +func (c *cSysData) selectedIndex() int { panic(runtime.GOOS + " sysData does not define selectedIndex()") } -func (c *cSysData) selectedIndices() ([]int, error) { +func (c *cSysData) selectedIndices() []int { panic(runtime.GOOS + " sysData does not define selectedIndices()") } -func (c *cSysData) selectedTexts() ([]string, error) { +func (c *cSysData) selectedTexts() []string { panic(runtime.GOOS + " sysData does not define selectedIndex()") } func (c *cSysData) setWindowSize(int, int) error { diff --git a/sysdata_windows.go b/sysdata_windows.go index 34ec3cb..7458f45 100644 --- a/sysdata_windows.go +++ b/sysdata_windows.go @@ -29,6 +29,7 @@ type classData struct { deleteMsg uintptr selectedIndexMsg uintptr selectedIndexErr int + addSpaceErr int } const controlstyle = _WS_CHILD | _WS_VISIBLE | _WS_TABSTOP @@ -59,6 +60,7 @@ var classTypes = [nctypes]*classData{ deleteMsg: _CB_DELETESTRING, selectedIndexMsg: _CB_GETCURSEL, selectedIndexErr: _CB_ERR, + addSpaceErr: _CB_ERRSPACE, }, c_lineedit: &classData{ name: "EDIT", @@ -81,6 +83,7 @@ var classTypes = [nctypes]*classData{ deleteMsg: _LB_DELETESTRING, selectedIndexMsg: _LB_GETCURSEL, selectedIndexErr: _LB_ERR, + addSpaceErr: _LB_ERRSPACE, }, } @@ -293,7 +296,6 @@ func (s *sysData) text() (str string) { return syscall.UTF16ToString(tc) } -// TODO figure out how to handle errors func (s *sysData) append(what string) (err error) { ret := make(chan uiret) defer close(ret) @@ -307,12 +309,15 @@ func (s *sysData) append(what string) (err error) { }, ret: ret, } - <-ret - // TODO error handling + r := <-ret + if r.ret == uintptr(classTypes[s.ctype].addSpaceErr) { + return fmt.Errorf("out of space adding item to combobox/listbox (last error: %v)", r.err) + } else if r.ret == uintptr(classTypes[s.ctype].selectedIndexErr) { + return fmt.Errorf("failed to add item to combobox/listbox (last error: %v)", r.err) + } return nil } -// TODO figure out how to handle errors func (s *sysData) insertBefore(what string, index int) (err error) { ret := make(chan uiret) defer close(ret) @@ -326,14 +331,17 @@ func (s *sysData) insertBefore(what string, index int) (err error) { }, ret: ret, } - <-ret - // TODO error handling + r := <-ret + if r.ret == uintptr(classTypes[s.ctype].addSpaceErr) { + return fmt.Errorf("out of space adding item to combobox/listbox (last error: %v)", r.err) + } else if r.ret == uintptr(classTypes[s.ctype].selectedIndexErr) { + return fmt.Errorf("failed to add item to combobox/listbox (last error: %v)", r.err) + } return nil } -// TODO handle actual errors // TODO differentiate between nothing selected and custom text entered for a Combobox -func (s *sysData) selectedIndex() (int, error) { +func (s *sysData) selectedIndex() int { ret := make(chan uiret) defer close(ret) uitask <- &uimsg{ @@ -348,19 +356,14 @@ func (s *sysData) selectedIndex() (int, error) { } r := <-ret if r.ret == uintptr(classTypes[s.ctype].selectedIndexErr) { // no selection - return -1, nil + return -1 } - return int(r.ret), nil + return int(r.ret) } -// TODO handle actual errors -func (s *sysData) selectedIndices() ([]int, error) { +func (s *sysData) selectedIndices() []int { if !s.alternate { // single-selection list box; use single-selection method - index, err := s.selectedIndex() - if err != nil { - return nil, fmt.Errorf("error getting indices of single-selection list box: %v", err) - } - return []int{index}, nil + return []int{s.selectedIndex()} } ret := make(chan uiret) @@ -376,7 +379,9 @@ func (s *sysData) selectedIndices() ([]int, error) { ret: ret, } r := <-ret - // TODO handle errors + if r.ret == uintptr(_LB_ERR) { + panic("UI library internal error: LB_ERR from LB_GETSELCOUNT in what we know is a multi-selection listbox") + } indices := make([]int, r.ret) uitask <- &uimsg{ call: _sendMessage, @@ -388,16 +393,15 @@ func (s *sysData) selectedIndices() ([]int, error) { }, ret: ret, } - <-ret - // TODO handle errors - return indices, nil + r = <-ret + if r.ret == uintptr(_LB_ERR) { + panic("UI library internal error: LB_ERR from LB_GETSELITEMS in what we know is a multi-selection listbox") + } + return indices } -func (s *sysData) selectedTexts() ([]string, error) { - indices, err := s.selectedIndices() - if err != nil { - return nil, fmt.Errorf("error getting selected indices for selected texts: %v", err) - } +func (s *sysData) selectedTexts() []string { + indices := s.selectedIndices() ret := make(chan uiret) defer close(ret) strings := make([]string, len(indices)) @@ -413,7 +417,9 @@ func (s *sysData) selectedTexts() ([]string, error) { ret: ret, } r := <-ret - // TODO handle errors + 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, @@ -426,10 +432,12 @@ func (s *sysData) selectedTexts() ([]string, error) { ret: ret, } <-ret - // TODO handle errors + 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") + } strings[i] = syscall.UTF16ToString(str) } - return strings, nil + return strings } func (s *sysData) setWindowSize(width int, height int) error { diff --git a/todo.md b/todo.md index 30855d3..dfcfc81 100644 --- a/todo.md +++ b/todo.md @@ -18,6 +18,7 @@ super ultra important things: - the windows build appears to be unstable: - 64-bit doesn't work, period: it crashes in malloc in wine with heap corruption warnings aplenty during DLL loading; in windows 7 CreateWindowExW complains about an unregistered window class, yet the RegisterClassW appears to have succeeded and examining the stack in WinDbg indicates the correct class name is being sent (see below) - 32-bit: it works now, but if I save the class name converted to UTF-16 beforehand, wine indicates that the class name is replaced with the window title, so something there is wrong... +- handle in-library panics (internal errors) by reporting them to the user important things: - maybe make it so sysData doesn't need specialized info on every control type? diff --git a/winerrors.md b/winerrors.md index da7ac33..542b527 100644 --- a/winerrors.md +++ b/winerrors.md @@ -2,3 +2,6 @@ - BM_GETCHECK (sysData.isChecked()) - WM_GETTEXTLENGTH (LRESULT is unsinged so) (sysData.text()) - WM_GETTEXT (WM_GETTEXTLENGTH docs say its result may be larger than the actual length, so we can't use that) (sysData.text()) +- CB_GETCURSEL/LB_GETCURSEL (sysData.selectedIndex()) +- LB_GETSELCOUNT/LB_GETSELITEMS (LB_ERR is returned if this is a single-selection listbox; are there actual errors?) (sysData.selectedIndices()) +- LB_GETTEXTLEN/LB_GETTEXT (LB_ERR is returned if the given index is invalid, but since we get indices from LB_GETSELITEMS this shouldn't happen; are there actual errors?) (sysData.selectedTexts())