diff --git a/redo/comctl32_windows.go b/redo/comctl32_windows.go index 6b3d6e5..282d721 100644 --- a/redo/comctl32_windows.go +++ b/redo/comctl32_windows.go @@ -102,8 +102,8 @@ func f_RemoveWindowSubclass(hwnd uintptr, subproc uintptr, id t_UINT_PTR) (uintp return r1, err } -func f_DefSubclassProc(hwnd uintptr, uMsg t_UINT, wParam t_WPARAM, lParam t_LPARAM, id t_UINT_PTR, data t_DWORD_PTR) t_LRESULT { - r1, _, _ := fv_DefSubclassProc.Call(hwnd, uintptr(uMsg), uintptr(wParam), uintptr(lParam), uintptr(id), uintptr(data)) +func f_DefSubclassProc(hwnd uintptr, uMsg t_UINT, wParam t_WPARAM, lParam t_LPARAM) t_LRESULT { + r1, _, _ := fv_DefSubclassProc.Call(hwnd, uintptr(uMsg), uintptr(wParam), uintptr(lParam)) return t_LRESULT(r1) } diff --git a/redo/controls_windows.go b/redo/controls_windows.go index dd4b8c9..299ce99 100644 --- a/redo/controls_windows.go +++ b/redo/controls_windows.go @@ -100,10 +100,15 @@ func newButton(text string) *Request { c_BS_PUSHBUTTON | c_WS_TABSTOP, 0) setWindowText(w.hwnd, text, []t_LRESULT{c_FALSE}) - c <- &button{ + b := &button{ widgetbase: w, clicked: newEvent(), } + res, err := f_SetWindowSubclass(w.hwnd, buttonsubprocptr, 0, t_DWORD_PTR(uintptr(unsafe.Pointer(b)))) + if res == c_FALSE { + panic(fmt.Errorf("error subclassing Button to give it its own event handler: %v", err)) + } + c <- b }, resp: c, } @@ -128,7 +133,12 @@ func (b *button) SetText(text string) *Request { return b.settext(text) } -var buttonsubprocptr = syscall.NewCallback(buttonSubProc) +var buttonsubprocptr uintptr + +// to avoid recursive initialization loop +func init() { + buttonsubprocptr = syscall.NewCallback(buttonSubProc) +} func buttonSubProc(hwnd uintptr, uMsg t_UINT, wParam t_WPARAM, lParam t_LPARAM, id t_UINT_PTR, data t_DWORD_PTR) t_LRESULT { b := (*button)(unsafe.Pointer(uintptr(data))) @@ -139,12 +149,15 @@ func buttonSubProc(hwnd uintptr, uMsg t_UINT, wParam t_WPARAM, lParam t_LPARAM, println("button clicked") return 0 } - // TODO return + return f_DefSubclassProc(hwnd, uMsg, wParam, lParam) case c_WM_NCDESTROY: - // TODO remove - // TODO return + res, err := f_RemoveWindowSubclass(b.hwnd, buttonsubprocptr, id) + if res == c_FALSE { + panic(fmt.Errorf("error removing Button subclass (which was for its own event handler): %v", err)) + } + return f_DefSubclassProc(hwnd, uMsg, wParam, lParam) default: - // TODO return + return f_DefSubclassProc(hwnd, uMsg, wParam, lParam) } panic(fmt.Errorf("Button message %d does not return a value (bug in buttonSubProc())", uMsg)) }