Restructuring the codebase to make things neater. First off: each window now has its own class; the sysData knows about children. This updates the window class to become a generator and rewrites the WndProc as well.

This commit is contained in:
Pietro Gagliardi 2014-02-12 20:51:07 -05:00
parent a9ff388944
commit 4b16716e61
2 changed files with 77 additions and 56 deletions

View File

@ -67,9 +67,9 @@ func doWindowsInit() (err error) {
if err != nil {
return fmt.Errorf("error getting WinMain nCmdShow: %v", err)
}
err = registerStdWndClass()
err = initWndClassInfo()
if err != nil {
return fmt.Errorf("error registering standard window class: %v", err)
return fmt.Errorf("error initializing standard window class auxiliary info: %v", err)
}
// TODO others
return nil // all ready to go

View File

@ -5,29 +5,34 @@ import (
"fmt"
"syscall"
"unsafe"
"sync"
)
const (
stdWndClassFormat = "gouiwnd%X"
)
var (
stdWndClass = "gouiwndclass"
curWndClassNum uintptr
curWndClassNumLock sync.Mutex
)
var (
defWindowProc = user32.NewProc("DefWindowProcW")
)
func stdWndProc(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT {
sysData := getSysData(hwnd)
if sysData == nil { // not ready for events yet
goto defwndproc
}
func stdWndProc(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 {
case _WM_COMMAND:
id := _HMENU(wParam.LOWORD())
sysData = getSysDataID(id)
switch sysData.ctype {
s.childrenLock.Lock()
defer s.childrenLock.Unlock()
ss = s.children[id]
switch ss.ctype {
case c_button:
if wParam.HIWORD() == _BN_CLICKED {
sysData.clicked <- struct{}{}
sysData.event <- struct{}{}
}
}
return 0
@ -45,16 +50,15 @@ func stdWndProc(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESUL
}
return 0
default:
goto defwndproc
}
panic(fmt.Sprintf("stdWndProc message %d did not return: internal bug in ui library", uMsg))
defwndproc:
r1, _, _ := defWindowProc.Call(
uintptr(hwnd),
uintptr(uMsg),
uintptr(wParam),
uintptr(lParam))
return _LRESULT(r1)
}
panic(fmt.Sprintf("stdWndProc message %d did not return: internal bug in ui library", uMsg))
}
}
type _WNDCLASS struct {
@ -70,7 +74,37 @@ type _WNDCLASS struct {
lpszClassName uintptr
}
func registerStdWndClass() (err error) {
var (
icon, cursor _HANDLE
)
var (
_registerClass = user32.NewProc("RegisterClassW")
)
func registerStdWndClass(s *sysData) (newClassName string, err error) {
curWndClassNumLock.Lock()
newClassName = fmt.Sprintf(stdWndClassFormat, curWndClassNum)
curWndClassNum++
curWndClassNumLock.Unlock()
wc := &_WNDCLASS{
lpszClassName: uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(newClassName))),
lpfnWndProc: syscall.NewCallback(stdWndProc(s)),
hInstance: hInstance,
hIcon: icon,
hCursor: cursor,
hbrBackground: _HBRUSH(_COLOR_BTNFACE + 1),
}
r1, _, err = user32.NewProc("RegisterClassW").Call(uintptr(unsafe.Pointer(wc)))
if r1 == 0 { // failure
return "", err
}
return newClassName, nil
}
func initWndClassInfo() (err error) {
const (
_IDI_APPLICATION = 32512
_IDC_ARROW = 32512
@ -82,7 +116,7 @@ func registerStdWndClass() (err error) {
if r1 == 0 { // failure
return fmt.Errorf("error getting window icon: %v", err)
}
icon := _HANDLE(r1)
icon = _HANDLE(r1)
r1, _, err = user32.NewProc("LoadCursorW").Call(
uintptr(_NULL),
@ -90,20 +124,7 @@ func registerStdWndClass() (err error) {
if r1 == 0 { // failure
return fmt.Errorf("error getting window cursor: %v", err)
}
cursor := _HANDLE(r1)
cursor = _HANDLE(r1)
wc := &_WNDCLASS{
lpszClassName: uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(stdWndClass))),
lpfnWndProc: syscall.NewCallback(stdWndProc),
hInstance: hInstance,
hIcon: icon,
hCursor: cursor,
hbrBackground: _HBRUSH(_COLOR_BTNFACE + 1),
}
r1, _, err = user32.NewProc("RegisterClassW").Call(uintptr(unsafe.Pointer(wc)))
if r1 == 0 { // failure
return fmt.Errorf("error registering class: %v", err)
}
return nil
}