Added combo boxes and added some to the main window example.
This commit is contained in:
parent
6ae896cd64
commit
e9f25362be
|
@ -0,0 +1,83 @@
|
|||
// 10 february 2014
|
||||
package main
|
||||
|
||||
import (
|
||||
// "syscall"
|
||||
// "unsafe"
|
||||
)
|
||||
|
||||
// Combobox styles.
|
||||
const (
|
||||
// from winuser.h
|
||||
CBS_SIMPLE = 0x0001
|
||||
CBS_DROPDOWN = 0x0002
|
||||
CBS_DROPDOWNLIST = 0x0003
|
||||
CBS_OWNERDRAWFIXED = 0x0010
|
||||
CBS_OWNERDRAWVARIABLE = 0x0020
|
||||
CBS_AUTOHSCROLL = 0x0040
|
||||
CBS_OEMCONVERT = 0x0080
|
||||
CBS_SORT = 0x0100
|
||||
CBS_HASSTRINGS = 0x0200
|
||||
CBS_NOINTEGRALHEIGHT = 0x0400
|
||||
CBS_DISABLENOSCROLL = 0x0800
|
||||
CBS_UPPERCASE = 0x2000
|
||||
CBS_LOWERCASE = 0x4000
|
||||
)
|
||||
|
||||
// Combobox messages.
|
||||
// TODO filter out messages not provided in windows 2000
|
||||
const (
|
||||
// from winuser.h
|
||||
CB_GETEDITSEL = 0x0140
|
||||
CB_LIMITTEXT = 0x0141
|
||||
CB_SETEDITSEL = 0x0142
|
||||
CB_ADDSTRING = 0x0143
|
||||
CB_DELETESTRING = 0x0144
|
||||
CB_DIR = 0x0145
|
||||
CB_GETCOUNT = 0x0146
|
||||
CB_GETCURSEL = 0x0147
|
||||
CB_GETLBTEXT = 0x0148
|
||||
CB_GETLBTEXTLEN = 0x0149
|
||||
CB_INSERTSTRING = 0x014A
|
||||
CB_RESETCONTENT = 0x014B
|
||||
CB_FINDSTRING = 0x014C
|
||||
CB_SELECTSTRING = 0x014D
|
||||
CB_SETCURSEL = 0x014E
|
||||
CB_SHOWDROPDOWN = 0x014F
|
||||
CB_GETITEMDATA = 0x0150
|
||||
CB_SETITEMDATA = 0x0151
|
||||
CB_GETDROPPEDCONTROLRECT = 0x0152
|
||||
CB_SETITEMHEIGHT = 0x0153
|
||||
CB_GETITEMHEIGHT = 0x0154
|
||||
CB_SETEXTENDEDUI = 0x0155
|
||||
CB_GETEXTENDEDUI = 0x0156
|
||||
CB_GETDROPPEDSTATE = 0x0157
|
||||
CB_FINDSTRINGEXACT = 0x0158
|
||||
CB_SETLOCALE = 0x0159
|
||||
CB_GETLOCALE = 0x015A
|
||||
CB_GETTOPINDEX = 0x015B
|
||||
CB_SETTOPINDEX = 0x015C
|
||||
CB_GETHORIZONTALEXTENT = 0x015D
|
||||
CB_SETHORIZONTALEXTENT = 0x015E
|
||||
CB_GETDROPPEDWIDTH = 0x015F
|
||||
CB_SETDROPPEDWIDTH = 0x0160
|
||||
CB_INITSTORAGE = 0x0161
|
||||
CB_MULTIPLEADDSTRING = 0x0163
|
||||
CB_GETCOMBOBOXINFO = 0x0164
|
||||
)
|
||||
|
||||
// Combobox WM_COMMAND notificaitons.
|
||||
const (
|
||||
// from winuser.h
|
||||
CBN_ERRSPACE = (-1) // TODO this will blow up the Go compiler if it's used
|
||||
CBN_SELCHANGE = 1
|
||||
CBN_DBLCLK = 2
|
||||
CBN_SETFOCUS = 3
|
||||
CBN_KILLFOCUS = 4
|
||||
CBN_EDITCHANGE = 5
|
||||
CBN_EDITUPDATE = 6
|
||||
CBN_DROPDOWN = 7
|
||||
CBN_CLOSEUP = 8
|
||||
CBN_SELENDOK = 9
|
||||
CBN_SELENDCANCEL = 10
|
||||
)
|
26
common.go
26
common.go
|
@ -3,8 +3,11 @@ package main
|
|||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// TODO filter out commctrl.h stuff because the combobox stuff has values that differ between windows versions and bleh
|
||||
|
||||
var (
|
||||
user32 = syscall.NewLazyDLL("user32.dll")
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
|
@ -37,7 +40,30 @@ func (w WPARAM) HIWORD() uint16 {
|
|||
return uint16((w >> 16) & 0xFFFF)
|
||||
}
|
||||
|
||||
func LPARAMFromString(str string) LPARAM {
|
||||
return LPARAM(unsafe.Pointer(syscall.StringToUTF16Ptr(str)))
|
||||
}
|
||||
|
||||
// microsoft's header files do this
|
||||
func MAKEINTRESOURCE(what uint16) uintptr {
|
||||
return uintptr(what)
|
||||
}
|
||||
|
||||
// TODO adorn error messages with which step failed?
|
||||
func getText(hwnd HWND) (text string, err error) {
|
||||
var tc []uint16
|
||||
|
||||
length, err := SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
tc = make([]uint16, length + 1)
|
||||
_, err = SendMessage(hwnd,
|
||||
WM_GETTEXT,
|
||||
WPARAM(length + 1),
|
||||
LPARAM(unsafe.Pointer(&tc[0])))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return syscall.UTF16ToString(tc), nil
|
||||
}
|
||||
|
|
72
main.go
72
main.go
|
@ -21,17 +21,47 @@ func fatalf(format string, args ...interface{}) {
|
|||
|
||||
const (
|
||||
IDC_BUTTON = 100
|
||||
IDC_VARCOMBO = 101
|
||||
IDC_FIXCOMBO = 102
|
||||
)
|
||||
|
||||
var varCombo, fixCombo HWND
|
||||
|
||||
func wndProc(hwnd HWND, msg uint32, wParam WPARAM, lParam LPARAM) LRESULT {
|
||||
switch msg {
|
||||
case WM_COMMAND:
|
||||
if wParam.LOWORD() == IDC_BUTTON {
|
||||
buttonclick := "neither clicked nor double clicked (somehow)"
|
||||
if wParam.HIWORD() == BN_CLICKED {
|
||||
MessageBox(hwnd, "clicked", "", MB_OK)
|
||||
buttonclick = "clicked"
|
||||
} else if wParam.HIWORD() == BN_DOUBLECLICKED {
|
||||
MessageBox(hwnd, "double clicked", "", MB_OK)
|
||||
buttonclick = "double clicked"
|
||||
}
|
||||
|
||||
varText, err := getText(varCombo)
|
||||
if err != nil {
|
||||
fatalf("error getting variable combo box text: %v", err)
|
||||
}
|
||||
|
||||
fixTextWM, err := getText(fixCombo)
|
||||
if err != nil {
|
||||
fatalf("error getting fixed combo box text with WM_GETTEXT: %v", err)
|
||||
}
|
||||
|
||||
fixTextIndex, err := SendMessage(fixCombo, CB_GETCURSEL, 0, 0)
|
||||
if err != nil {
|
||||
fatalf("error getting fixed combo box current selection: %v", err)
|
||||
}
|
||||
// TODO get text from index
|
||||
|
||||
MessageBox(hwnd,
|
||||
fmt.Sprintf("button state: %s\n" +
|
||||
"variable combo box text: %s\n" +
|
||||
"fixed combo box text with WM_GETTEXT: %s\n" +
|
||||
"fixed combo box current index: %d\n",
|
||||
buttonclick, varText, fixTextWM, fixTextIndex),
|
||||
"note",
|
||||
MB_OK)
|
||||
}
|
||||
return 0
|
||||
case WM_CLOSE:
|
||||
|
@ -103,12 +133,48 @@ func main() {
|
|||
0,
|
||||
"BUTTON", "Click Me",
|
||||
BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
|
||||
20, 20, 100, 100,
|
||||
20, 20, 100, 20,
|
||||
hwnd, HMENU(IDC_BUTTON), hInstance, NULL)
|
||||
if err != nil {
|
||||
fatalf("error creating button: %v", err)
|
||||
}
|
||||
|
||||
varCombo, err = CreateWindowEx(
|
||||
0,
|
||||
"COMBOBOX", "",
|
||||
CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
|
||||
140, 20, 100, 20,
|
||||
hwnd, HMENU(IDC_VARCOMBO), hInstance, NULL)
|
||||
if err != nil {
|
||||
fatalf("error creating variable combo box: %v", err)
|
||||
}
|
||||
vcItems := []string{"a", "b", "c", "d"}
|
||||
for _, v := range vcItems {
|
||||
_, err := SendMessage(varCombo, CB_ADDSTRING, 0,
|
||||
LPARAMFromString(v))
|
||||
if err != nil {
|
||||
fatalf("error adding %q to variable combo box: %v", v, err)
|
||||
}
|
||||
}
|
||||
|
||||
fixCombo, err = CreateWindowEx(
|
||||
0,
|
||||
"COMBOBOX", "",
|
||||
CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
|
||||
140, 50, 100, 20,
|
||||
hwnd, HMENU(IDC_FIXCOMBO), hInstance, NULL)
|
||||
if err != nil {
|
||||
fatalf("error creating fixed combo box: %v", err)
|
||||
}
|
||||
fcItems := []string{"e", "f", "g", "h"}
|
||||
for _, v := range fcItems {
|
||||
_, err := SendMessage(fixCombo, CB_ADDSTRING, 0,
|
||||
LPARAMFromString(v))
|
||||
if err != nil {
|
||||
fatalf("error adding %q to fixed combo box: %v", v, err)
|
||||
}
|
||||
}
|
||||
|
||||
_, err = ShowWindow(hwnd, nCmdShow)
|
||||
if err != nil {
|
||||
fatalf("error showing window: %v", err)
|
||||
|
|
16
messages.go
16
messages.go
|
@ -6,6 +6,11 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
// SendMessage constants.
|
||||
const (
|
||||
HWND_BROADCAST = HWND(0xFFFF)
|
||||
)
|
||||
|
||||
type MSG struct {
|
||||
Hwnd HWND
|
||||
Message uint32
|
||||
|
@ -19,6 +24,7 @@ var (
|
|||
dispatchMessage = user32.NewProc("DispatchMessageW")
|
||||
getMessage = user32.NewProc("GetMessageW")
|
||||
postQuitMessage = user32.NewProc("PostQuitMessage")
|
||||
sendMessage = user32.NewProc("SendMessageW")
|
||||
translateMessage = user32.NewProc("TranslateMessage")
|
||||
)
|
||||
|
||||
|
@ -49,6 +55,16 @@ func PostQuitMessage(nExitCode int) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
// TODO handle errors
|
||||
func SendMessage(hWnd HWND, Msg uint32, wParam WPARAM, lParam LPARAM) (result LRESULT, err error) {
|
||||
r1, _, _ := sendMessage.Call(
|
||||
uintptr(hWnd),
|
||||
uintptr(Msg),
|
||||
uintptr(wParam),
|
||||
uintptr(lParam))
|
||||
return LRESULT(r1), nil
|
||||
}
|
||||
|
||||
// TODO handle errors
|
||||
func TranslateMessage(lpMsg *MSG) (translated bool, err error) {
|
||||
r1, _, _ := translateMessage.Call(uintptr(unsafe.Pointer(lpMsg)))
|
||||
|
|
Loading…
Reference in New Issue