"Cannot add event handling after the window is created" error when trying to add button to visible window
Hoto-Cocoa opened this issue · 2 comments
I was trying to add button when some situation. However, It makes panic always.
Here is reproducible code:
package main
import (
"fmt"
"runtime"
"github.com/rodrigocfd/windigo/ui"
"github.com/rodrigocfd/windigo/win"
"internal/modules/utils"
)
func main() {
defer utils.PanicHandler()
runtime.LockOSThread()
window := ui.NewWindowMain(
ui.WindowMainOpts().
Title("App"),
)
button := ui.NewButton(
window,
ui.ButtonOpts().
Position(win.POINT{X: 100, Y: 100}),
)
button.On().BnClicked(func() {
fmt.Println("Clicked")
window.Hwnd().EnumChildWindows(func(childHwnd win.HWND) bool {
childHwnd.DestroyWindow()
button := ui.NewButton(
window,
ui.ButtonOpts().
Position(win.POINT{X: 100, Y: 100}),
)
button.On().BnClicked(func() {
fmt.Println("Clicked")
})
return true
})
})
window.RunAsMain()
}
When I click the button, It panic. I tried to omit WS_VISIBLE
but not works. Also I tried dummy window to create button, and changing parent using SetParent, but not works.
I don't know where to I should ask this question. Please let me know If this issue not attended...
Thanks.
Dynamic events are not allowed, this is intentional.
In the early days of Windigo, some programs I wrote used to crash in random situations, with no apparent cause. At first I thought it was something related to the goroutine address containment – something going wrong with address translation from one heap to another with different address spaces.
It took me months to realize what was really happening: when adding an event during an event, you are essentially modifying the same array you're reading from, which is a classic cause of memory access concurrency. Since then, dynamic events are strictly forbidden, they can be added only before the window is launched by RunAsMain()
.
Thinking the problem from another perspective: the event handling boils down to a big switch statement, which is a static thing. You can't add new switch clauses during runtime.
Possible solution: your code is destroying and creating controls at runtime; the way to respond to those button clicks is giving them IDs and then handling the WM_COMMAND
message, where you can see the ID and act accordingly.
Thanks for the explain! I will try that.