diff --git a/area_windows.go b/area_windows.go new file mode 100644 index 0000000..affdd9c --- /dev/null +++ b/area_windows.go @@ -0,0 +1,74 @@ +// 24 march 2014 + +package ui + +import ( + "fmt" + "syscall" + "unsafe" + "sync" +) + +const ( + areastyle = 0 | controlstyle + areaxstyle = 0 | controlxstyle +) + +const ( + areaWndClassFormat = "gouiarea%X" +) + +var ( + areaWndClassNum uintptr + areaWndClassNumLock sync.Mutex +) + +func areaWndProc(s *sysData) func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT { + return func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT { + switch uMsg { + default: + r1, _, _ := defWindowProc.Call( + uintptr(hwnd), + uintptr(uMsg), + uintptr(wParam), + uintptr(lParam)) + return _LRESULT(r1) + } + panic(fmt.Sprintf("areaWndProc message %d did not return: internal bug in ui library", uMsg)) + } +} + +func registerAreaWndClass(s *sysData) (newClassName string, err error) { + const ( + // from winuser.h + _CS_DBLCLKS = 0x0008 + ) + + areaWndClassNumLock.Lock() + newClassName = fmt.Sprintf(areaWndClassFormat, areaWndClassNum) + areaWndClassNum++ + areaWndClassNumLock.Unlock() + + wc := &_WNDCLASS{ + style: _CS_DBLCLKS, // needed to be able to register double-clicks + lpszClassName: uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(newClassName))), + lpfnWndProc: syscall.NewCallback(areaWndProc(s)), + hInstance: hInstance, + hIcon: icon, + hCursor: cursor, + hbrBackground: _HBRUSH(_COLOR_BTNFACE + 1), + } + + ret := make(chan uiret) + defer close(ret) + uitask <- &uimsg{ + call: _registerClass, + p: []uintptr{uintptr(unsafe.Pointer(wc))}, + ret: ret, + } + r := <-ret + if r.ret == 0 { // failure + return "", r.err + } + return newClassName, nil +} diff --git a/sysdata_windows.go b/sysdata_windows.go index 0a526ba..6782300 100644 --- a/sysdata_windows.go +++ b/sysdata_windows.go @@ -21,6 +21,7 @@ type sysData struct { type classData struct { name string + register func(s *sysData) (newClassName string, err error) style uint32 xstyle uint32 mkid bool @@ -40,6 +41,7 @@ const controlxstyle = 0 var classTypes = [nctypes]*classData{ c_window: &classData{ + register: registerStdWndClass, style: _WS_OVERLAPPEDWINDOW, xstyle: 0, }, @@ -103,6 +105,11 @@ var classTypes = [nctypes]*classData{ style: _PBS_SMOOTH | controlstyle, xstyle: 0 | controlxstyle, }, + c_area: &classData{ + register: registerAreaWndClass, + style: areastyle, + xstyle: areaxstyle, + }, } func (s *sysData) addChild(child *sysData) _HMENU { @@ -132,10 +139,11 @@ func (s *sysData) make(initText string, window *sysData) (err error) { if window != nil { // this is a child control cid = window.addChild(s) pwin = uintptr(window.hwnd) - } else { // need a new class - n, err := registerStdWndClass(s) + } + if classname == "" { // need a new window class + n, err := ct.register(s) if err != nil { - return fmt.Errorf("error creating window class for new window: %v", err) + return fmt.Errorf("error creating window class for new window/control (type %d): %v", s.ctype, err) } classname = n } @@ -613,3 +621,7 @@ func (s *sysData) len() int { } return int(r.ret) } + +func (s *sysData) setAreaSize(width int, height int) { + // TODO +}