summaryrefslogtreecommitdiff
path: root/sysdata_windows.go
blob: 6711c91268762063746490526dbb4acc5d2f2f89 (plain)
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
// 11 february 2014
package main

import (
	"fmt"
	"syscall"
	"unsafe"
)

type sysData struct {
	cSysData

	hwnd			_HWND
	cid				_HMENU
	shownAlready		bool
}

type classData struct {
	name	uintptr
	style		uint32
	xstyle	uint32
}

//const controlstyle = _WS_CHILD | _WS_VISIBLE | _WS_TABSTOP
//const controlxstyle = 0

var classTypes = [nctypes]*classData{
	c_window:	&classData{
		name:	uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(stdWndClass))),
		style:	_WS_OVERLAPPEDWINDOW,
		xstyle:	0,
	},
//	c_button:		&classData{
//		name:	uintptr(unsafe.Pointer("BUTTON"))
//		style:	_BS_PUSHBUTTON | controlstyle,
//		xstyle:	0 | controlxstyle,
//	},
}

func (s *sysData) make() (err error) {
	ret := make(chan uiret)
	defer close(ret)
	ct := classTypes[s.ctype]
	uitask <- &uimsg{
		call:		_createWindowEx,	
		p:		[]uintptr{
			uintptr(ct.xstyle),
			ct.name,
			uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s.text))),
			uintptr(ct.style),
			uintptr(_CW_USEDEFAULT),		// TODO
			uintptr(_CW_USEDEFAULT),
			uintptr(_CW_USEDEFAULT),
			uintptr(_CW_USEDEFAULT),
			uintptr(_NULL),					// TODO parent
			uintptr(s.cid),
			uintptr(hInstance),
			uintptr(_NULL),
		},
		ret:	ret,
	}
	r := <-ret
	if r.err != nil {
		return r.err
	}
	s.hwnd = _HWND(r.ret)
	return nil
}

var (
	_updateWindow = user32.NewProc("UpdateWindow")
)

// if the object is a window, we need to do the following the first time
// 	ShowWindow(hwnd, nCmdShow);
// 	UpdateWindow(hwnd);
// otherwise we go ahead and show the object normally with SW_SHOW
func (s *sysData) show() (err error) {
	if s.ctype != c_window {		// don't do the init ShowWindow/UpdateWindow chain on non-windows
		s.shownAlready = true
	}
	show := uintptr(_SW_SHOW)
	if !s.shownAlready {
		show = uintptr(nCmdShow)
	}
	ret := make(chan uiret)
	defer close(ret)
	uitask <- &uimsg{
		call:		_showWindow,
		p:		[]uintptr{uintptr(s.hwnd), show},
		ret:		ret,
	}
	r := <-ret
	if r.err != nil {
		return r.err
	}
	if !s.shownAlready {
		uitask <- &uimsg{
			call:		_updateWindow,
			p:		[]uintptr{uintptr(s.hwnd)},
			ret:		ret,
		}
		r = <-ret
		if r.ret == 0 {		// failure
			return fmt.Errorf("error updating window for the first time: %v", r.err)
		}
		s.shownAlready = true
	}
	return nil
}

func (s *sysData) hide() (err error) {
	ret := make(chan uiret)
	defer close(ret)
	uitask <- &uimsg{
		call:		_showWindow,
		p:		[]uintptr{uintptr(s.hwnd), _SW_HIDE},
		ret:		ret,
	}
	r := <-ret
	close(ret)
	return r.err
}