-
Notifications
You must be signed in to change notification settings - Fork 0
/
window_base.go
134 lines (112 loc) · 2.94 KB
/
window_base.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package gwin
import (
"errors"
"syscall"
"unsafe"
"github.com/lxn/win"
)
var handle2wb = make(map[win.HWND]*windowBase)
type windowBase struct {
Handle win.HWND
Name string
proc func(msg uint32, wParam, lParam uintptr) (result uintptr)
}
func (wb *windowBase) Valid() bool {
return wb.Handle != 0
}
func (wb *windowBase) Close() {
if wb.Valid() {
win.DestroyWindow(wb.Handle)
}
}
func (wb *windowBase) wndProc(msg uint32, wParam, lParam uintptr) (result uintptr) {
defer func() {
if msg == win.WM_DESTROY {
delete(handle2wb, wb.Handle)
wb.Handle = 0
}
}()
if wb.proc != nil {
return wb.proc(msg, wParam, lParam)
}
return win.DefWindowProc(wb.Handle, msg, wParam, lParam)
}
func createWindowBase(parent *windowBase, className string, windowName string, style, exStyle uint32,
x, y, nWidth, nHeight int32,
wndProc func(msg uint32, wParam, lParam uintptr) (result uintptr)) (*windowBase, error) {
parentHandle := win.HWND(0)
if parent != nil {
parentHandle = parent.Handle
}
wb := &windowBase{
Name: windowName,
proc: wndProc,
}
hwnd := win.CreateWindowEx(
exStyle,
syscall.StringToUTF16Ptr(className),
syscall.StringToUTF16Ptr(windowName),
style|win.WS_CLIPSIBLINGS,
x,
y,
nWidth,
nHeight,
parentHandle,
0,
0,
nil)
if hwnd == 0 {
return nil, errors.New("createWindow fail")
}
wb.Handle = hwnd
handle2wb[hwnd] = wb
return wb, nil
}
var (
defaultWndProcPtr = syscall.NewCallback(defaultWndProc)
)
func defaultWndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) (result uintptr) {
wb := handle2wb[hwnd]
if wb != nil {
return wb.wndProc(msg, wParam, lParam)
}
return win.DefWindowProc(hwnd, msg, wParam, lParam)
}
func MustRegisterWindowClass(className string) {
MustRegisterWindowClassWithWndProcPtr(className, defaultWndProcPtr)
}
func MustRegisterWindowClassWithStyle(className string, style uint32) {
MustRegisterWindowClassWithWndProcPtrAndStyle(className, defaultWndProcPtr, style)
}
func MustRegisterWindowClassWithWndProcPtr(className string, wndProcPtr uintptr) {
MustRegisterWindowClassWithWndProcPtrAndStyle(className, wndProcPtr, 0)
}
func MustRegisterWindowClassWithWndProcPtrAndStyle(className string, wndProcPtr uintptr, style uint32) {
hInst := win.GetModuleHandle(nil)
if hInst == 0 {
panic("GetModuleHandle")
}
hIcon := win.LoadIcon(hInst, win.MAKEINTRESOURCE(7)) // rsrc uses 7 for app icon
if hIcon == 0 {
hIcon = win.LoadIcon(0, win.MAKEINTRESOURCE(win.IDI_APPLICATION))
}
if hIcon == 0 {
panic("LoadIcon")
}
hCursor := win.LoadCursor(0, win.MAKEINTRESOURCE(win.IDC_ARROW))
if hCursor == 0 {
panic("LoadCursor")
}
var wc win.WNDCLASSEX
wc.CbSize = uint32(unsafe.Sizeof(wc))
wc.LpfnWndProc = wndProcPtr
wc.HInstance = hInst
wc.HIcon = hIcon
wc.HCursor = hCursor
wc.HbrBackground = win.COLOR_BTNFACE + 1
wc.LpszClassName = syscall.StringToUTF16Ptr(className)
wc.Style = style
if atom := win.RegisterClassEx(&wc); atom == 0 {
panic("RegisterClassEx")
}
}