// 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
}
Beispiel #2
0
// 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
}
Beispiel #4
0
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
}
Beispiel #5
0
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))))
}
Beispiel #6
0
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)
}
Beispiel #7
0
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))))
}
Beispiel #8
0
//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()
}
Beispiel #9
0
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
}
Beispiel #10
0
// 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
}
Beispiel #11
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))
}