summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dialog_windows.go4
-rw-r--r--sysdata_windows.go195
-rw-r--r--uitask_windows.go49
3 files changed, 81 insertions, 167 deletions
diff --git a/dialog_windows.go b/dialog_windows.go
index 655aa8b..910fb88 100644
--- a/dialog_windows.go
+++ b/dialog_windows.go
@@ -27,10 +27,10 @@ func _msgBox(parent *Window, primarytext string, secondarytext string, uType uin
uType |= _MB_TASKMODAL // make modal to every window in the program (they're all windows of the uitask, which is a single thread)
}
retchan := make(chan int)
+_,_,_,_=parenthwnd,ptext,ptitle,fmt.Printf/* TODO
go func() {
ret := make(chan uiret)
defer close(ret)
-/* TODO
uitask <- &uimsg{
call: _messageBox,
p: []uintptr{
@@ -41,13 +41,13 @@ func _msgBox(parent *Window, primarytext string, secondarytext string, uType uin
},
ret: ret,
}
-*/
r := <-ret
if r.ret == 0 { // failure
panic(fmt.Sprintf("error displaying message box to user: %v\nstyle: 0x%08X\ntitle: %q\ntext:\n%s", r.err, uType, os.Args[0], text))
}
retchan <- int(r.ret)
}()
+*/
return retchan
}
diff --git a/sysdata_windows.go b/sysdata_windows.go
index 504b715..3a6fc63 100644
--- a/sysdata_windows.go
+++ b/sysdata_windows.go
@@ -148,9 +148,7 @@ var (
)
func (s *sysData) make(window *sysData) (err error) {
- ret := make(chan struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
ct := classTypes[s.ctype]
cid := _HMENU(0)
pwin := uintptr(_NULL)
@@ -197,9 +195,7 @@ func (s *sysData) make(window *sysData) (err error) {
uintptr(_WPARAM(controlFont)),
uintptr(_LPARAM(_TRUE)))
}
- ret <- struct{}{}
- }
- <-ret
+ })
return nil
}
@@ -211,9 +207,7 @@ var (
// ShowWindow(hwnd, nCmdShow);
// UpdateWindow(hwnd);
func (s *sysData) firstShow() error {
- ret := make(chan struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
_showWindow.Call(
uintptr(s.hwnd),
uintptr(nCmdShow))
@@ -221,40 +215,28 @@ func (s *sysData) firstShow() error {
if r1 == 0 { // failure
panic(fmt.Errorf("error updating window for the first time: %v", err))
}
- ret <- struct{}{}
- }
- <-ret
+ })
return nil
}
func (s *sysData) show() {
- ret := make(chan struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
_showWindow.Call(
uintptr(s.hwnd),
uintptr(_SW_SHOW))
- ret <- struct{}{}
- }
- <-ret
+ })
}
func (s *sysData) hide() {
- ret := make(chan struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
_showWindow.Call(
uintptr(s.hwnd),
uintptr(_SW_HIDE))
- ret <- struct{}{}
- }
- <-ret
+ })
}
func (s *sysData) setText(text string) {
- ret := make(chan struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
ptext := toUTF16(text)
r1, _, err := _setWindowText.Call(
uintptr(s.hwnd),
@@ -262,9 +244,7 @@ func (s *sysData) setText(text string) {
if r1 == 0 { // failure
panic(fmt.Errorf("error setting window/control text: %v", err))
}
- ret <- struct{}{}
- }
- <-ret
+ })
}
// runs on uitask
@@ -283,23 +263,23 @@ func (s *sysData) setRect(x int, y int, width int, height int, winheight int) er
}
func (s *sysData) isChecked() bool {
- ret := make(chan bool)
- defer close(ret)
- uitask <- func() {
+ var b bool
+
+ uitask(func() {
r1, _, _ := _sendMessage.Call(
uintptr(s.hwnd),
uintptr(_BM_GETCHECK),
uintptr(0),
uintptr(0))
- ret <- r1 == _BST_CHECKED
- }
- return <-ret
+ b = r1 == _BST_CHECKED
+ })
+ return b
}
-func (s *sysData) text() (str string) {
- ret := make(chan string)
- defer close(ret)
- uitask <- func() {
+func (s *sysData) text() string {
+ var str string
+
+ uitask(func() {
var tc []uint16
r1, _, _ := _sendMessage.Call(
@@ -314,15 +294,13 @@ func (s *sysData) text() (str string) {
uintptr(_WM_GETTEXT),
uintptr(_WPARAM(length)),
uintptr(_LPARAM(unsafe.Pointer(&tc[0]))))
- ret <- syscall.UTF16ToString(tc)
- }
- return <-ret
+ str = syscall.UTF16ToString(tc)
+ })
+ return str
}
func (s *sysData) append(what string) {
- ret := make(chan struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
pwhat := toUTF16(what)
r1, _, err := _sendMessage.Call(
uintptr(s.hwnd),
@@ -334,15 +312,11 @@ func (s *sysData) append(what string) {
} 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) {
- ret := make(chan struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
pwhat := toUTF16(what)
r1, _, err := _sendMessage.Call(
uintptr(s.hwnd),
@@ -354,9 +328,7 @@ func (s *sysData) insertBefore(what string, index int) {
} 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
+ })
}
// runs on uitask
@@ -373,12 +345,12 @@ func (s *sysData) doSelectedIndex() int {
}
func (s *sysData) selectedIndex() int {
- ret := make(chan int)
- defer close(ret)
- uitask <- func() {
- ret <- s.doSelectedIndex()
- }
- return <-ret
+ var i int
+
+ uitask(func() {
+ i = s.doSelectedIndex()
+ })
+ return i
}
// runs on uitask
@@ -415,20 +387,20 @@ func (s *sysData) doSelectedIndices() []int {
}
func (s *sysData) selectedIndices() []int {
- ret := make(chan []int)
- defer close(ret)
- uitask <- func() {
- ret <- s.doSelectedIndices()
- }
- return <-ret
+ var i []int
+
+ uitask(func() {
+ i = s.doSelectedIndices()
+ })
+ return i
}
func (s *sysData) selectedTexts() []string {
- ret := make(chan []string)
- defer close(ret)
- uitask <- func() {
+ var strings []string
+
+ uitask(func() {
indices := s.doSelectedIndices()
- strings := make([]string, len(indices))
+ strings = make([]string, len(indices))
for i, v := range indices {
r1, _, err := _sendMessage.Call(
uintptr(s.hwnd),
@@ -449,15 +421,12 @@ func (s *sysData) selectedTexts() []string {
}
strings[i] = syscall.UTF16ToString(str)
}
- ret <- strings
- }
- return <-ret
+ })
+ return strings
}
func (s *sysData) setWindowSize(width int, height int) error {
- ret := make(chan struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
var rect _RECT
r1, _, err := _getClientRect.Call(
@@ -472,16 +441,12 @@ func (s *sysData) setWindowSize(width int, height int) error {
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 struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
r1, _, err := _sendMessage.Call(
uintptr(s.hwnd),
uintptr(classTypes[s.ctype].deleteMsg),
@@ -490,15 +455,11 @@ func (s *sysData) delete(index int) {
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 struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
r1, _, err := _setWindowLongPtr.Call(
uintptr(s.hwnd),
negConst(_GWL_STYLE),
@@ -512,9 +473,7 @@ func (s *sysData) setIndeterminate() {
uintptr(_WPARAM(_TRUE)),
uintptr(0))
s.isMarquee = true
- ret <- struct{}{}
- }
- <-ret
+ })
}
func (s *sysData) setProgress(percent int) {
@@ -522,9 +481,7 @@ func (s *sysData) setProgress(percent int) {
s.setIndeterminate()
return
}
- ret := make(chan struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
if s.isMarquee {
// turn off marquee before switching back
_sendMessage.Call(
@@ -560,15 +517,13 @@ func (s *sysData) setProgress(percent int) {
if percent == 100 {
send(_PBM_SETRANGE32, 0, 100)
}
- ret <- struct{}{}
- }
- <-ret
+ })
}
func (s *sysData) len() int {
- ret := make(chan int)
- defer close(ret)
- uitask <- func() {
+ var i int
+
+ uitask(func() {
r1, _, err := _sendMessage.Call(
uintptr(s.hwnd),
uintptr(classTypes[s.ctype].lenMsg),
@@ -577,43 +532,33 @@ func (s *sysData) len() int {
if r1 == uintptr(classTypes[s.ctype].selectedIndexErr) {
panic(fmt.Errorf("unexpected error return from sysData.len(); GetLastError() says %v", err))
}
- ret <- int(r1)
- }
- return <-ret
+ i = int(r1)
+ })
+ return i
}
func (s *sysData) setAreaSize(width int, height int) {
- ret := make(chan struct{})
- defer close(ret)
- uitask <- func() {
+ 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 <- struct{}{}
- }
- <-ret
+ })
}
func (s *sysData) repaintAll() {
- ret := make(chan struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
_sendMessage.Call(
uintptr(s.hwnd),
uintptr(msgRepaintAll),
uintptr(0),
uintptr(0))
- ret <- struct{}{}
- }
- <-ret
+ })
}
func (s *sysData) center() {
- ret := make(chan struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
var ws _RECT
r1, _, err := _getWindowRect.Call(
@@ -631,15 +576,11 @@ func (s *sysData) center() {
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{}{}
- }
- <-ret
+ })
}
func (s *sysData) setChecked(checked bool) {
- ret := make(chan struct{})
- defer close(ret)
- uitask <- func() {
+ uitask(func() {
c := uintptr(_BST_CHECKED)
if !checked {
c = uintptr(_BST_UNCHECKED)
@@ -649,7 +590,5 @@ func (s *sysData) setChecked(checked bool) {
uintptr(_BM_SETCHECK),
c,
uintptr(0))
- ret <- struct{}{}
- }
- <-ret
+ })
}
diff --git a/uitask_windows.go b/uitask_windows.go
index 1075b5b..772403f 100644
--- a/uitask_windows.go
+++ b/uitask_windows.go
@@ -22,17 +22,15 @@ the only recourse, and the one both Microsoft (http://support.microsoft.com/kb/1
yay.
*/
-var uitask chan interface{}
+var uimsgwin _HWND
-type uimsg struct {
- call *syscall.LazyProc
- p []uintptr
- ret chan uiret
-}
-
-type uiret struct {
- ret uintptr
- err error
+// works from any thread; waits for the function to finish before returning
+func uitask(f func()) {
+ _sendMessage.Call(
+ uintptr(uimsgwin),
+ msgRequested,
+ uintptr(0),
+ uintptr(unsafe.Pointer(&f)))
}
const (
@@ -49,34 +47,20 @@ var (
func ui(main func()) error {
runtime.LockOSThread()
- uitask = make(chan interface{})
err := doWindowsInit()
if err != nil {
return fmt.Errorf("error doing general Windows initialization: %v", err)
}
- hwnd, err := makeMessageHandler()
+ uimsgwin, err = makeMessageHandler()
if err != nil {
return fmt.Errorf("error making invisible window for handling events: %v", err)
}
go func() {
- for m := range uitask {
- r1, _, err := _postMessage.Call(
- uintptr(hwnd),
- msgRequested,
- uintptr(0),
- uintptr(unsafe.Pointer(&m)))
- if r1 == 0 { // failure
- panic("error sending message to message loop to call function: " + err.Error())
- }
- }
- }()
-
- go func() {
main()
r1, _, err := _postMessage.Call(
- uintptr(hwnd),
+ uintptr(uimsgwin),
msgQuit,
uintptr(0),
uintptr(0))
@@ -178,17 +162,8 @@ func makeMessageHandler() (hwnd _HWND, err error) {
func messageHandlerWndProc(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT {
switch uMsg {
case msgRequested:
- mt := (*interface{})(unsafe.Pointer(lParam))
- switch m := (*mt).(type) {
- case *uimsg:
- r1, _, err := m.call.Call(m.p...)
- m.ret <- uiret{
- ret: r1,
- err: err,
- }
- case func():
- m()
- }
+ f := (*func())(unsafe.Pointer(lParam))
+ (*f)()
return 0
case msgQuit:
// does not return a value according to MSDN