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)
|
||||
}
|
||||
switch uMsg {
|
||||
case msgPost:
|
||||
data := (*interface{})(unsafe.Pointer(lParam))
|
||||
s.post(*data)
|
||||
return 0
|
||||
case _WM_COMMAND:
|
||||
id := _HMENU(wParam.LOWORD())
|
||||
s.childrenLock.Lock()
|
||||
|
|
|
@ -9,8 +9,9 @@ type cSysData struct {
|
|||
spaced bool
|
||||
alternate bool // editable for Combobox, multi-select for listbox, password for lineedit
|
||||
handler AreaHandler // for Areas; TODO rename to areahandler
|
||||
close func() bool // provided by each Window
|
||||
event func() // provided by each control
|
||||
close func() bool // provided by each Window
|
||||
post func(interface{}) // provided by each Window
|
||||
event func() // provided by each control
|
||||
}
|
||||
|
||||
// this interface is used to make sure all sysDatas are synced
|
||||
|
|
|
@ -249,12 +249,13 @@ func areaTest() {
|
|||
layout.SetStretchy(0)
|
||||
w := NewWindow("Area Test", 100, 100)
|
||||
w.Closing = die
|
||||
w.Posted = func(data interface{}) {
|
||||
timedisp.SetText(data.(string))
|
||||
}
|
||||
w.Open(layout)
|
||||
go func() {
|
||||
for t := range timechan {
|
||||
// TODO
|
||||
_ = t
|
||||
// timedisp.SetText(t.String())
|
||||
Post(w, t.String())
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
|
|
@ -26,6 +26,14 @@ func Go(start func()) error {
|
|||
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
|
||||
// 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.
|
||||
|
|
|
@ -29,6 +29,7 @@ const (
|
|||
msgQuit = _WM_APP + iota + 1 // + 1 just to be safe
|
||||
msgSetAreaSize
|
||||
msgRepaintAll
|
||||
msgPost
|
||||
)
|
||||
|
||||
func uiinit() error {
|
||||
|
@ -66,6 +67,15 @@ func ui() {
|
|||
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 (
|
||||
_dispatchMessage = user32.NewProc("DispatchMessageW")
|
||||
_getActiveWindow = user32.NewProc("GetActiveWindow")
|
||||
|
|
|
@ -15,6 +15,11 @@ type Window struct {
|
|||
// If Closing is nil, a default which rejects the close will be used.
|
||||
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
|
||||
sysData *sysData
|
||||
initTitle string
|
||||
|
@ -87,6 +92,10 @@ func (w *Window) Create(control Control) {
|
|||
return false
|
||||
}
|
||||
}
|
||||
w.sysData.post = w.Posted
|
||||
if w.sysData.post == nil {
|
||||
w.sysData.post = func(data interface{}) {}
|
||||
}
|
||||
err := w.sysData.make(nil)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("error opening window: %v", err))
|
||||
|
|
Loading…
Reference in New Issue