summaryrefslogtreecommitdiff
path: root/redo/controls_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'redo/controls_windows.go')
-rw-r--r--redo/controls_windows.go87
1 files changed, 19 insertions, 68 deletions
diff --git a/redo/controls_windows.go b/redo/controls_windows.go
index 299ce99..8f82eac 100644
--- a/redo/controls_windows.go
+++ b/redo/controls_windows.go
@@ -8,47 +8,27 @@ import (
"unsafe"
)
+// #include "winapi_windows.h"
+import "C"
+
type widgetbase struct {
- hwnd uintptr
+ hwnd C.HWND
}
-var emptystr = syscall.StringToUTF16Ptr("")
-
-func newWidget(class *uint16, style uintptr, extstyle uintptr) *widgetbase {
- hwnd, err := f_CreateWindowExW(
- extstyle,
- class, emptystr,
- style | c_WS_CHILD | c_WS_VISIBLE,
- c_CW_USEDEFAULT, c_CW_USEDEFAULT,
-// c_CW_USEDEFAULT, c_CW_USEDEFAULT,
-100,100,
- // the following has the consequence of making the control message-only at first
- // this shouldn't cause any problems... hopefully not
- // but see the msgwndproc() for caveat info
- // also don't use low control IDs as they will conflict with dialog boxes (IDCANCEL, etc.)
- msgwin, 100, hInstance, nil)
- if hwnd == hNULL {
- panic(fmt.Errorf("creating control of class %q failed: %v", class, err))
- }
+func newWidget(class C.LPCWSTR, style uintptr, extstyle uintptr) *widgetbase {
return &widgetbase{
- hwnd: hwnd,
+ hwnd: C.newWidget(class, style, extstyle),
}
}
// these few methods are embedded by all the various Controls since they all will do the same thing
func (w *widgetbase) unparent() {
- res, err := f_SetParent(w.hwnd, msgwin)
- if res == hNULL { // result type is HWND
- panic(fmt.Errorf("error unparenting control: %v", err))
- }
+ C.controlSetParent(w.hwnd, C.msgwin)
}
func (w *widgetbase) parent(win *window) {
- res, err := f_SetParent(w.hwnd, win.hwnd)
- if res == hNULL { // result type is HWND
- panic(fmt.Errorf("error parenting control: %v", err))
- }
+ C.controlSetParent(w.hwnd, win.hwnd)
}
// don't embed these as exported; let each Control decide if it should
@@ -57,7 +37,7 @@ func (w *widgetbase) text() *Request {
c := make(chan interface{})
return &Request{
op: func() {
- c <- getWindowText(w.hwnd)
+ c <- C.GoString(C.getWindowText(w.hwnd))
},
resp: c,
}
@@ -67,47 +47,33 @@ func (w *widgetbase) settext(text string, results ...t_LRESULT) *Request {
c := make(chan interface{})
return &Request{
op: func() {
- setWindowText(w.hwnd, text, append([]t_LRESULT{c_FALSE}, results...))
+ C.setWindowText(w.hwnd, toUTF16(text))
c <- struct{}{}
},
resp: c,
}
}
-// all controls that have events receive the events themselves through subclasses
-// to do this, all windows (including the message-only window; see http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q104069) forward WM_COMMAND to each control with this function
-func forwardCommand(hwnd uintptr, uMsg t_UINT, wParam t_WPARAM, lParam t_LPARAM) t_LRESULT {
- control := uintptr(lParam)
- // don't generate an event if the control (if there is one) is unparented (a child of the message-only window)
- if control != hNULL && f_IsChild(msgwin, control) == 0 {
- return f_SendMessageW(control, msgCOMMAND, wParam, lParam)
- }
- return f_DefWindowProcW(hwnd, uMsg, wParam, lParam)
-}
-
type button struct {
*widgetbase
clicked *event
}
-var buttonclass = syscall.StringToUTF16Ptr("BUTTON")
+var buttonclass = toUTF16("BUTTON")
func newButton(text string) *Request {
c := make(chan interface{})
return &Request{
op: func() {
w := newWidget(buttonclass,
- c_BS_PUSHBUTTON | c_WS_TABSTOP,
+ C.BS_PUSHBUTTON | C.WS_TABSTOP,
0)
- setWindowText(w.hwnd, text, []t_LRESULT{c_FALSE})
+ C.setWindowText(w.hwnd, toUTF16(text))
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.setButtonSubclass(w.hwnd, unsafe.Pointer(b))
c <- b
},
resp: c,
@@ -140,24 +106,9 @@ 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)))
- switch uMsg {
- case msgCOMMAND:
- if wParam.HIWORD() == c_BN_CLICKED {
- b.clicked.fire()
- println("button clicked")
- return 0
- }
- return f_DefSubclassProc(hwnd, uMsg, wParam, lParam)
- case c_WM_NCDESTROY:
- 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:
- return f_DefSubclassProc(hwnd, uMsg, wParam, lParam)
- }
- panic(fmt.Errorf("Button message %d does not return a value (bug in buttonSubProc())", uMsg))
+//export buttonClicked
+func buttonClicked(data unsafe.Pointer) {
+ b := (*button)(data)
+ b.clicked.fire()
+ println("button clicked")
}