summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--redo/container_windows.go7
-rw-r--r--redo/control_windows.go5
-rw-r--r--redo/label_windows.go3
-rw-r--r--redo/tab_windows.c2
-rw-r--r--redo/tab_windows.go11
-rw-r--r--redo/uitask_windows.c20
-rw-r--r--redo/winapi_windows.h1
-rw-r--r--redo/window_windows.go2
8 files changed, 34 insertions, 17 deletions
diff --git a/redo/container_windows.go b/redo/container_windows.go
index 5cd1877..c782c38 100644
--- a/redo/container_windows.go
+++ b/redo/container_windows.go
@@ -14,6 +14,7 @@ import "C"
type container struct {
containerbase
hwnd C.HWND
+ nchildren int
}
type sizing struct {
@@ -45,12 +46,12 @@ func newContainer(control Control) *container {
panic(fmt.Errorf("inconsistency: hwnd returned by CreateWindowEx() (%p) and hwnd stored in container (%p) differ", hwnd, c.hwnd))
}
c.child = control
- c.child.setParent(&controlParent{c.hwnd})
+ c.child.setParent(&controlParent{c})
return c
}
-func (c *container) setParent(p *controlParent) {
- C.controlSetParent(c.hwnd, p.hwnd)
+func (c *container) setParent(hwnd C.HWND) {
+ C.controlSetParent(c.hwnd, hwnd)
}
// this is needed because Windows won't move/resize a child window for us
diff --git a/redo/control_windows.go b/redo/control_windows.go
index 49ac644..564d8d4 100644
--- a/redo/control_windows.go
+++ b/redo/control_windows.go
@@ -11,11 +11,12 @@ type controlPrivate interface {
}
type controlParent struct {
- hwnd C.HWND
+ c *container
}
func basesetParent(c controlPrivate, p *controlParent) {
- C.controlSetParent(c.hwnd(), p.hwnd)
+ C.controlSetParent(c.hwnd(), p.c.hwnd)
+ p.c.nchildren++
}
// don't specify basepreferredSize; it is custom on ALL controls
diff --git a/redo/label_windows.go b/redo/label_windows.go
index d87f02e..a37bc9d 100644
--- a/redo/label_windows.go
+++ b/redo/label_windows.go
@@ -57,7 +57,8 @@ func (l *label) settextlen(len C.LONG) {
}
func (l *label) setParent(p *controlParent) {
- basesetParent(l, p)
+ C.controlSetParent(l.hwnd(), p.c.hwnd)
+ // don't increment p.c.nchildren here because Labels aren't tab stops
}
func (l *label) allocate(x int, y int, width int, height int, d *sizing) []*allocation {
diff --git a/redo/tab_windows.c b/redo/tab_windows.c
index 4958a68..9a9908a 100644
--- a/redo/tab_windows.c
+++ b/redo/tab_windows.c
@@ -25,6 +25,8 @@ static LRESULT CALLBACK tabSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
return 0;
}
return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
+ case msgTabCurrentTabHasChildren:
+ return (LRESULT) tabTabHasChildren((void *) data, SendMessageW(hwnd, TCM_GETCURSEL, 0, 0));
case WM_NCDESTROY:
if ((*fv_RemoveWindowSubclass)(hwnd, tabSubProc, id) == FALSE)
xpanic("error removing Tab subclass (which was for its own event handler)", GetLastError());
diff --git a/redo/tab_windows.go b/redo/tab_windows.go
index 1d22887..371d7bc 100644
--- a/redo/tab_windows.go
+++ b/redo/tab_windows.go
@@ -34,7 +34,7 @@ func newTab() Tab {
func (t *tab) Append(name string, control Control) {
c := newContainer(control)
- c.setParent(&controlParent{t._hwnd})
+ c.setParent(t._hwnd)
t.tabs = append(t.tabs, c)
// initially hide tab 1..n controls; if we don't, they'll appear over other tabs, resulting in weird behavior
if len(t.tabs) != 1 {
@@ -55,6 +55,15 @@ func tabChanged(data unsafe.Pointer, new C.LRESULT) {
t.tabs[int(new)].show()
}
+//export tabTabHasChildren
+func tabTabHasChildren(data unsafe.Pointer, which C.LRESULT) C.BOOL {
+ t := (*tab)(data)
+ if t.tabs[int(which)].nchildren > 0 {
+ return C.TRUE
+ }
+ return C.FALSE
+}
+
func (t *tab) hwnd() C.HWND {
return t._hwnd
}
diff --git a/redo/uitask_windows.c b/redo/uitask_windows.c
index 3101452..9ba418e 100644
--- a/redo/uitask_windows.c
+++ b/redo/uitask_windows.c
@@ -41,17 +41,19 @@ void uimsgloop(void)
if (wcscmp(classchk, areaWindowClass) == 0)
dodlgmessage = FALSE;
else if (wcscmp(classchk, WC_TABCONTROL) == 0)
- istab = TRUE;
+ // THIS BIT IS IMPORTANT
+ // if the current tab has no children, then there will be no children left in the dialog to tab to, and IsDialogMessageW() will loop forever
+ istab = (BOOL) SendMessageW(focus, msgTabCurrentTabHasChildren, 0, 0);
}
- if (istab)
- tabEnterChildren(focus);
- // TODO this goes into an infinite loop on a blank tab
- if (dodlgmessage)
+ if (dodlgmessage) {
+ if (istab)
+ tabEnterChildren(focus);
idm = IsDialogMessageW(active, &msg);
- if (istab)
- tabLeaveChildren(focus);
- if (idm != 0)
- continue;
+ if (istab)
+ tabLeaveChildren(focus);
+ if (idm != 0)
+ continue;
+ }
}
TranslateMessage(&msg);
DispatchMessageW(&msg);
diff --git a/redo/winapi_windows.h b/redo/winapi_windows.h
index c063679..c5fd4c1 100644
--- a/redo/winapi_windows.h
+++ b/redo/winapi_windows.h
@@ -29,6 +29,7 @@ enum {
msgNOTIFY, // WM_NOTIFY proxy
msgAreaSizeChanged,
msgAreaRepaintAll,
+ msgTabCurrentTabHasChildren,
};
// uitask_windows.c
diff --git a/redo/window_windows.go b/redo/window_windows.go
index 3a551c2..60f89d1 100644
--- a/redo/window_windows.go
+++ b/redo/window_windows.go
@@ -44,7 +44,7 @@ func newWindow(title string, width int, height int, control Control) *window {
if hresult != C.S_OK {
panic(fmt.Errorf("error setting tab background texture on Window; HRESULT: 0x%X", hresult))
}
- w.container.setParent(&controlParent{w.hwnd})
+ w.container.setParent(w.hwnd)
return w
}