Started the Windows implementation of Area.
This commit is contained in:
parent
6da4a9ba9f
commit
5c8587ab00
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue