Started the Windows implementation of Area.

This commit is contained in:
Pietro Gagliardi 2014-03-24 13:32:38 -04:00
parent 6da4a9ba9f
commit 5c8587ab00
2 changed files with 89 additions and 3 deletions

74
area_windows.go Normal file
View File

@ -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
}

View File

@ -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
}