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:
parent
a9ff388944
commit
4b16716e61
|
@ -67,9 +67,9 @@ func doWindowsInit() (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error getting WinMain nCmdShow: %v", err)
|
return fmt.Errorf("error getting WinMain nCmdShow: %v", err)
|
||||||
}
|
}
|
||||||
err = registerStdWndClass()
|
err = initWndClassInfo()
|
||||||
if err != nil {
|
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
|
// TODO others
|
||||||
return nil // all ready to go
|
return nil // all ready to go
|
||||||
|
|
|
@ -5,56 +5,60 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
stdWndClassFormat = "gouiwnd%X"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
stdWndClass = "gouiwndclass"
|
curWndClassNum uintptr
|
||||||
|
curWndClassNumLock sync.Mutex
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
defWindowProc = user32.NewProc("DefWindowProcW")
|
defWindowProc = user32.NewProc("DefWindowProcW")
|
||||||
)
|
)
|
||||||
|
|
||||||
func stdWndProc(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT {
|
func stdWndProc(s *sysData) func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT {
|
||||||
sysData := getSysData(hwnd)
|
return func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT {
|
||||||
if sysData == nil { // not ready for events yet
|
switch uMsg {
|
||||||
goto defwndproc
|
case _WM_COMMAND:
|
||||||
}
|
id := _HMENU(wParam.LOWORD())
|
||||||
switch uMsg {
|
s.childrenLock.Lock()
|
||||||
case _WM_COMMAND:
|
defer s.childrenLock.Unlock()
|
||||||
id := _HMENU(wParam.LOWORD())
|
ss = s.children[id]
|
||||||
sysData = getSysDataID(id)
|
switch ss.ctype {
|
||||||
switch sysData.ctype {
|
case c_button:
|
||||||
case c_button:
|
if wParam.HIWORD() == _BN_CLICKED {
|
||||||
if wParam.HIWORD() == _BN_CLICKED {
|
sysData.event <- struct{}{}
|
||||||
sysData.clicked <- struct{}{}
|
}
|
||||||
}
|
}
|
||||||
|
return 0
|
||||||
|
case _WM_GETMINMAXINFO:
|
||||||
|
mm := lParam.MINMAXINFO()
|
||||||
|
// ... minimum size
|
||||||
|
_ = mm
|
||||||
|
return 0
|
||||||
|
case _WM_SIZE:
|
||||||
|
// TODO
|
||||||
|
return 0
|
||||||
|
case _WM_CLOSE:
|
||||||
|
if sysData.closing != nil {
|
||||||
|
sysData.closing <- struct{}{}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
default:
|
||||||
|
r1, _, _ := defWindowProc.Call(
|
||||||
|
uintptr(hwnd),
|
||||||
|
uintptr(uMsg),
|
||||||
|
uintptr(wParam),
|
||||||
|
uintptr(lParam))
|
||||||
|
return _LRESULT(r1)
|
||||||
}
|
}
|
||||||
return 0
|
panic(fmt.Sprintf("stdWndProc message %d did not return: internal bug in ui library", uMsg))
|
||||||
case _WM_GETMINMAXINFO:
|
|
||||||
mm := lParam.MINMAXINFO()
|
|
||||||
// ... minimum size
|
|
||||||
_ = mm
|
|
||||||
return 0
|
|
||||||
case _WM_SIZE:
|
|
||||||
// TODO
|
|
||||||
return 0
|
|
||||||
case _WM_CLOSE:
|
|
||||||
if sysData.closing != nil {
|
|
||||||
sysData.closing <- struct{}{}
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type _WNDCLASS struct {
|
type _WNDCLASS struct {
|
||||||
|
@ -70,7 +74,37 @@ type _WNDCLASS struct {
|
||||||
lpszClassName uintptr
|
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 (
|
const (
|
||||||
_IDI_APPLICATION = 32512
|
_IDI_APPLICATION = 32512
|
||||||
_IDC_ARROW = 32512
|
_IDC_ARROW = 32512
|
||||||
|
@ -82,7 +116,7 @@ func registerStdWndClass() (err error) {
|
||||||
if r1 == 0 { // failure
|
if r1 == 0 { // failure
|
||||||
return fmt.Errorf("error getting window icon: %v", err)
|
return fmt.Errorf("error getting window icon: %v", err)
|
||||||
}
|
}
|
||||||
icon := _HANDLE(r1)
|
icon = _HANDLE(r1)
|
||||||
|
|
||||||
r1, _, err = user32.NewProc("LoadCursorW").Call(
|
r1, _, err = user32.NewProc("LoadCursorW").Call(
|
||||||
uintptr(_NULL),
|
uintptr(_NULL),
|
||||||
|
@ -90,20 +124,7 @@ func registerStdWndClass() (err error) {
|
||||||
if r1 == 0 { // failure
|
if r1 == 0 { // failure
|
||||||
return fmt.Errorf("error getting window cursor: %v", err)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue