_RunModalLoop doesn't break
Hoto-Cocoa opened this issue · 4 comments
If I show modal window, modal loop doesn't break even window closed/destroyed.
Here is reproducible code:
package main
import (
"github.com/rodrigocfd/windigo/ui"
"github.com/rodrigocfd/windigo/win"
"github.com/rodrigocfd/windigo/win/co"
)
func main() {
window := ui.NewWindowMain(
ui.WindowMainOpts().
Title("Test").
ClientArea(win.SIZE{Cx: 800, Cy: 600}),
)
button := ui.NewButton(window, ui.ButtonOpts().
Position(win.POINT{X: 10, Y: 10}).
Size(win.SIZE{Cx: 100, Cy: 30}).
Text("Open Modal"))
button.On().BnClicked(func() {
modal := ui.NewWindowModal(ui.WindowModalOpts().
Title("Modal").
ClientArea(win.SIZE{Cx: 300, Cy: 300}))
button := ui.NewButton(modal, ui.ButtonOpts().
Position(win.POINT{X: 10, Y: 10}).
Size(win.SIZE{Cx: 100, Cy: 30}).
Text("Close"))
edit := ui.NewEdit(modal, ui.EditOpts().
Position(win.POINT{X: 10, Y: 50}).
Size(win.SIZE{Cx: 280, Cy: 20}).
Text("Hello, world!"))
button.On().BnClicked(func() {
modal.Hwnd().DestroyWindow()
})
modal.On().WmDestroy(func() {
window.Hwnd().EnableWindow(true)
window.Hwnd().MessageBox(edit.Text(), "Input", co.MB_OK|co.MB_ICONINFORMATION)
})
modal.ShowModal(window)
window.Hwnd().MessageBox("Closed", "Modal", co.MB_OK|co.MB_ICONINFORMATION)
})
window.RunAsMain()
}
I can see Input message box, but not Modal message box. I was trying to implement a function that returns input value as string after modal closed, but It never returns.
I digged down windigo, and I could check the hWnd
value doesn't changed in _RunModalLoop
function even modal closed. Maybe this is the problem, but I don't know how to fix this, so I open this Issue instead of Pull Request.
Please let me know If my code is wrong. Thanks for the creating windigo.
The problem is that you're making a mess with DestroyWindow
and WmDestroy
. But in order to better understand and control what's going on, I divided your program into 3 files: main.go
, WndMain.go
and WndModal.go
. Each one takes care of 1 thing.
- Program entry point:
main.go
package main
import (
"runtime"
)
func main() {
runtime.LockOSThread()
mainWindow := NewWndMain()
mainWindow.Run()
}
- Main window:
WndMain.go
package main
import (
"github.com/rodrigocfd/windigo/ui"
"github.com/rodrigocfd/windigo/win"
)
// WndMain is the main application window.
type WndMain struct {
wnd ui.WindowMain
btnOpen ui.Button
}
// WndMain constructor.
func NewWndMain() *WndMain {
wnd := ui.NewWindowMain(
ui.WindowMainOpts().
Title("Test").
ClientArea(win.SIZE{Cx: 800, Cy: 600}),
)
mainWindow := &WndMain{
wnd: wnd,
btnOpen: ui.NewButton(
wnd,
ui.ButtonOpts().
Position(win.POINT{X: 10, Y: 10}).
Size(win.SIZE{Cx: 300, Cy: 300}).
Text("Open Modal"),
),
}
mainWindow.events()
return mainWindow
}
// WndMain will run.
func (me *WndMain) Run() {
me.wnd.RunAsMain()
}
// WndMain events are attached here.
func (me *WndMain) events() {
me.btnOpen.On().BnClicked(func() {
modal := NewWndModal()
modal.Show(me.wnd)
})
}
- Modal window:
WndModal.go
package main
import (
"github.com/rodrigocfd/windigo/ui"
"github.com/rodrigocfd/windigo/win"
"github.com/rodrigocfd/windigo/win/co"
)
// WndModal is the modal window, opened by WndMain.
type WndModal struct {
wnd ui.WindowModal
btnClose ui.Button
edit ui.Edit
}
// WndModal constructor.
func NewWndModal() *WndModal {
wnd := ui.NewWindowModal(
ui.WindowModalOpts().
Title("Modal").
ClientArea(win.SIZE{Cx: 300, Cy: 300}),
)
modalWindow := &WndModal{
wnd: wnd,
btnClose: ui.NewButton(
wnd,
ui.ButtonOpts().
Position(win.POINT{X: 10, Y: 10}).
Size(win.SIZE{Cx: 100, Cy: 30}).
Text("Close"),
),
edit: ui.NewEdit(
wnd,
ui.EditOpts().
Position(win.POINT{X: 10, Y: 50}).
Size(win.SIZE{Cx: 280, Cy: 20}).
Text("Hello, world!"),
),
}
modalWindow.events()
return modalWindow
}
// WndModal will be shown; blocks until the modal is closed.
func (me *WndModal) Show(parent ui.AnyParent) {
me.wnd.ShowModal(parent)
}
// WndModal events are attached here.
func (me *WndModal) events() {
me.btnClose.On().BnClicked(func() {
me.wnd.Hwnd().SendMessage(co.WM_CLOSE, 0, 0)
})
}
Although longer, such code structure is much more scalable, allowing your program to grow in complexity while being maintainable.
Thanks for the advise.
Sorry for asking questions, but why this code not works? I think the message box should appear after modal closed, but It doesn't appear.
// WndMain events are attached here.
func (me *WndMain) events() {
me.btnOpen.On().BnClicked(func() {
modal := NewWndModal()
modal.Show(me.wnd)
me.wnd.Hwnd().MessageBox("Modal closed.", "Test", co.MB_ICONINFORMATION)
})
}
This time you found a bug. The modal loop was not being terminated correctly in some cases. It's fixed now, thank you.
Thanks! I confirm this issue resolved.