diff options
Diffstat (limited to 'redo/window_windows.go')
| -rw-r--r-- | redo/window_windows.go | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/redo/window_windows.go b/redo/window_windows.go new file mode 100644 index 0000000..aba3232 --- /dev/null +++ b/redo/window_windows.go @@ -0,0 +1,166 @@ +// 12 july 2014 + +package ui + +import ( + "fmt" + "syscall" + "unsafe" +) + +type window struct { + hwnd uintptr + shownbefore bool + + closing *event +} + +const windowclassname = "gouiwindow" +var windowclassptr = syscall.StringToUTF16Ptr(windowclassname) + +func makeWindowWindowClass() error { + var wc s_WNDCLASSW + + wc.lpfnWndProc = syscall.NewCallback(windowWndProc) + wc.hInstance = hInstance + wc.hIcon = hDefaultIcon + wc.hCursor = hArrowCursor + wc.hbrBackground = c_COLOR_BTNFACE + 1 + wc.lpszClassName = windowclassptr + res, err := f_RegisterClassW(&wc) + if res == 0 { + return fmt.Errorf("error registering Window window class: %v", err) + } + return nil +} + +func newWindow(title string, width int, height int) *Request { + c := make(chan interface{}) + return &Request{ + op: func() { + w := &window{ + // hwnd set in WM_CREATE handler + closing: newEvent(), + } + hwnd, err := f_CreateWindowExW( + 0, + windowclassptr, + syscall.StringToUTF16Ptr(title), + c_WS_OVERLAPPED, + c_CW_USEDEFAULT, c_CW_USEDEFAULT, + uintptr(width), uintptr(height), + hNULL, hNULL, hInstance, unsafe.Pointer(w)) + if hwnd == hNULL { + panic(fmt.Errorf("Window creation failed: %v", err)) + } else if hwnd != w.hwnd { + panic(fmt.Errorf("inconsistency: hwnd returned by CreateWindowEx() (%p) and hwnd stored in window (%p) differ", hwnd, w.hwnd)) + } + c <- w + }, + resp: c, + } +} + +func (w *window) SetControl(control Control) *Request { + c := make(chan interface{}) + return &Request{ + op: func() { + // TODO unparent + // TODO reparent + c <- struct{}{} + }, + resp: c, + } +} + +func (w *window) Title() *Request { + c := make(chan interface{}) + return &Request{ + op: func() { + c <- getWindowText(w.hwnd) + }, + resp: c, + } +} + +func (w *window) SetTitle(title string) *Request { + c := make(chan interface{}) + return &Request{ + op: func() { + setWindowText(w.hwnd, title, []t_LRESULT{c_FALSE}) + c <- struct{}{} + }, + resp: c, + } +} + +func (w *window) Show() *Request { + c := make(chan interface{}) + return &Request{ + op: func() { + if !w.shownbefore { + // TODO get rid of need for cast + f_ShowWindow(w.hwnd, uintptr(nCmdShow)) + updateWindow(w.hwnd, "Window.Show()") + w.shownbefore = true + } else { + f_ShowWindow(w.hwnd, c_SW_SHOW) + } + c <- struct{}{} + }, + resp: c, + } +} + +func (w *window) Hide() *Request { + c := make(chan interface{}) + return &Request{ + op: func() { + f_ShowWindow(w.hwnd, c_SW_HIDE) + c <- struct{}{} + }, + resp: c, + } +} + +func (w *window) Close() *Request { + c := make(chan interface{}) + return &Request{ + op: func() { + // TODO + c <- struct{}{} + }, + resp: c, + } +} + +func (w *window) OnClosing(e func(Doer) bool) *Request { + c := make(chan interface{}) + return &Request{ + op: func() { + w.closing.setbool(e) + c <- struct{}{} + }, + resp: c, + } +} + +func windowWndProc(hwnd uintptr, msg t_UINT, wParam t_WPARAM, lParam t_LPARAM) t_LRESULT { + w := (*window)(unsafe.Pointer(f_GetWindowLongPtrW(hwnd, c_GWLP_USERDATA))) + if w == nil { + // the lpParam is available during WM_NCCREATE and WM_CREATE + if msg == c_WM_NCCREATE { + storelpParam(hwnd, lParam) + } + // act as if we're not ready yet, even during WM_NCCREATE (nothing important to the switch statement below happens here anyway) + return f_DefWindowProcW(hwnd, msg, wParam, lParam) + } + switch msg { + default: + return f_DefWindowProcW(hwnd, msg, wParam, lParam) + } + panic(fmt.Errorf("Window message %d does not return a value (bug in windowWndProc())", msg)) +} + +// TODO +func newButton(string)*Request{return nil}
\ No newline at end of file |
