2014-02-07 20:17:24 -06:00
|
|
|
// 7 february 2014
|
|
|
|
package main
|
|
|
|
|
2014-02-11 17:57:03 -06:00
|
|
|
//+build skip
|
|
|
|
|
2014-02-09 13:59:37 -06:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"runtime"
|
|
|
|
)
|
|
|
|
|
|
|
|
func fatalf(format string, args ...interface{}) {
|
|
|
|
s := fmt.Sprintf(format, args...)
|
|
|
|
_, err := MessageBox(NULL,
|
|
|
|
"An internal error has occured:\n" + s,
|
|
|
|
os.Args[0],
|
|
|
|
MB_OK | MB_ICONERROR)
|
|
|
|
if err == nil {
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
panic(fmt.Sprintf("error trying to warn user of internal error: %v\ninternal error:\n%s", err, s))
|
|
|
|
}
|
|
|
|
|
2014-02-10 03:59:39 -06:00
|
|
|
const (
|
2014-02-10 14:23:09 -06:00
|
|
|
IDC_BUTTON = 100 + iota
|
|
|
|
IDC_VARCOMBO
|
|
|
|
IDC_FIXCOMBO
|
|
|
|
IDC_EDIT
|
2014-02-10 15:00:11 -06:00
|
|
|
IDC_LIST
|
2014-02-10 16:02:54 -06:00
|
|
|
IDC_LABEL
|
2014-02-10 16:10:47 -06:00
|
|
|
IDC_CHECK
|
2014-02-10 03:59:39 -06:00
|
|
|
)
|
|
|
|
|
2014-02-10 15:00:11 -06:00
|
|
|
var varCombo, fixCombo, edit, list HWND
|
2014-02-10 11:44:11 -06:00
|
|
|
|
2014-02-10 03:59:39 -06:00
|
|
|
func wndProc(hwnd HWND, msg uint32, wParam WPARAM, lParam LPARAM) LRESULT {
|
2014-02-09 15:40:53 -06:00
|
|
|
switch msg {
|
2014-02-10 03:59:39 -06:00
|
|
|
case WM_COMMAND:
|
|
|
|
if wParam.LOWORD() == IDC_BUTTON {
|
2014-02-10 11:44:11 -06:00
|
|
|
buttonclick := "neither clicked nor double clicked (somehow)"
|
2014-02-10 03:59:39 -06:00
|
|
|
if wParam.HIWORD() == BN_CLICKED {
|
2014-02-10 11:44:11 -06:00
|
|
|
buttonclick = "clicked"
|
2014-02-10 03:59:39 -06:00
|
|
|
} else if wParam.HIWORD() == BN_DOUBLECLICKED {
|
2014-02-10 11:44:11 -06:00
|
|
|
buttonclick = "double clicked"
|
|
|
|
}
|
|
|
|
|
|
|
|
varText, err := getText(varCombo)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error getting variable combo box text: %v", err)
|
2014-02-10 03:59:39 -06:00
|
|
|
}
|
2014-02-10 11:44:11 -06:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2014-02-10 14:23:09 -06:00
|
|
|
editText, err := getText(edit)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error getting edit field text: %v", err)
|
|
|
|
}
|
|
|
|
|
2014-02-10 15:00:11 -06:00
|
|
|
listIndex, err := SendMessage(list, LB_GETCURSEL, 0, 0)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error getting fixed list box current selection: %v", err)
|
|
|
|
}
|
|
|
|
// TODO get text from index
|
|
|
|
|
2014-02-10 16:10:47 -06:00
|
|
|
checkState, err := IsDlgButtonChecked(hwnd, IDC_CHECK)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error getting checkbox check state: %v", err)
|
|
|
|
}
|
|
|
|
|
2014-02-10 11:44:11 -06:00
|
|
|
MessageBox(hwnd,
|
|
|
|
fmt.Sprintf("button state: %s\n" +
|
|
|
|
"variable combo box text: %s\n" +
|
|
|
|
"fixed combo box text with WM_GETTEXT: %s\n" +
|
2014-02-10 14:23:09 -06:00
|
|
|
"fixed combo box current index: %d\n" +
|
2014-02-10 15:00:11 -06:00
|
|
|
"edit field text: %s\n" +
|
2014-02-10 16:10:47 -06:00
|
|
|
"list box current index: %d\n" +
|
|
|
|
"check box checked: %v\n",
|
|
|
|
buttonclick, varText, fixTextWM, fixTextIndex, editText, listIndex, checkState == BST_CHECKED),
|
2014-02-10 11:44:11 -06:00
|
|
|
"note",
|
|
|
|
MB_OK)
|
2014-02-10 03:59:39 -06:00
|
|
|
}
|
|
|
|
return 0
|
2014-02-11 06:50:00 -06:00
|
|
|
case WM_GETMINMAXINFO:
|
|
|
|
mm := lParam.MINMAXINFO()
|
|
|
|
mm.PtMinTrackSize.X = 320
|
|
|
|
mm.PtMinTrackSize.Y = 240
|
|
|
|
return 0
|
2014-02-11 08:43:18 -06:00
|
|
|
case WM_SIZE:
|
|
|
|
if wParam != SIZE_MINIMIZED {
|
|
|
|
resize(hwnd)
|
|
|
|
}
|
|
|
|
return 0
|
2014-02-09 15:40:53 -06:00
|
|
|
case WM_CLOSE:
|
|
|
|
err := DestroyWindow(hwnd)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error destroying window: %v", err)
|
|
|
|
}
|
|
|
|
return 0
|
|
|
|
case WM_DESTROY:
|
|
|
|
err := PostQuitMessage(0)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error posting quit message: %v", err)
|
|
|
|
}
|
|
|
|
return 0
|
|
|
|
default:
|
2014-02-10 03:59:39 -06:00
|
|
|
return DefWindowProc(hwnd, msg, wParam, lParam)
|
2014-02-09 15:40:53 -06:00
|
|
|
}
|
|
|
|
fatalf("major bug: forgot a return on wndProc for message %d", msg)
|
|
|
|
panic("unreachable")
|
|
|
|
}
|
|
|
|
|
2014-02-10 19:48:08 -06:00
|
|
|
func setFontAll(hwnd HWND, lParam LPARAM) (cont bool) {
|
|
|
|
_, err := SendMessage(hwnd, WM_SETFONT, WPARAM(lParam), LPARAM(TRUE))
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error setting window font: %v", err)
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2014-02-11 08:43:18 -06:00
|
|
|
func resize(hwnd HWND) {
|
|
|
|
cr, err := GetClientRect(hwnd)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error getting window client rect: %v", err)
|
|
|
|
}
|
|
|
|
cr.Bottom -= 80 // Y position of listbox
|
|
|
|
cr.Bottom -= 20 // amount of pixels to leave behind
|
|
|
|
err = SetWindowPos(list,
|
|
|
|
HWND_TOP,
|
|
|
|
20, 80, 100, int(cr.Bottom),
|
|
|
|
0)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error resizing listbox: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-09 13:59:37 -06:00
|
|
|
const className = "mainwin"
|
2014-02-07 20:17:24 -06:00
|
|
|
|
|
|
|
func main() {
|
2014-02-09 13:59:37 -06:00
|
|
|
runtime.LockOSThread()
|
|
|
|
|
|
|
|
hInstance, err := getWinMainhInstance()
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error getting WinMain hInstance: %v", err)
|
|
|
|
}
|
|
|
|
nCmdShow, err := getWinMainnCmdShow()
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error getting WinMain nCmdShow: %v", err)
|
|
|
|
}
|
2014-02-10 19:48:08 -06:00
|
|
|
font, err := getStandardWindowFont()
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error getting standard window font: %v", err)
|
|
|
|
}
|
2014-02-09 13:59:37 -06:00
|
|
|
|
|
|
|
icon, err := LoadIcon_ResourceID(NULL, IDI_APPLICATION)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error getting window icon: %v", err)
|
|
|
|
}
|
|
|
|
cursor, err := LoadCursor_ResourceID(NULL, IDC_ARROW)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error getting window cursor: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
wc := &WNDCLASS{
|
|
|
|
LpszClassName: className,
|
2014-02-09 15:40:53 -06:00
|
|
|
LpfnWndProc: wndProc,
|
2014-02-09 13:59:37 -06:00
|
|
|
HInstance: hInstance,
|
|
|
|
HIcon: icon,
|
|
|
|
HCursor: cursor,
|
2014-02-10 19:48:08 -06:00
|
|
|
HbrBackground: HBRUSH(COLOR_BTNFACE + 1),
|
2014-02-09 13:59:37 -06:00
|
|
|
}
|
|
|
|
_, err = RegisterClass(wc)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error registering window class: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
hwnd, err := CreateWindowEx(
|
2014-02-10 19:48:08 -06:00
|
|
|
0,
|
2014-02-09 13:59:37 -06:00
|
|
|
className, "Main Window",
|
|
|
|
WS_OVERLAPPEDWINDOW,
|
|
|
|
CW_USEDEFAULT, CW_USEDEFAULT, 320, 240,
|
|
|
|
NULL, NULL, hInstance, NULL)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error creating window: %v", err)
|
|
|
|
}
|
|
|
|
|
2014-02-10 14:23:09 -06:00
|
|
|
const controlStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP
|
|
|
|
|
2014-02-10 03:59:39 -06:00
|
|
|
_, err = CreateWindowEx(
|
|
|
|
0,
|
|
|
|
"BUTTON", "Click Me",
|
2014-02-10 14:23:09 -06:00
|
|
|
BS_PUSHBUTTON | controlStyle,
|
2014-02-10 11:44:11 -06:00
|
|
|
20, 20, 100, 20,
|
2014-02-10 03:59:39 -06:00
|
|
|
hwnd, HMENU(IDC_BUTTON), hInstance, NULL)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error creating button: %v", err)
|
|
|
|
}
|
|
|
|
|
2014-02-10 11:44:11 -06:00
|
|
|
varCombo, err = CreateWindowEx(
|
|
|
|
0,
|
|
|
|
"COMBOBOX", "",
|
2014-02-10 14:23:09 -06:00
|
|
|
CBS_DROPDOWN | CBS_AUTOHSCROLL | controlStyle,
|
2014-02-10 11:44:11 -06:00
|
|
|
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", "",
|
2014-02-10 14:23:09 -06:00
|
|
|
CBS_DROPDOWNLIST | controlStyle,
|
2014-02-10 11:44:11 -06:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-10 14:23:09 -06:00
|
|
|
edit, err = CreateWindowEx(
|
|
|
|
0,
|
|
|
|
"EDIT", "",
|
|
|
|
ES_AUTOHSCROLL | ES_NOHIDESEL | WS_BORDER | controlStyle,
|
|
|
|
20, 50, 100, 20,
|
|
|
|
hwnd, HMENU(IDC_EDIT), hInstance, NULL)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error creating edit field: %v", err)
|
|
|
|
}
|
|
|
|
|
2014-02-10 15:00:11 -06:00
|
|
|
list, err = CreateWindowEx(
|
|
|
|
0,
|
|
|
|
"LISTBOX", "",
|
|
|
|
LBS_STANDARD | controlStyle,
|
|
|
|
20, 80, 100, 100,
|
|
|
|
hwnd, HMENU(IDC_FIXCOMBO), hInstance, NULL)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error creating list box: %v", err)
|
|
|
|
}
|
|
|
|
lItems := []string{"i", "j", "k", "l"}
|
|
|
|
for _, v := range lItems {
|
|
|
|
_, err := SendMessage(list, LB_ADDSTRING, 0,
|
|
|
|
LPARAMFromString(v))
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error adding %q to list box: %v", v, err)
|
|
|
|
}
|
|
|
|
// TODO check actual return value as THAT indicates an error
|
|
|
|
}
|
|
|
|
|
2014-02-10 16:02:54 -06:00
|
|
|
_, err = CreateWindowEx(
|
|
|
|
0,
|
|
|
|
"STATIC", "Label",
|
|
|
|
SS_NOPREFIX | controlStyle,
|
|
|
|
140, 80, 100, 20,
|
|
|
|
hwnd, HMENU(IDC_FIXCOMBO), hInstance, NULL)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error creating label: %v", err)
|
|
|
|
}
|
|
|
|
|
2014-02-10 16:10:47 -06:00
|
|
|
_, err = CreateWindowEx(
|
|
|
|
0,
|
|
|
|
"BUTTON", "Checkbox",
|
|
|
|
BS_AUTOCHECKBOX | controlStyle,
|
|
|
|
140, 110, 100, 20,
|
|
|
|
hwnd, HMENU(IDC_CHECK), hInstance, NULL)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error creating checkbox: %v", err)
|
|
|
|
}
|
|
|
|
|
2014-02-10 19:48:08 -06:00
|
|
|
setFontAll(hwnd, LPARAM(font))
|
|
|
|
err = EnumChildWindows(hwnd, setFontAll, LPARAM(font))
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error setting font on controls: %v", err)
|
|
|
|
}
|
2014-02-11 08:43:18 -06:00
|
|
|
resize(hwnd)
|
2014-02-10 19:48:08 -06:00
|
|
|
|
2014-02-09 13:59:37 -06:00
|
|
|
_, err = ShowWindow(hwnd, nCmdShow)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error showing window: %v", err)
|
|
|
|
}
|
|
|
|
err = UpdateWindow(hwnd)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error updating window: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for {
|
|
|
|
msg, done, err := GetMessage(NULL, 0, 0)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error getting message: %v", err)
|
|
|
|
}
|
|
|
|
if done {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
_, err = TranslateMessage(msg)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error translating message: %v", err)
|
|
|
|
}
|
|
|
|
_, err = DispatchMessage(msg)
|
|
|
|
if err != nil {
|
|
|
|
fatalf("error dispatching message: %v", err)
|
|
|
|
}
|
|
|
|
}
|
2014-02-07 20:17:24 -06:00
|
|
|
}
|
|
|
|
|