From 5626b9e35c5824707a905a26f9b074240cd54e7a Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Thu, 13 Feb 2014 05:28:26 -0500 Subject: [PATCH] Added sizing of windows and the main window control. It presently deadlocks; I'll need to redo my mutexes... --- button.go | 7 +++++++ control.go | 1 + stdwndclass_windows.go | 15 ++++++++++++++- sysdata.go | 4 ++++ sysdata_windows.go | 22 ++++++++++++++++++++++ window.go | 4 ++++ windows_windows.go | 28 +--------------------------- 7 files changed, 53 insertions(+), 28 deletions(-) diff --git a/button.go b/button.go index 4603ee00..d464780d 100644 --- a/button.go +++ b/button.go @@ -49,6 +49,13 @@ func (b *Button) apply(window *sysData) error { // TODO size to parent size } +func (b *Button) setRect(x int, y int, width int, height int) error { + b.lock.Lock() + defer b.lock.Unlock() + + return b.sysData.setRect(x, y, width, height) +} + func (b *Button) setParent(c Control) { b.parent = c } diff --git a/control.go b/control.go index 4e1243e0..a1f83afb 100644 --- a/control.go +++ b/control.go @@ -9,5 +9,6 @@ import ( // A Control represents an UI control. Note that Control contains unexported members; this has the consequence that you can't build custom controls that interface directly with the system-specific code (fo rinstance, to import an unsupported control), or at least not without some hackery. If you want to make your own controls, embed Area and provide its necessities. type Control interface { apply(window *sysData) error + setRect(x int, y int, width int, height int) error setParent(c Control) } diff --git a/stdwndclass_windows.go b/stdwndclass_windows.go index b87743ff..28247462 100644 --- a/stdwndclass_windows.go +++ b/stdwndclass_windows.go @@ -42,7 +42,20 @@ func stdWndProc(s *sysData) func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _ = mm return 0 case _WM_SIZE: - // TODO + if s.resize != nil { + var r _RECT + + r1, _, err := _getClientRect.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&r))) + if r1 == 0 { + panic("GetClientRect failed: " + err.Error()) + } + err = s.resize(int(r.Left), int(r.Top), int(r.Right), int(r.Bottom)) + if err != nil { + panic("child resize failed: " + err.Error()) + } + } return 0 case _WM_CLOSE: if s.event != nil { diff --git a/sysdata.go b/sysdata.go index ee99ae2d..a0b5b107 100644 --- a/sysdata.go +++ b/sysdata.go @@ -9,6 +9,7 @@ import ( type cSysData struct { ctype int event chan struct{} + resize func(x int, y int, width int, height int) error } func (c *cSysData) make(initText string, initWidth int, initHeight int, window *sysData) error { panic(runtime.GOOS + " sysData does not define make()") @@ -22,6 +23,9 @@ func (c *cSysData) hide() error { func (c *cSysData) setText(text string) error { panic(runtime.GOOS + " sysData does not define setText()") } +func (c *cSysData) setRect(x int, y int, width int, height int) error { + panic(runtime.GOOS + " sysData does not define setRect()") +} const ( c_window = iota diff --git a/sysdata_windows.go b/sysdata_windows.go index da1c6b81..fd0d1800 100644 --- a/sysdata_windows.go +++ b/sysdata_windows.go @@ -174,3 +174,25 @@ func (s *sysData) setText(text string) error { } return nil } + +func (s *sysData) setRect(x int, y int, width int, height int) error { + ret := make(chan uiret) + defer close(ret) + uitask <- &uimsg{ + call: _moveWindow, + p: []uintptr{ + uintptr(s.hwnd), + uintptr(x), + uintptr(y), + uintptr(width), + uintptr(height), + uintptr(_TRUE), + }, + ret: ret, + } + r := <-ret + if r.ret == 0 { // failure + return r.err + } + return nil +} diff --git a/window.go b/window.go index 0e4f7aa3..29003ec4 100644 --- a/window.go +++ b/window.go @@ -77,6 +77,7 @@ func (w *Window) Open(control Control) (err error) { return err } if control != nil { + w.sysData.resize = control.setRect err = control.apply(w.sysData) if err != nil { return err @@ -101,6 +102,9 @@ func (w *Window) Hide() (err error) { func (w *Window) apply(window *sysData) error { panic("Window.apply() should never be called") } +func (w *Window) setRect(x int, y int, width int, height int) error { + panic("Window.setRect() should never be called") +} func (w *Window) setParent(c Control) { panic("Window.setParent() should never be called") } diff --git a/windows_windows.go b/windows_windows.go index 16f451da..fa62c1da 100644 --- a/windows_windows.go +++ b/windows_windows.go @@ -169,6 +169,7 @@ var ( _destroyWindow = user32.NewProc("DestroyWindow") _getClientRect = user32.NewProc("GetClientRect") _enumChildWindows = user32.NewProc("EnumChildWindows") + _moveWindow = user32.NewProc("MoveWindow") _setWindowPos = user32.NewProc("SetWindowPos") _setWindowText = user32.NewProc("SetWindowTextW") _showWindow = user32.NewProc("ShowWindow") @@ -203,33 +204,6 @@ func EnumChildWindows(hWndParent HWND, lpEnumFunc WNDENUMPROC, lParam LPARAM) (e uintptr(lParam)) return nil } - -// TODO return the rect itself? -func GetClientRect(hWnd HWND) (lpRect *RECT, err error) { - lpRect = new(RECT) - r1, _, err := getClientRect.Call( - uintptr(hWnd), - uintptr(unsafe.Pointer(lpRect))) - if r1 == 0 { // failure - return nil, err - } - return lpRect, nil -} - -func SetWindowPos(hWnd HWND, hWndInsertAfter HWND, X int, Y int, cx int, cy int, uFlags uint32) (err error) { - r1, _, err := setWindowPos.Call( - uintptr(hWnd), - uintptr(hWndInsertAfter), - uintptr(X), - uintptr(Y), - uintptr(cx), - uintptr(cy), - uintptr(uFlags)) - if r1 == 0 { // failure - return err - } - return nil -} */ // WM_SETICON and WM_GETICON values.