Added Post() and implemented it on Windows.
This commit is contained in:
parent
f7dedc8cb0
commit
1238936a16
|
@ -108,6 +108,10 @@ func stdWndProc(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESUL
|
||||||
return storeSysData(hwnd, uMsg, wParam, lParam)
|
return storeSysData(hwnd, uMsg, wParam, lParam)
|
||||||
}
|
}
|
||||||
switch uMsg {
|
switch uMsg {
|
||||||
|
case msgPost:
|
||||||
|
data := (*interface{})(unsafe.Pointer(lParam))
|
||||||
|
s.post(*data)
|
||||||
|
return 0
|
||||||
case _WM_COMMAND:
|
case _WM_COMMAND:
|
||||||
id := _HMENU(wParam.LOWORD())
|
id := _HMENU(wParam.LOWORD())
|
||||||
s.childrenLock.Lock()
|
s.childrenLock.Lock()
|
||||||
|
|
|
@ -9,8 +9,9 @@ type cSysData struct {
|
||||||
spaced bool
|
spaced bool
|
||||||
alternate bool // editable for Combobox, multi-select for listbox, password for lineedit
|
alternate bool // editable for Combobox, multi-select for listbox, password for lineedit
|
||||||
handler AreaHandler // for Areas; TODO rename to areahandler
|
handler AreaHandler // for Areas; TODO rename to areahandler
|
||||||
close func() bool // provided by each Window
|
close func() bool // provided by each Window
|
||||||
event func() // provided by each control
|
post func(interface{}) // provided by each Window
|
||||||
|
event func() // provided by each control
|
||||||
}
|
}
|
||||||
|
|
||||||
// this interface is used to make sure all sysDatas are synced
|
// this interface is used to make sure all sysDatas are synced
|
||||||
|
|
|
@ -249,12 +249,13 @@ func areaTest() {
|
||||||
layout.SetStretchy(0)
|
layout.SetStretchy(0)
|
||||||
w := NewWindow("Area Test", 100, 100)
|
w := NewWindow("Area Test", 100, 100)
|
||||||
w.Closing = die
|
w.Closing = die
|
||||||
|
w.Posted = func(data interface{}) {
|
||||||
|
timedisp.SetText(data.(string))
|
||||||
|
}
|
||||||
w.Open(layout)
|
w.Open(layout)
|
||||||
go func() {
|
go func() {
|
||||||
for t := range timechan {
|
for t := range timechan {
|
||||||
// TODO
|
Post(w, t.String())
|
||||||
_ = t
|
|
||||||
// timedisp.SetText(t.String())
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,14 @@ func Go(start func()) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Post issues a request to the given Window to do something on the main thread.
|
||||||
|
// Note the name of the function: there is no guarantee that the request will be handled immediately.
|
||||||
|
// Because this can be safely called from any goroutine, it is a package-level function, and not a method on Window.
|
||||||
|
// TODO garbage collection
|
||||||
|
func Post(w *Window, data interface{}) {
|
||||||
|
uipost(w, data)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO this needs to be replaced with a function
|
// TODO this needs to be replaced with a function
|
||||||
// Stop should be pulsed when you are ready for Go() to return.
|
// Stop should be pulsed when you are ready for Go() to return.
|
||||||
// Pulsing Stop will cause Go() to return immediately; the programmer is responsible for cleaning up (for instance, hiding open Windows) beforehand.
|
// Pulsing Stop will cause Go() to return immediately; the programmer is responsible for cleaning up (for instance, hiding open Windows) beforehand.
|
||||||
|
|
|
@ -29,6 +29,7 @@ const (
|
||||||
msgQuit = _WM_APP + iota + 1 // + 1 just to be safe
|
msgQuit = _WM_APP + iota + 1 // + 1 just to be safe
|
||||||
msgSetAreaSize
|
msgSetAreaSize
|
||||||
msgRepaintAll
|
msgRepaintAll
|
||||||
|
msgPost
|
||||||
)
|
)
|
||||||
|
|
||||||
func uiinit() error {
|
func uiinit() error {
|
||||||
|
@ -66,6 +67,15 @@ func ui() {
|
||||||
msgloop()
|
msgloop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we'll use SendMessage() here, which will do a thread switch, call the function immediately, and wait for it to return, so we don't have to worry about the garbage collector collecting data
|
||||||
|
func uipost(w *Window, data interface{}) {
|
||||||
|
_sendMessage.Call(
|
||||||
|
uintptr(w.sysData.hwnd), // note: we pass this directly to the window
|
||||||
|
msgPost,
|
||||||
|
0,
|
||||||
|
uintptr(unsafe.Pointer(&data)))
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_dispatchMessage = user32.NewProc("DispatchMessageW")
|
_dispatchMessage = user32.NewProc("DispatchMessageW")
|
||||||
_getActiveWindow = user32.NewProc("GetActiveWindow")
|
_getActiveWindow = user32.NewProc("GetActiveWindow")
|
||||||
|
|
|
@ -15,6 +15,11 @@ type Window struct {
|
||||||
// If Closing is nil, a default which rejects the close will be used.
|
// If Closing is nil, a default which rejects the close will be used.
|
||||||
Closing func() bool
|
Closing func() bool
|
||||||
|
|
||||||
|
// Posted is called when Post() is called with the given Window as an argument.
|
||||||
|
// It receives the data passed to Post() as an argument.
|
||||||
|
// If Posted is nil, a default handler which does nothing will be used.
|
||||||
|
Posted func(data interface{})
|
||||||
|
|
||||||
created bool
|
created bool
|
||||||
sysData *sysData
|
sysData *sysData
|
||||||
initTitle string
|
initTitle string
|
||||||
|
@ -87,6 +92,10 @@ func (w *Window) Create(control Control) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
w.sysData.post = w.Posted
|
||||||
|
if w.sysData.post == nil {
|
||||||
|
w.sysData.post = func(data interface{}) {}
|
||||||
|
}
|
||||||
err := w.sysData.make(nil)
|
err := w.sysData.make(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("error opening window: %v", err))
|
panic(fmt.Errorf("error opening window: %v", err))
|
||||||
|
|
Loading…
Reference in New Issue