func finishNewTable(b *tablebase, ty reflect.Type) Table { hwnd := C.newControl(C.xtableWindowClass, C.WS_HSCROLL|C.WS_VSCROLL|C.WS_TABSTOP, C.WS_EX_CLIENTEDGE) // WS_EX_CLIENTEDGE without WS_BORDER will show the canonical visual styles border (thanks to MindChild in irc.efnet.net/#winprog) t := &table{ controlSingleHWND: newControlSingleHWND(hwnd), tablebase: b, selected: newEvent(), free: make(map[C.uintptr_t]bool), } t.fpreferredSize = t.xpreferredSize t.chainresize = t.fresize t.fresize = t.xresize C.setTableSubclass(t.hwnd, unsafe.Pointer(t)) // TODO listview didn't need this; someone mentioned (TODO) it uses the small caption font??? C.controlSetControlFont(t.hwnd) for i := 0; i < ty.NumField(); i++ { coltype := C.WPARAM(C.tableColumnText) switch { case ty.Field(i).Type == reflect.TypeOf((*image.RGBA)(nil)): coltype = C.tableColumnImage case ty.Field(i).Type.Kind() == reflect.Bool: coltype = C.tableColumnCheckbox } colname := ty.Field(i).Tag.Get("uicolumn") if colname == "" { colname = ty.Field(i).Name } ccolname := toUTF16(colname) C.SendMessageW(t.hwnd, C.tableAddColumn, coltype, C.LPARAM(uintptr(unsafe.Pointer(ccolname)))) // TODO free ccolname } t.colcount = C.int(ty.NumField()) return t }
func newTab() Tab { hwnd := C.newControl(C.xWC_TABCONTROL, C.TCS_TOOLTIPS|C.WS_TABSTOP, 0) t := &tab{ _hwnd: hwnd, } C.controlSetControlFont(t._hwnd) C.setTabSubclass(t._hwnd, unsafe.Pointer(t)) return t }
func newTab() Tab { hwnd := C.newControl(C.xWC_TABCONTROL, C.TCS_TOOLTIPS|C.WS_TABSTOP, 0) // don't set WS_EX_CONTROLPARENT here; see uitask_windows.c t := &tab{ _hwnd: hwnd, } C.controlSetControlFont(t._hwnd) C.setTabSubclass(t._hwnd, unsafe.Pointer(t)) return t }
func startNewTextField(style C.DWORD) *textfield { hwnd := C.newControl(editclass, style|C.textfieldStyle, C.textfieldExtStyle) // WS_EX_CLIENTEDGE without WS_BORDER will show the canonical visual styles border (thanks to MindChild in irc.efnet.net/#winprog) t := &textfield{ _hwnd: hwnd, changed: newEvent(), } C.controlSetControlFont(t._hwnd) C.setTextFieldSubclass(t._hwnd, unsafe.Pointer(t)) return t }
func newButton(text string) *button { hwnd := C.newControl(buttonclass, C.BS_PUSHBUTTON|C.WS_TABSTOP, 0) b := &button{ _hwnd: hwnd, clicked: newEvent(), } b.SetText(text) C.controlSetControlFont(b._hwnd) C.setButtonSubclass(b._hwnd, unsafe.Pointer(b)) return b }
// TODO autohide scrollbars func newTextbox() Textbox { hwnd := C.newControl(editclass, // TODO ES_AUTOHSCROLL/ES_AUTOVSCROLL as well? // TODO word wrap C.ES_LEFT|C.ES_MULTILINE|C.ES_NOHIDESEL|C.ES_WANTRETURN|C.WS_HSCROLL|C.WS_VSCROLL, C.WS_EX_CLIENTEDGE) t := &textbox{ controlSingleHWNDWithText: newControlSingleHWNDWithText(hwnd), } t.fpreferredSize = t.xpreferredSize C.controlSetControlFont(t.hwnd) return t }
func newGroup(text string, control Control) Group { hwnd := C.newControl(buttonclass, C.BS_GROUPBOX, C.WS_EX_CONTROLPARENT) g := &group{ _hwnd: hwnd, container: newContainer(control), } g.SetText(text) C.controlSetControlFont(g._hwnd) g.container.setParent(g._hwnd) g.container.isGroup = true return g }
func finishNewLabel(text string, standalone bool) *label { hwnd := C.newControl(labelclass, // SS_NOPREFIX avoids accelerator translation; SS_LEFTNOWORDWRAP clips text past the end // controls are vertically aligned to the top by default (thanks Xeek in irc.freenode.net/#winapi) C.SS_NOPREFIX|C.SS_LEFTNOWORDWRAP, C.WS_EX_TRANSPARENT) l := &label{ _hwnd: hwnd, standalone: standalone, } l.SetText(text) C.controlSetControlFont(l._hwnd) return l }
func newProgressBar() ProgressBar { hwnd := C.newControl(C.xPROGRESS_CLASS, C.PBS_SMOOTH, 0) p := &progressbar{ controlSingleHWND: newControlSingleHWND(hwnd), } p.fpreferredSize = p.xpreferredSize p.fnTabStops = func() int { // progress bars are not tab stops return 0 } return p }
func newButton(text string) *button { hwnd := C.newControl(buttonclass, C.BS_PUSHBUTTON|C.WS_TABSTOP, 0) b := &button{ controlSingleHWNDWithText: newControlSingleHWNDWithText(hwnd), clicked: newEvent(), } b.fpreferredSize = b.xpreferredSize b.SetText(text) C.controlSetControlFont(b.hwnd) C.setButtonSubclass(b.hwnd, unsafe.Pointer(b)) return b }
func newTab() Tab { hwnd := C.newControl(C.xWC_TABCONTROL, C.TCS_TOOLTIPS|C.WS_TABSTOP, 0) // don't set WS_EX_CONTROLPARENT here; see uitask_windows.c t := &tab{ controlSingleHWND: newControlSingleHWND(hwnd), } t.fpreferredSize = t.xpreferredSize t.chainresize = t.fresize t.fresize = t.xresize // count tabs as 1 tab stop; the actual number of tab stops varies C.controlSetControlFont(t.hwnd) C.setTabSubclass(t.hwnd, unsafe.Pointer(t)) return t }
func newSpinbox(min int, max int) Spinbox { s := new(spinbox) s.hwndEdit = C.newControl(editclass, C.textfieldStyle|C.ES_NUMBER, C.textfieldExtStyle) s.changed = newEvent() s.updownVisible = true // initially shown s.min = min s.max = max s.value = s.min s.remakeUpDown() C.controlSetControlFont(s.hwndEdit) C.setSpinboxEditSubclass(s.hwndEdit, unsafe.Pointer(s)) return s }
func newCheckbox(text string) *checkbox { // don't use BS_AUTOCHECKBOX here because it creates problems when refocusing (see http://blogs.msdn.com/b/oldnewthing/archive/2014/05/22/10527522.aspx) // we'll handle actually toggling the check state ourselves (see controls_windows.c) hwnd := C.newControl(buttonclass, C.BS_CHECKBOX|C.WS_TABSTOP, 0) c := &checkbox{ _hwnd: hwnd, toggled: newEvent(), } c.SetText(text) C.controlSetControlFont(c._hwnd) C.setCheckboxSubclass(c._hwnd, unsafe.Pointer(c)) return c }
func newGroup(text string, control Control) Group { hwnd := C.newControl(buttonclass, C.BS_GROUPBOX, C.WS_EX_CONTROLPARENT) g := &group{ controlSingleHWNDWithText: newControlSingleHWNDWithText(hwnd), child: control, } g.fpreferredSize = g.xpreferredSize g.fnTabStops = control.nTabStops // groupbox itself is not tabbable but the contents might be g.SetText(text) C.controlSetControlFont(g.hwnd) C.setGroupSubclass(g.hwnd, unsafe.Pointer(g)) control.setParent(&controlParent{g.hwnd}) return g }
func newLabel(text string) Label { hwnd := C.newControl(labelclass, // SS_NOPREFIX avoids accelerator translation; SS_LEFTNOWORDWRAP clips text past the end // controls are vertically aligned to the top by default (thanks Xeek in irc.freenode.net/#winapi) C.SS_NOPREFIX|C.SS_LEFTNOWORDWRAP, C.WS_EX_TRANSPARENT) l := &label{ controlSingleHWNDWithText: newControlSingleHWNDWithText(hwnd), } l.fpreferredSize = l.xpreferredSize l.fnTabStops = func() int { // labels are not tab stops return 0 } l.SetText(text) C.controlSetControlFont(l.hwnd) return l }
func finishNewTable(b *tablebase, ty reflect.Type) Table { t := &table{ _hwnd: C.newControl(C.xWC_LISTVIEW, C.LVS_REPORT|C.LVS_OWNERDATA|C.LVS_NOSORTHEADER|C.LVS_SHOWSELALWAYS|C.LVS_SINGLESEL|C.WS_HSCROLL|C.WS_VSCROLL|C.WS_TABSTOP, C.WS_EX_CLIENTEDGE), // WS_EX_CLIENTEDGE without WS_BORDER will show the canonical visual styles border (thanks to MindChild in irc.efnet.net/#winprog) tablebase: b, hotrow: -1, hotcol: -1, pushedrow: -1, pushedcol: -1, selected: newEvent(), } C.setTableSubclass(t._hwnd, unsafe.Pointer(t)) // LVS_EX_FULLROWSELECT gives us selection across the whole row, not just the leftmost column; this makes the list view work like on other platforms // LVS_EX_SUBITEMIMAGES gives us images in subitems, which will be important when both images and checkboxes are added C.tableAddExtendedStyles(t._hwnd, C.LVS_EX_FULLROWSELECT|C.LVS_EX_SUBITEMIMAGES) // this must come after the subclass because it uses one of our private messages C.SendMessageW(t._hwnd, C.msgTableMakeInitialCheckboxImageList, 0, 0) for i := 0; i < ty.NumField(); i++ { C.tableAppendColumn(t._hwnd, C.int(i), toUTF16(ty.Field(i).Name)) } t.colcount = C.int(ty.NumField()) return t }