// Change the window's icon func (wi *windowInternal) setIcon(icon image.Image) error { // First destroy the previous one if wi.icon != nil { C.DestroyIcon(wi.icon) } type BGRA [4]uint8 // Windows wants BGRA pixels: swap red and blue channels Rect := icon.Bounds() iconPixels := make([]BGRA, Rect.Dy()*Rect.Dx()) for i, y := 0, 0; y < Rect.Dy(); y++ { for x := 0; x < Rect.Dx(); x++ { r, g, b, a := icon.At(x, y).RGBA() iconPixels[i][0] = uint8(b) iconPixels[i][1] = uint8(g) iconPixels[i][2] = uint8(r) iconPixels[i][3] = uint8(a) } } // Create the icon from the pixel array width, height := C.int(Rect.Dx()), C.int(Rect.Dy()) wi.icon = C.CreateIcon(C.GetModuleHandle(nil), width, height, 1, 32, nil, (*C.BYTE)(&iconPixels[0][0])) if wi.icon == nil { return fmt.Errorf("could not create icon (%d)", C.GetLastError()) } C.SendMessage(wi.window.Handle, C.WM_SETICON, C.ICON_BIG, C.LPARAM(uintptr(unsafe.Pointer(wi.icon)))) C.SendMessage(wi.window.Handle, C.WM_SETICON, C.ICON_SMALL, C.LPARAM(uintptr(unsafe.Pointer(wi.icon)))) return nil }
// an up-down control will only properly position itself the first time // stupidly, there are no messages to force a size calculation, nor can I seem to reset the buddy window to force a new position // alas, we have to make a new up/down control each time :( // TODO we'll need to store a copy of the current position and range for this func (s *spinbox) remakeUpDown() { // destroying the previous one, setting the parent properly, and subclassing are handled here s.hwndUpDown = C.newUpDown(s.hwndUpDown, unsafe.Pointer(s)) // for this to work, hwndUpDown needs to have rect [0 0 0 0] C.moveWindow(s.hwndUpDown, 0, 0, 0, 0) C.SendMessageW(s.hwndUpDown, C.UDM_SETBUDDY, C.WPARAM(uintptr(unsafe.Pointer(s.hwndEdit))), 0) C.SendMessageW(s.hwndUpDown, C.UDM_SETRANGE32, C.WPARAM(s.min), C.LPARAM(s.max)) C.SendMessageW(s.hwndUpDown, C.UDM_SETPOS32, 0, C.LPARAM(s.value)) if s.updownVisible { C.ShowWindow(s.hwndUpDown, C.SW_SHOW) } }
func findMonitors() *monitorInternalFinder { m := &monitorInternalFinder{} C.EnumDisplayMonitors(nil, nil, C.pEnumMonitors, C.LPARAM(uintptr(unsafe.Pointer(m)))) return m }
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 (i *imagelist) apply(hwnd C.HWND, uMsg C.UINT) { width := C.GetSystemMetrics(C.SM_CXSMICON) height := C.GetSystemMetrics(C.SM_CYSMICON) il := C.newImageList(width, height) for index := range i.list { C.addImage(il, hwnd, i.list[index], C.int(i.width[index]), C.int(i.height[index]), width, height) } C.SendMessageW(hwnd, uMsg, 0, C.LPARAM(uintptr(unsafe.Pointer(il)))) }
func (b *button) preferredSize(d *sizing) (width, height int) { // comctl32.dll version 6 thankfully provides a method to grab this... var size C.SIZE size.cx = 0 // explicitly ask for ideal size size.cy = 0 if C.SendMessageW(b._hwnd, C.BCM_GETIDEALSIZE, 0, C.LPARAM(uintptr(unsafe.Pointer(&size)))) != C.FALSE { return int(size.cx), int(size.cy) } // that failed, fall back println("message failed; falling back") // don't worry about the error return from GetSystemMetrics(); there's no way to tell (explicitly documented as such) xmargins := 2 * int(C.GetSystemMetrics(C.SM_CXEDGE)) return xmargins + int(b._textlen), fromdlgunitsY(buttonHeight, d) }
func (a *area) Repaint(r image.Rectangle) { var hscroll, vscroll C.int var rect C.RECT C.SendMessageW(a.hwnd, C.msgAreaGetScroll, C.WPARAM(uintptr(unsafe.Pointer(&hscroll))), C.LPARAM(uintptr(unsafe.Pointer(&vscroll)))) r = r.Add(image.Pt(int(hscroll), int(vscroll))) // adjust by scroll position r = image.Rect(0, 0, a.width, a.height).Intersect(r) if r.Empty() { return } rect.left = C.LONG(r.Min.X) rect.top = C.LONG(r.Min.Y) rect.right = C.LONG(r.Max.X) rect.bottom = C.LONG(r.Max.Y) C.SendMessageW(a.hwnd, C.msgAreaRepaint, 0, C.LPARAM(uintptr(unsafe.Pointer(&rect)))) }
//export spinboxEditChanged func spinboxEditChanged(data unsafe.Pointer) { // we're basically on our own here s := (*spinbox)(unsafe.Pointer(data)) // this basically does what OS X does: values too low get clamped to the minimum, values too high get clamped to the maximum, and deleting everything clamps to the minimum value, err := strconv.Atoi(getWindowText(s.hwndEdit)) if err != nil { // best we can do fo rnow in this case :S // a partial atoi() like in C would be more optimal // it handles the deleting everything case just fine value = s.min } s.value = value s.cap() C.SendMessageW(s.hwndUpDown, C.UDM_SETPOS32, 0, C.LPARAM(s.value)) // TODO position the insertion caret at the end (or wherever is appropriate) s.changed.fire() }
func ProcND(hwnd win.HWND, msg uint, wParam uintptr, lParam uintptr) (ret int, handled bool) { var bHandled C.BOOL // ret = uintptr(syssciterProcND(HWND(hwnd), msg, wParam, lParam, &bHandled)) ret = int(C.SciterProcND(C.HWINDOW(unsafe.Pointer(hwnd)), C.UINT(msg), C.WPARAM(wParam), C.LPARAM(lParam), &bHandled)) if bHandled == 0 { handled = false } else { handled = true } return }
// Main htmlayout wndproc func ProcNoDefault(hwnd, msg uint32, wparam, lparam uintptr) (uintptr, bool) { var handled C.BOOL = 0 var result C.LRESULT = C.HTMLayoutProcND(C.HWND(C.HANDLE(uintptr(hwnd))), C.UINT(msg), C.WPARAM(wparam), C.LPARAM(lparam), &handled) return uintptr(result), handled != 0 }
func (s *spinbox) SetValue(value int) { // UDM_SETPOS32 is documented to do what we want, but since we're keeping a copy of value we need to do it anyway s.value = value s.cap() C.SendMessageW(s.hwndUpDown, C.UDM_SETPOS32, 0, C.LPARAM(s.value)) }