This repository has been archived by the owner on Jun 3, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 44
/
list_windows.go
120 lines (100 loc) · 3.42 KB
/
list_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
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
// +build windows,!linux,!darwin,!js
package dlgs
import (
"strings"
"syscall"
"unsafe"
)
// List displays a list dialog, returning the selected value and a bool for success.
func List(title, text string, items []string) (string, bool, error) {
return listBox(title, text, "ClassList", items, false)
}
// ListMulti displays a multiple list dialog, returning the selected values and a bool for success.
func ListMulti(title, text string, items []string) ([]string, bool, error) {
out, ok, err := listBox(title, text, "ClassListMulti", items, true)
return strings.Split(out, lbSeparator), ok, err
}
// listBox displays list dialog.
func listBox(title, text, className string, items []string, multi bool) (string, bool, error) {
var out string
notCancledOrClosed := true
var hwndList syscall.Handle
instance, err := getModuleHandle()
if err != nil {
return out, false, err
}
fn := func(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) uintptr {
switch msg {
case wmClose:
notCancledOrClosed = false
destroyWindow(hwnd)
case wmDestroy:
postQuitMessage(0)
case wmKeydown:
if wparam == vkEscape {
notCancledOrClosed = false
destroyWindow(hwnd)
}
case wmCommand:
if wparam == 100 {
if multi {
selCount := int(sendMessage(hwndList, lbGetSelCount, 0, 0))
selItems := make([]int32, selCount)
sendMessage(hwndList, lbGetSelItems, uintptr(selCount), uintptr(unsafe.Pointer(&selItems[0])))
for i, idx := range selItems {
out += items[idx]
if i != len(selItems)-1 {
out += lbSeparator
}
}
} else {
i := int(sendMessage(hwndList, lbGetCurSel, 0, 0))
if i >= 0 {
out = items[i]
}
}
destroyWindow(hwnd)
} else if wparam == 110 {
notCancledOrClosed = false
destroyWindow(hwnd)
}
default:
ret := defWindowProc(hwnd, msg, wparam, lparam)
return ret
}
return 0
}
err = registerClass(className, instance, fn)
if err != nil {
return out, false, err
}
defer unregisterClass(className, instance)
hwnd, _ := createWindow(0, className, title, wsOverlappedWindow, swUseDefault, swUseDefault, 235, 300, 0, 0, instance)
hwndText, _ := createWindow(0, "STATIC", text, wsChild|wsVisible, 10, 10, 200, 16, hwnd, 0, instance)
flags := wsBorder | wsChild | wsVisible | wsGroup | wsTabStop | esAutoVScroll
if multi {
flags |= lbsExtendedsel
}
hwndList, _ = createWindow(wsExClientEdge, "LISTBOX", title, uint64(flags), 10, 30, 200, 200, hwnd, 0, instance)
hwndOK, _ := createWindow(wsExClientEdge, "BUTTON", "OK", wsChild|wsVisible|bsPushButton|wsGroup|wsTabStop, 10, 230, 90, 24, hwnd, 100, instance)
hwndCancel, _ := createWindow(wsExClientEdge, "BUTTON", "Cancel", wsChild|wsVisible|bsPushButton|wsGroup|wsTabStop, 120, 230, 90, 24, hwnd, 110, instance)
setWindowLong(hwnd, gwlStyle, getWindowLong(hwnd, gwlStyle)^wsMinimizeBox)
setWindowLong(hwnd, gwlStyle, getWindowLong(hwnd, gwlStyle)^wsMaximizeBox)
font := getMessageFont()
sendMessage(hwndText, wmSetFont, font, 0)
sendMessage(hwndList, wmSetFont, font, 0)
sendMessage(hwndOK, wmSetFont, font, 0)
sendMessage(hwndCancel, wmSetFont, font, 0)
centerWindow(hwnd)
for _, item := range items {
i, _ := syscall.UTF16PtrFromString(item)
sendMessage(hwndList, lbAddString, 0, uintptr(unsafe.Pointer(i)))
}
showWindow(hwnd, swShowNormal)
updateWindow(hwnd)
err = messageLoop(hwnd)
if err != nil {
return out, false, err
}
return out, notCancledOrClosed, nil
}