-
Notifications
You must be signed in to change notification settings - Fork 1
/
hr_windows.go
95 lines (81 loc) · 2.21 KB
/
hr_windows.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
package goey
import (
"syscall"
"unsafe"
"bitbucket.org/rj/goey/base"
"github.com/lxn/win"
)
var (
hr struct {
className []uint16
atom win.ATOM
}
)
func init() {
hr.className = []uint16{'G', 'o', 'e', 'y', 'H', 'R', 0}
}
func registerHRClass(hInst win.HINSTANCE, wndproc uintptr) (win.ATOM, error) {
var wc win.WNDCLASSEX
wc.CbSize = uint32(unsafe.Sizeof(wc))
wc.HInstance = hInst
wc.LpfnWndProc = wndproc
wc.HCursor = win.LoadCursor(0, (*uint16)(unsafe.Pointer(uintptr(win.IDC_ARROW))))
wc.HbrBackground = (win.HBRUSH)(win.GetStockObject(win.NULL_BRUSH))
wc.LpszClassName = &hr.className[0]
atom := win.RegisterClassEx(&wc)
if atom == 0 {
return 0, syscall.GetLastError()
}
return atom, nil
}
func (w *HR) mount(parent base.Control) (base.Element, error) {
hInstance := win.GetModuleHandle(nil)
if hInstance == 0 {
return nil, syscall.GetLastError()
}
if hr.atom == 0 {
atom, err := registerHRClass(hInstance, syscall.NewCallback(hrWindowProc))
if err != nil {
return nil, err
}
hr.atom = atom
}
hwnd := win.CreateWindowEx(0, &hr.className[0], nil, win.WS_CHILD|win.WS_VISIBLE,
10, 10, 100, 100,
parent.HWnd, 0, 0, nil)
if hwnd == 0 {
err := syscall.GetLastError()
if err == nil {
return nil, syscall.EINVAL
}
return nil, err
}
retval := &hrElement{Control: Control{hwnd}}
win.SetWindowLongPtr(hwnd, win.GWLP_USERDATA, uintptr(unsafe.Pointer(retval)))
return retval, nil
}
type hrElement struct {
Control
}
func hrWindowProc(hwnd win.HWND, msg uint32, wParam uintptr, lParam uintptr) (result uintptr) {
switch msg {
case win.WM_DESTROY:
// Make sure that the data structure on the Go-side does not point to a non-existent
// window.
if w := win.GetWindowLongPtr(hwnd, win.GWLP_USERDATA); w != 0 {
ptr := (*hrElement)(unsafe.Pointer(w))
ptr.hWnd = 0
}
// Defer to the old window proc
case win.WM_PAINT:
ps := win.PAINTSTRUCT{}
rect := win.RECT{}
hdc := win.BeginPaint(hwnd, &ps)
win.SetBkMode(hdc, win.TRANSPARENT)
win.GetClientRect(hwnd, &rect)
win.MoveToEx(hdc, int(rect.Left), int(rect.Top+rect.Bottom)/2, nil)
win.LineTo(hdc, rect.Right, (rect.Top+rect.Bottom)/2)
win.EndPaint(hwnd, &ps)
}
return win.DefWindowProc(hwnd, msg, wParam, lParam)
}