summaryrefslogtreecommitdiff
path: root/sysdata_windows.go
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-06-12 11:46:51 -0400
committerPietro Gagliardi <[email protected]>2014-06-12 11:46:51 -0400
commitaf2e8c4b1315ece9737cb206b2f158f2759e53e9 (patch)
tree037f186cf613da783061b3aaf07d5883787c9cc0 /sysdata_windows.go
parentc159bb20182338bbd17a4f36384bfdae2816c78e (diff)
Made sysdata_windows.go send func()s to uitask and not uimsgs. This is also more correct, as multi-step processes happen in one homogenous blob instead of in steps spread across two goroutines.
Diffstat (limited to 'sysdata_windows.go')
-rw-r--r--sysdata_windows.go644
1 files changed, 274 insertions, 370 deletions
diff --git a/sysdata_windows.go b/sysdata_windows.go
index 99dbad8..317840a 100644
--- a/sysdata_windows.go
+++ b/sysdata_windows.go
@@ -144,26 +144,25 @@ var (
)
func (s *sysData) make(window *sysData) (err error) {
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- ct := classTypes[s.ctype]
- cid := _HMENU(0)
- pwin := uintptr(_NULL)
- if window != nil { // this is a child control
- cid = window.addChild(s)
- pwin = uintptr(window.hwnd)
- }
- style := uintptr(ct.style)
- if s.alternate {
- style = uintptr(ct.altStyle)
- }
- lpParam := uintptr(_NULL)
- if ct.storeSysData {
- lpParam = uintptr(unsafe.Pointer(s))
- }
- uitask <- &uimsg{
- call: _createWindowEx,
- p: []uintptr{
+ uitask <- func() {
+ ct := classTypes[s.ctype]
+ cid := _HMENU(0)
+ pwin := uintptr(_NULL)
+ if window != nil { // this is a child control
+ cid = window.addChild(s)
+ pwin = uintptr(window.hwnd)
+ }
+ style := uintptr(ct.style)
+ if s.alternate {
+ style = uintptr(ct.altStyle)
+ }
+ lpParam := uintptr(_NULL)
+ if ct.storeSysData {
+ lpParam = uintptr(unsafe.Pointer(s))
+ }
+ r1, _, err := _createWindowEx.Call(
uintptr(ct.xstyle),
utf16ToArg(ct.name),
blankString, // we set the window text later
@@ -175,35 +174,28 @@ func (s *sysData) make(window *sysData) (err error) {
pwin,
uintptr(cid),
uintptr(hInstance),
- lpParam,
- },
- ret: ret,
- }
- r := <-ret
- if r.ret == 0 { // failure
- if window != nil {
- window.delChild(cid)
+ lpParam)
+ if r1 == 0 { // failure
+ if window != nil {
+ window.delChild(cid)
+ }
+ panic(fmt.Errorf("error actually creating window/control: %v", err))
}
- return fmt.Errorf("error actually creating window/control: %v", r.err)
- }
- if !ct.storeSysData { // regular control; store s.hwnd ourselves
- s.hwnd = _HWND(r.ret)
- } else if s.hwnd != _HWND(r.ret) { // we store sysData in storeSysData(); sanity check
- panic(fmt.Errorf("hwnd mismatch creating window/control: storeSysData() stored 0x%X but CreateWindowEx() returned 0x%X", s.hwnd, ret))
- }
- if !ct.doNotLoadFont {
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ if !ct.storeSysData { // regular control; store s.hwnd ourselves
+ s.hwnd = _HWND(r1)
+ } else if s.hwnd != _HWND(r1) { // we store sysData in storeSysData(); sanity check
+ panic(fmt.Errorf("hwnd mismatch creating window/control: storeSysData() stored 0x%X but CreateWindowEx() returned 0x%X", s.hwnd, r1))
+ }
+ if !ct.doNotLoadFont {
+ _sendMessage.Call(
uintptr(s.hwnd),
uintptr(_WM_SETFONT),
uintptr(_WPARAM(controlFont)),
- uintptr(_LPARAM(_TRUE)),
- },
- ret: ret,
+ uintptr(_LPARAM(_TRUE)))
}
- <-ret
+ ret <- struct{}{}
}
+ <-ret
return nil
}
@@ -215,75 +207,63 @@ var (
// ShowWindow(hwnd, nCmdShow);
// UpdateWindow(hwnd);
func (s *sysData) firstShow() error {
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- uitask <- &uimsg{
- call: _showWindow,
- p: []uintptr{
+ uitask <- func() {
+ _showWindow.Call(
uintptr(s.hwnd),
- uintptr(nCmdShow),
- },
- ret: ret,
+ uintptr(nCmdShow))
+ r1, _, err := _updateWindow.Call(uintptr(s.hwnd))
+ if r1 == 0 { // failure
+ panic(fmt.Errorf("error updating window for the first time: %v", err))
+ }
+ ret <- struct{}{}
}
<-ret
- uitask <- &uimsg{
- call: _updateWindow,
- p: []uintptr{uintptr(s.hwnd)},
- ret: ret,
- }
- r := <-ret
- if r.ret == 0 { // failure
- return fmt.Errorf("error updating window for the first time: %v", r.err)
- }
return nil
}
func (s *sysData) show() {
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- uitask <- &uimsg{
- call: _showWindow,
- p: []uintptr{
+ uitask <- func() {
+ _showWindow.Call(
uintptr(s.hwnd),
- uintptr(_SW_SHOW),
- },
- ret: ret,
+ uintptr(_SW_SHOW))
+ ret <- struct{}{}
}
<-ret
}
func (s *sysData) hide() {
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- uitask <- &uimsg{
- call: _showWindow,
- p: []uintptr{
+ uitask <- func() {
+ _showWindow.Call(
uintptr(s.hwnd),
- uintptr(_SW_HIDE),
- },
- ret: ret,
+ uintptr(_SW_HIDE))
+ ret <- struct{}{}
}
<-ret
}
func (s *sysData) setText(text string) {
- ptext := toUTF16(text)
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- uitask <- &uimsg{
- call: _setWindowText,
- p: []uintptr{
+ uitask <- func() {
+ ptext := toUTF16(text)
+ r1, _, err := _setWindowText.Call(
uintptr(s.hwnd),
- utf16ToArg(ptext),
- },
- ret: ret,
- }
- r := <-ret
- if r.ret == 0 { // failure
- panic(fmt.Errorf("error setting window/control text: %v", r.err))
+ utf16ToArg(ptext))
+ if r1 == 0 { // failure
+ panic(fmt.Errorf("error setting window/control text: %v", err))
+ }
+ ret <- struct{}{}
}
+ <-ret
}
+// runs on uitask
func (s *sysData) setRect(x int, y int, width int, height int, winheight int) error {
r1, _, err := _moveWindow.Call(
uintptr(s.hwnd),
@@ -299,277 +279,238 @@ func (s *sysData) setRect(x int, y int, width int, height int, winheight int) er
}
func (s *sysData) isChecked() bool {
- ret := make(chan uiret)
+ ret := make(chan bool)
defer close(ret)
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ uitask <- func() {
+ r1, _, _ := _sendMessage.Call(
uintptr(s.hwnd),
uintptr(_BM_GETCHECK),
uintptr(0),
- uintptr(0),
- },
- ret: ret,
+ uintptr(0))
+ ret <- r1 == _BST_CHECKED
}
- r := <-ret
- return r.ret == _BST_CHECKED
+ return <-ret
}
func (s *sysData) text() (str string) {
- var tc []uint16
-
- ret := make(chan uiret)
+ ret := make(chan string)
defer close(ret)
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ uitask <- func() {
+ var tc []uint16
+
+ r1, _, _ := _sendMessage.Call(
uintptr(s.hwnd),
uintptr(_WM_GETTEXTLENGTH),
uintptr(0),
- uintptr(0),
- },
- ret: ret,
- }
- r := <-ret
- length := r.ret + 1 // terminating null
- tc = make([]uint16, length)
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ uintptr(0))
+ length := r1 + 1 // terminating null
+ tc = make([]uint16, length)
+ _sendMessage.Call(
uintptr(s.hwnd),
uintptr(_WM_GETTEXT),
uintptr(_WPARAM(length)),
- uintptr(_LPARAM(unsafe.Pointer(&tc[0]))),
- },
- ret: ret,
+ uintptr(_LPARAM(unsafe.Pointer(&tc[0]))))
+ ret <- syscall.UTF16ToString(tc)
}
- <-ret
- return syscall.UTF16ToString(tc)
+ return <-ret
}
func (s *sysData) append(what string) {
- pwhat := toUTF16(what)
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ uitask <- func() {
+ pwhat := toUTF16(what)
+ r1, _, err := _sendMessage.Call(
uintptr(s.hwnd),
uintptr(classTypes[s.ctype].appendMsg),
uintptr(_WPARAM(0)),
- utf16ToLPARAM(pwhat),
- },
- ret: ret,
- }
- r := <-ret
- if r.ret == uintptr(classTypes[s.ctype].addSpaceErr) {
- panic(fmt.Errorf("out of space adding item to combobox/listbox (last error: %v)", r.err))
- } else if r.ret == uintptr(classTypes[s.ctype].selectedIndexErr) {
- panic(fmt.Errorf("failed to add item to combobox/listbox (last error: %v)", r.err))
+ utf16ToLPARAM(pwhat))
+ if r1 == uintptr(classTypes[s.ctype].addSpaceErr) {
+ panic(fmt.Errorf("out of space adding item to combobox/listbox (last error: %v)", err))
+ } else if r1 == uintptr(classTypes[s.ctype].selectedIndexErr) {
+ panic(fmt.Errorf("failed to add item to combobox/listbox (last error: %v)", err))
+ }
+ ret <- struct{}{}
}
+ <-ret
}
func (s *sysData) insertBefore(what string, index int) {
- pwhat := toUTF16(what)
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ uitask <- func() {
+ pwhat := toUTF16(what)
+ r1, _, err := _sendMessage.Call(
uintptr(s.hwnd),
uintptr(classTypes[s.ctype].insertBeforeMsg),
uintptr(_WPARAM(index)),
- utf16ToLPARAM(pwhat),
- },
- ret: ret,
+ utf16ToLPARAM(pwhat))
+ if r1 == uintptr(classTypes[s.ctype].addSpaceErr) {
+ panic(fmt.Errorf("out of space adding item to combobox/listbox (last error: %v)", err))
+ } else if r1 == uintptr(classTypes[s.ctype].selectedIndexErr) {
+ panic(fmt.Errorf("failed to add item to combobox/listbox (last error: %v)", err))
+ }
+ ret <- struct{}{}
}
- r := <-ret
- if r.ret == uintptr(classTypes[s.ctype].addSpaceErr) {
- panic(fmt.Errorf("out of space adding item to combobox/listbox (last error: %v)", r.err))
- } else if r.ret == uintptr(classTypes[s.ctype].selectedIndexErr) {
- panic(fmt.Errorf("failed to add item to combobox/listbox (last error: %v)", r.err))
+ <-ret
+}
+
+// runs on uitask
+func (s *sysData) doSelectedIndex() int {
+ r1, _, _ := _sendMessage.Call(
+ uintptr(s.hwnd),
+ uintptr(classTypes[s.ctype].selectedIndexMsg),
+ uintptr(_WPARAM(0)),
+ uintptr(_LPARAM(0)))
+ if r1 == uintptr(classTypes[s.ctype].selectedIndexErr) { // no selection or manually entered text (apparently, for the latter)
+ return -1
}
+ return int(r1)
}
func (s *sysData) selectedIndex() int {
- ret := make(chan uiret)
+ ret := make(chan int)
defer close(ret)
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
- uintptr(s.hwnd),
- uintptr(classTypes[s.ctype].selectedIndexMsg),
- uintptr(_WPARAM(0)),
- uintptr(_LPARAM(0)),
- },
- ret: ret,
- }
- r := <-ret
- if r.ret == uintptr(classTypes[s.ctype].selectedIndexErr) { // no selection or manually entered text (apparently, for the latter)
- return -1
+ uitask <- func() {
+ ret <- s.doSelectedIndex()
}
- return int(r.ret)
+ return <-ret
}
-func (s *sysData) selectedIndices() []int {
+// runs on uitask
+func (s *sysData) doSelectedIndices() []int {
if !s.alternate { // single-selection list box; use single-selection method
- index := s.selectedIndex()
+ index := s.doSelectedIndex()
if index == -1 {
return nil
}
return []int{index}
}
- ret := make(chan uiret)
- defer close(ret)
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
- uintptr(s.hwnd),
- uintptr(_LB_GETSELCOUNT),
- uintptr(0),
- uintptr(0),
- },
- ret: ret,
- }
- r := <-ret
- if r.ret == negConst(_LB_ERR) {
- panic("UI library internal error: LB_ERR from LB_GETSELCOUNT in what we know is a multi-selection listbox")
+ r1, _, err := _sendMessage.Call(
+ uintptr(s.hwnd),
+ uintptr(_LB_GETSELCOUNT),
+ uintptr(0),
+ uintptr(0))
+ if r1 == negConst(_LB_ERR) {
+ panic(fmt.Errorf("error: LB_ERR from LB_GETSELCOUNT in what we know is a multi-selection listbox: %v", err))
}
- if r.ret == 0 { // nothing selected
+ if r1 == 0 { // nothing selected
return nil
}
- indices := make([]int, r.ret)
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
- uintptr(s.hwnd),
- uintptr(_LB_GETSELITEMS),
- uintptr(_WPARAM(r.ret)),
- uintptr(_LPARAM(unsafe.Pointer(&indices[0]))),
- },
- ret: ret,
- }
- r = <-ret
- if r.ret == negConst(_LB_ERR) {
- panic("UI library internal error: LB_ERR from LB_GETSELITEMS in what we know is a multi-selection listbox")
+ indices := make([]int, r1)
+ r1, _, err = _sendMessage.Call(
+ uintptr(s.hwnd),
+ uintptr(_LB_GETSELITEMS),
+ uintptr(_WPARAM(r1)),
+ uintptr(_LPARAM(unsafe.Pointer(&indices[0]))))
+ if r1 == negConst(_LB_ERR) {
+ panic(fmt.Errorf("error: LB_ERR from LB_GETSELITEMS in what we know is a multi-selection listbox: %v", err))
}
return indices
}
+func (s *sysData) selectedIndices() []int {
+ ret := make(chan []int)
+ defer close(ret)
+ uitask <- func() {
+ ret <- s.doSelectedIndices()
+ }
+ return <-ret
+}
+
func (s *sysData) selectedTexts() []string {
- indices := s.selectedIndices()
- ret := make(chan uiret)
+ ret := make(chan []string)
defer close(ret)
- strings := make([]string, len(indices))
- for i, v := range indices {
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ uitask <- func() {
+ indices := s.doSelectedIndices()
+ strings := make([]string, len(indices))
+ for i, v := range indices {
+ r1, _, err := _sendMessage.Call(
uintptr(s.hwnd),
uintptr(_LB_GETTEXTLEN),
uintptr(_WPARAM(v)),
- uintptr(0),
- },
- ret: ret,
- }
- r := <-ret
- if r.ret == negConst(_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(0))
+ if r1 == negConst(_LB_ERR) {
+ panic(fmt.Errorf("error: LB_ERR from LB_GETTEXTLEN in what we know is a valid listbox index (came from LB_GETSELITEMS): %v", err))
+ }
+ str := make([]uint16, r1)
+ r1, _, err = _sendMessage.Call(
uintptr(s.hwnd),
uintptr(_LB_GETTEXT),
uintptr(_WPARAM(v)),
- uintptr(_LPARAM(unsafe.Pointer(&str[0]))),
- },
- ret: ret,
+ uintptr(_LPARAM(unsafe.Pointer(&str[0]))))
+ if r1 == negConst(_LB_ERR) {
+ panic(fmt.Errorf("error: LB_ERR from LB_GETTEXT in what we know is a valid listbox index (came from LB_GETSELITEMS): %v", err))
+ }
+ strings[i] = syscall.UTF16ToString(str)
}
- r = <-ret
- if r.ret == negConst(_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)
+ ret <- strings
}
- return strings
+ return <-ret
}
func (s *sysData) setWindowSize(width int, height int) error {
- var rect _RECT
-
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- uitask <- &uimsg{
- call: _getClientRect,
- p: []uintptr{
+ uitask <- func() {
+ var rect _RECT
+
+ r1, _, err := _getClientRect.Call(
uintptr(s.hwnd),
- uintptr(unsafe.Pointer(&rect)),
- },
- ret: ret,
- }
- r := <-ret
- if r.ret == 0 {
- return fmt.Errorf("error getting upper-left of window for resize: %v", r.err)
- }
- // 0 because (0,0) is top-left so no winheight
- // TODO this needs to be run on uitask!
- err := s.setRect(int(rect.left), int(rect.top), width, height, 0)
- if err != nil {
- return fmt.Errorf("error actually resizing window: %v", err)
+ uintptr(unsafe.Pointer(&rect)))
+ if r1 == 0 {
+ panic(fmt.Errorf("error getting upper-left of window for resize: %v", err))
+ }
+ // TODO AdjustWindowRect() on the result
+ // 0 because (0,0) is top-left so no winheight
+ err = s.setRect(int(rect.left), int(rect.top), width, height, 0)
+ if err != nil {
+ panic(fmt.Errorf("error actually resizing window: %v", err))
+ }
+ ret <- struct{}{}
}
+ <-ret
return nil
}
func (s *sysData) delete(index int) {
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ uitask <- func() {
+ r1, _, err := _sendMessage.Call(
uintptr(s.hwnd),
uintptr(classTypes[s.ctype].deleteMsg),
uintptr(_WPARAM(index)),
- uintptr(0),
- },
- ret: ret,
- }
- r := <-ret
- if r.ret == uintptr(classTypes[s.ctype].selectedIndexErr) {
- panic(fmt.Errorf("failed to delete item from combobox/listbox (last error: %v)", r.err))
+ uintptr(0))
+ if r1 == uintptr(classTypes[s.ctype].selectedIndexErr) {
+ panic(fmt.Errorf("failed to delete item from combobox/listbox (last error: %v)", err))
+ }
+ ret <- struct{}{}
}
+ <-ret
}
func (s *sysData) setIndeterminate() {
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- uitask <- &uimsg{
- call: _setWindowLongPtr,
- p: []uintptr{
+ uitask <- func() {
+ r1, _, err := _setWindowLongPtr.Call(
uintptr(s.hwnd),
negConst(_GWL_STYLE),
- uintptr(classTypes[s.ctype].style | _PBS_MARQUEE),
- },
- ret: ret,
- }
- r := <-ret
- if r.ret == 0 {
- panic(fmt.Errorf("error setting progress bar style to enter indeterminate mode: %v", r.err))
- }
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ uintptr(classTypes[s.ctype].style | _PBS_MARQUEE))
+ if r1 == 0 {
+ panic(fmt.Errorf("error setting progress bar style to enter indeterminate mode: %v", err))
+ }
+ _sendMessage.Call(
uintptr(s.hwnd),
uintptr(_PBM_SETMARQUEE),
uintptr(_WPARAM(_TRUE)),
- uintptr(0),
- },
- ret: ret,
+ uintptr(0))
+ s.isMarquee = true
+ ret <- struct{}{}
}
<-ret
- s.isMarquee = true
}
func (s *sysData) setProgress(percent int) {
@@ -577,153 +518,116 @@ func (s *sysData) setProgress(percent int) {
s.setIndeterminate()
return
}
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- if s.isMarquee {
- // turn off marquee before switching back
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ uitask <- func() {
+ if s.isMarquee {
+ // turn off marquee before switching back
+ _sendMessage.Call(
uintptr(s.hwnd),
uintptr(_PBM_SETMARQUEE),
uintptr(_WPARAM(_FALSE)),
- uintptr(0),
- },
- ret: ret,
- }
- <-ret
- uitask <- &uimsg{
- call: _setWindowLongPtr,
- p: []uintptr{
+ uintptr(0))
+ r1, _, err := _setWindowLongPtr.Call(
uintptr(s.hwnd),
negConst(_GWL_STYLE),
- uintptr(classTypes[s.ctype].style),
- },
- ret: ret,
- }
- r := <-ret
- if r.ret == 0 {
- panic(fmt.Errorf("error setting progress bar style to leave indeterminate mode (percent %d): %v", percent, r.err))
+ uintptr(classTypes[s.ctype].style))
+ if r1 == 0 {
+ panic(fmt.Errorf("error setting progress bar style to leave indeterminate mode (percent %d): %v", percent, err))
+ }
+ s.isMarquee = false
}
- s.isMarquee = false
- }
- send := func(msg uintptr, n int, l _LPARAM) {
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ send := func(msg uintptr, n int, l _LPARAM) {
+ _sendMessage.Call(
uintptr(s.hwnd),
msg,
uintptr(_WPARAM(n)),
- uintptr(l),
- },
- ret: ret,
+ uintptr(l))
}
- <-ret
- }
- // Windows 7 has a non-disableable slowly-animating progress bar increment
- // there isn't one for decrement, so we'll work around by going one higher and then lower again
- // for the case where percent == 100, we need to increase the range temporarily
- // this kind of thing is why I want to move away from uimsg and toward having uitask take func()s like on the other platforms
- // sources: http://social.msdn.microsoft.com/Forums/en-US/61350dc7-6584-4c4e-91b0-69d642c03dae/progressbar-disable-smooth-animation http://stackoverflow.com/questions/2217688/windows-7-aero-theme-progress-bar-bug http://discuss.joelonsoftware.com/default.asp?dotnet.12.600456.2 http://stackoverflow.com/questions/22469876/progressbar-lag-when-setting-position-with-pbm-setpos http://stackoverflow.com/questions/6128287/tprogressbar-never-fills-up-all-the-way-seems-to-be-updating-too-fast
- if percent == 100 {
- send(_PBM_SETRANGE32, 0, 101)
- }
- send(_PBM_SETPOS, percent+1, 0)
- send(_PBM_SETPOS, percent, 0)
- if percent == 100 {
- send(_PBM_SETRANGE32, 0, 100)
+ // Windows 7 has a non-disableable slowly-animating progress bar increment
+ // there isn't one for decrement, so we'll work around by going one higher and then lower again
+ // for the case where percent == 100, we need to increase the range temporarily
+ // sources: http://social.msdn.microsoft.com/Forums/en-US/61350dc7-6584-4c4e-91b0-69d642c03dae/progressbar-disable-smooth-animation http://stackoverflow.com/questions/2217688/windows-7-aero-theme-progress-bar-bug http://discuss.joelonsoftware.com/default.asp?dotnet.12.600456.2 http://stackoverflow.com/questions/22469876/progressbar-lag-when-setting-position-with-pbm-setpos http://stackoverflow.com/questions/6128287/tprogressbar-never-fills-up-all-the-way-seems-to-be-updating-too-fast
+ if percent == 100 {
+ send(_PBM_SETRANGE32, 0, 101)
+ }
+ send(_PBM_SETPOS, percent+1, 0)
+ send(_PBM_SETPOS, percent, 0)
+ if percent == 100 {
+ send(_PBM_SETRANGE32, 0, 100)
+ }
+ ret <- struct{}{}
}
+ <-ret
}
func (s *sysData) len() int {
- ret := make(chan uiret)
+ ret := make(chan int)
defer close(ret)
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ uitask <- func() {
+ r1, _, err := _sendMessage.Call(
uintptr(s.hwnd),
uintptr(classTypes[s.ctype].lenMsg),
uintptr(_WPARAM(0)),
- uintptr(_LPARAM(0)),
- },
- ret: ret,
- }
- r := <-ret
- if r.ret == uintptr(classTypes[s.ctype].selectedIndexErr) {
- panic(fmt.Errorf("unexpected error return from sysData.len(); GetLastError() says %v", r.err))
+ uintptr(_LPARAM(0)))
+ if r1 == uintptr(classTypes[s.ctype].selectedIndexErr) {
+ panic(fmt.Errorf("unexpected error return from sysData.len(); GetLastError() says %v", err))
+ }
+ ret <- int(r1)
}
- return int(r.ret)
+ return <-ret
}
func (s *sysData) setAreaSize(width int, height int) {
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ uitask <- func() {
+ _sendMessage.Call(
uintptr(s.hwnd),
uintptr(msgSetAreaSize),
uintptr(width), // WPARAM is UINT_PTR on Windows XP and newer at least, so we're good with this
- uintptr(height),
- },
- ret: ret,
+ uintptr(height))
+ ret <- struct{}{}
}
<-ret
}
func (s *sysData) repaintAll() {
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- uitask <- &uimsg{
- call: _sendMessage,
- p: []uintptr{
+ uitask <- func() {
+ _sendMessage.Call(
uintptr(s.hwnd),
uintptr(msgRepaintAll),
uintptr(0),
- uintptr(0),
- },
- ret: ret,
+ uintptr(0))
+ ret <- struct{}{}
}
<-ret
}
func (s *sysData) center() {
- var ws _RECT
-
- ret := make(chan uiret)
+ ret := make(chan struct{})
defer close(ret)
- uitask <- &uimsg{
- call: _getWindowRect,
- p: []uintptr{
+ uitask <- func() {
+ var ws _RECT
+
+ r1, _, err := _getWindowRect.Call(
uintptr(s.hwnd),
- uintptr(unsafe.Pointer(&ws)),
- },
- ret: ret,
- }
- r := <-ret
- if r.ret == 0 {
- panic(fmt.Errorf("error getting window rect for sysData.center(): %v", r.err))
- }
- // TODO should this be using the monitor functions instead? http://blogs.msdn.com/b/oldnewthing/archive/2005/05/05/414910.aspx
- // error returns from GetSystemMetrics() is meaningless because the return value, 0, is still valid
- uitask <- &uimsg{
- call: _getSystemMetrics,
- p: []uintptr{uintptr(_SM_CXFULLSCREEN)},
- ret: ret,
- }
- r = <-ret
- dw := r.ret
- uitask <- &uimsg{
- call: _getSystemMetrics,
- p: []uintptr{uintptr(_SM_CYFULLSCREEN)},
- ret: ret,
+ uintptr(unsafe.Pointer(&ws)))
+ if r1 == 0 {
+ panic(fmt.Errorf("error getting window rect for sysData.center(): %v", err))
+ }
+ // TODO should this be using the monitor functions instead? http://blogs.msdn.com/b/oldnewthing/archive/2005/05/05/414910.aspx
+ // error returns from GetSystemMetrics() is meaningless because the return value, 0, is still valid
+ dw, _, _ := _getSystemMetrics.Call(uintptr(_SM_CXFULLSCREEN))
+ dh, _, _ := _getSystemMetrics.Call(uintptr(_SM_CYFULLSCREEN))
+ ww := ws.right - ws.left
+ wh := ws.bottom - ws.top
+ wx := (int32(dw) / 2) - (ww / 2)
+ wy := (int32(dh) / 2) - (wh / 2)
+ s.setRect(int(wx), int(wy), int(ww), int(wh), 0)
+ ret <- struct{}{}
}
- r = <-ret
- dh := r.ret
- ww := ws.right - ws.left
- wh := ws.bottom - ws.top
- wx := (int32(dw) / 2) - (ww / 2)
- wy := (int32(dh) / 2) - (wh / 2)
- // TODO this needs to be run on uitask!
- s.setRect(int(wx), int(wy), int(ww), int(wh), 0)
+ <-ret
}