diff --git a/form.go b/form.go index 6e61d755..3b44dbae 100644 --- a/form.go +++ b/form.go @@ -2,11 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build windows // +build windows package walk import ( + "context" "fmt" "math" "sync" @@ -341,6 +343,15 @@ func (fb *FormBase) SetRightToLeftLayout(rtl bool) error { } func (fb *FormBase) Run() int { + return fb.run(context.Background()) +} + +// RunWithContext does the same as Run, but with the context cancellation respect. +func (fb *FormBase) RunWithContext(ctx context.Context) int { + return fb.run(ctx) +} + +func (fb *FormBase) run(ctx context.Context) int { if fb.owner != nil { win.EnableWindow(fb.owner.Handle(), false) @@ -372,7 +383,7 @@ func (fb *FormBase) Run() int { fb.SetSuspended(false) - return fb.mainLoop() + return fb.mainLoop(ctx) } func (fb *FormBase) handleKeyDown(msg *win.MSG) bool { diff --git a/mainloop_cgo.go b/mainloop_cgo.go index 5a21feef..c5ac90e5 100644 --- a/mainloop_cgo.go +++ b/mainloop_cgo.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build windows && walk_use_cgo // +build windows,walk_use_cgo package walk @@ -51,6 +52,6 @@ func shimRunSynchronized(fb uintptr) { (*FormBase)(unsafe.Pointer(fb)).group.RunSynchronized() } -func (fb *FormBase) mainLoop() int { +func (fb *FormBase) mainLoop(_ context.Context) int { return int(C.mainloop(C.uintptr_t(uintptr(unsafe.Pointer(&fb.hWnd))), C.uintptr_t(uintptr(unsafe.Pointer(fb))))) } diff --git a/mainloop_default.go b/mainloop_default.go index 389914fa..68cb87a2 100644 --- a/mainloop_default.go +++ b/mainloop_default.go @@ -2,21 +2,27 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build windows && !walk_use_cgo // +build windows,!walk_use_cgo package walk import ( + "context" "unsafe" "github.com/lxn/win" ) -func (fb *FormBase) mainLoop() int { +func (fb *FormBase) mainLoop(ctx context.Context) int { msg := (*win.MSG)(unsafe.Pointer(win.GlobalAlloc(0, unsafe.Sizeof(win.MSG{})))) defer win.GlobalFree(win.HGLOBAL(unsafe.Pointer(msg))) for fb.hWnd != 0 { + if err := ctx.Err(); err != nil { + return 0 + } + switch win.GetMessage(msg, 0, 0, 0) { case 0: return int(msg.WParam)