예제 #1
0
파일: toolbar.go 프로젝트: kumakichi/walk
func (tb *ToolBar) SizeHint() Size {
	if tb.actions.Len() == 0 {
		return Size{}
	}

	size := uint32(tb.SendMessage(win.TB_GETBUTTONSIZE, 0, 0))

	width := tb.defaultButtonWidth
	if width == 0 {
		width = int(win.LOWORD(size))
	}

	height := int(win.HIWORD(size))

	return Size{width, height}
}
예제 #2
0
파일: toolbar.go 프로젝트: kumakichi/walk
func (tb *ToolBar) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr {
	switch msg {
	case win.WM_COMMAND:
		switch win.HIWORD(uint32(wParam)) {
		case win.BN_CLICKED:
			actionId := uint16(win.LOWORD(uint32(wParam)))
			if action, ok := actionsById[actionId]; ok {
				action.raiseTriggered()
				return 0
			}
		}

	case win.WM_NOTIFY:
		nmhdr := (*win.NMHDR)(unsafe.Pointer(lParam))

		switch int32(nmhdr.Code) {
		case win.TBN_DROPDOWN:
			nmtb := (*win.NMTOOLBAR)(unsafe.Pointer(lParam))
			actionId := uint16(nmtb.IItem)
			if action := actionsById[actionId]; action != nil {
				var r win.RECT
				if 0 == tb.SendMessage(win.TB_GETRECT, uintptr(actionId), uintptr(unsafe.Pointer(&r))) {
					break
				}

				p := win.POINT{r.Left, r.Bottom}

				if !win.ClientToScreen(tb.hWnd, &p) {
					break
				}

				win.TrackPopupMenuEx(
					action.menu.hMenu,
					win.TPM_NOANIMATION,
					p.X,
					p.Y,
					tb.hWnd,
					nil)

				return win.TBDDRET_DEFAULT
			}
		}
	}

	return tb.WidgetBase.WndProc(hwnd, msg, wParam, lParam)
}
예제 #3
0
파일: container.go 프로젝트: kumakichi/walk
func (cb *ContainerBase) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr {
	switch msg {
	case win.WM_COMMAND:
		if lParam == 0 {
			switch win.HIWORD(uint32(wParam)) {
			case 0:
				cmdId := win.LOWORD(uint32(wParam))
				switch cmdId {
				case win.IDOK, win.IDCANCEL:
					form := ancestor(cb)
					if form == nil {
						break
					}

					dlg, ok := form.(dialogish)
					if !ok {
						break
					}

					var button *PushButton
					if cmdId == win.IDOK {
						button = dlg.DefaultButton()
					} else {
						button = dlg.CancelButton()
					}

					if button != nil && button.Visible() && button.Enabled() {
						button.raiseClicked()
					}

					break
				}

				// Menu
				actionId := uint16(win.LOWORD(uint32(wParam)))
				if action, ok := actionsById[actionId]; ok {
					action.raiseTriggered()
					return 0
				}

			case 1:
				// Accelerator
			}
		} else {
			// The window that sent the notification shall handle it itself.
			hWnd := win.HWND(lParam)
			if window := windowFromHandle(hWnd); window != nil {
				window.WndProc(hwnd, msg, wParam, lParam)
				return 0
			}
		}

	case win.WM_NOTIFY:
		nmh := (*win.NMHDR)(unsafe.Pointer(lParam))
		if window := windowFromHandle(nmh.HwndFrom); window != nil {
			// The window that sent the notification shall handle it itself.
			return window.WndProc(hwnd, msg, wParam, lParam)
		}

	case win.WM_SIZE, win.WM_SIZING:
		if cb.layout != nil {
			cb.layout.Update(false)
		}
	}

	return cb.WidgetBase.WndProc(hwnd, msg, wParam, lParam)
}
예제 #4
0
func (nle *numberLineEdit) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr {
	switch msg {
	case win.WM_CHAR:
		if AltDown() {
			return 0
		}

		if ControlDown() {
			if wParam == 1 {
				// Ctrl+A
				return 0
			}
			break
		}

		char := uint16(wParam)

		text := nle.textUTF16()
		text = text[len(nle.prefix) : len(text)-len(nle.suffix)]
		start, end := nle.TextSelection()
		start -= len(nle.prefix)
		end -= len(nle.prefix)

		if Key(wParam) == KeyBack {
			nle.processChar(text, start, end, KeyBack, 0)
			return 0
		}

		switch char {
		case uint16('0'), uint16('1'), uint16('2'), uint16('3'), uint16('4'), uint16('5'), uint16('6'), uint16('7'), uint16('8'), uint16('9'):
			if start == end && nle.decimals > 0 {
				if i := uint16IndexUint16(text, decimalSepUint16); i > -1 && i < len(text)-nle.decimals && start > i {
					return 0
				}
			}

			nle.processChar(text, start, end, 0, char)
			return 0

		case uint16('-'):
			if nle.minValue != nle.maxValue && nle.minValue >= 0 {
				return 0
			}

			if start > 0 || uint16ContainsUint16(text, uint16('-')) && end == 0 {
				return 0
			}

			nle.processChar(text, start, end, 0, char)
			return 0

		case decimalSepUint16:
			if nle.decimals == 0 {
				return 0
			}

			if start == 0 && end == 0 && len(text) > 0 && text[0] == '-' {
				return 0
			}

			if end < len(text)-nle.decimals {
				return 0
			}

			if i := uint16IndexUint16(text, decimalSepUint16); i > -1 && i <= start || i > end {
				return 0
			}

			nle.processChar(text, start, end, 0, char)
			return 0

		default:
			return 0
		}

	case win.WM_KEYDOWN:
		switch Key(wParam) {
		case KeyA:
			if ControlDown() {
				nle.selectNumber()
				return 0
			}

		case KeyDelete:
			text := nle.textUTF16()
			text = text[len(nle.prefix) : len(text)-len(nle.suffix)]
			start, end := nle.TextSelection()
			start -= len(nle.prefix)
			end -= len(nle.prefix)

			nle.processChar(text, start, end, KeyDelete, 0)
			return 0

		case KeyDown:
			nle.incrementValue(-nle.increment)
			return 0

		case KeyEnd:
			start, end := nle.TextSelection()
			end = len(nle.textUTF16()) - len(nle.suffix)
			if !ShiftDown() {
				start = end
			}
			nle.SetTextSelection(start, end)
			return 0

		case KeyHome:
			start, end := nle.TextSelection()
			start = len(nle.prefix)
			if !ShiftDown() {
				end = start
			}
			nle.SetTextSelection(start, end)
			return 0

		case KeyLeft:
			var pos win.POINT
			win.GetCaretPos(&pos)

			lParam := uintptr(win.MAKELONG(uint16(pos.X), uint16(pos.Y)))
			i := int(win.LOWORD(uint32(nle.SendMessage(win.EM_CHARFROMPOS, 0, lParam))))

			if min := len(nle.prefix); i <= min {
				if !ShiftDown() {
					nle.SetTextSelection(min, min)
				}
				return 0
			}

		case KeyReturn:
			if nle.inEditMode {
				nle.endEdit()
				nle.selectNumber()
				return 0
			}

		case KeyRight:
			var pos win.POINT
			win.GetCaretPos(&pos)

			lParam := uintptr(win.MAKELONG(uint16(pos.X), uint16(pos.Y)))
			i := int(win.LOWORD(uint32(nle.SendMessage(win.EM_CHARFROMPOS, 0, lParam))))

			if max := len(nle.textUTF16()) - len(nle.suffix); i >= max {
				if !ShiftDown() {
					nle.SetTextSelection(max, max)
				}
				return 0
			}

		case KeyUp:
			nle.incrementValue(nle.increment)
			return 0
		}

	case win.WM_GETDLGCODE:
		if !nle.inEditMode {
			if form := ancestor(nle); form != nil {
				if dlg, ok := form.(dialogish); ok {
					if dlg.DefaultButton() != nil {
						// If the NumberEdit lives in a Dialog that has a
						// DefaultButton, we won't swallow the return key.
						break
					}
				}
			}
		}

		if wParam == win.VK_RETURN {
			return win.DLGC_WANTALLKEYS
		}

	case win.WM_KILLFOCUS:
		nle.endEdit()

	case win.WM_LBUTTONDOWN:
		i := int(win.LOWORD(uint32(nle.SendMessage(win.EM_CHARFROMPOS, 0, lParam))))

		if min := len(nle.prefix); i < min {
			nle.SetFocus()
			nle.SetTextSelection(min, min)
			return 0
		}
		if max := len(nle.textUTF16()) - len(nle.suffix); i > max {
			nle.SetFocus()
			nle.SetTextSelection(max, max)
			return 0
		}

	case win.WM_LBUTTONDBLCLK:
		nle.selectNumber()
		return 0

	case win.WM_MOUSEMOVE:
		i := int(win.LOWORD(uint32(nle.SendMessage(win.EM_CHARFROMPOS, 0, lParam))))

		if min := len(nle.prefix); i < min {
			return 0
		}
		if max := len(nle.textUTF16()) - len(nle.suffix); i > max {
			return 0
		}

	case win.WM_MOUSEWHEEL:
		delta := float64(int16(win.HIWORD(uint32(wParam))))
		nle.incrementValue(delta / 120 * nle.increment)
		return 0

	case win.WM_PASTE:
		ret := nle.LineEdit.WndProc(hwnd, msg, wParam, lParam)
		if !nle.tryUpdateValue(true) {
			nle.setTextFromValue(nle.value)
		}
		nle.selectNumber()
		return ret

	case win.WM_SETFOCUS:
		nle.selectNumber()

	case win.EM_SETSEL:
		start := int(wParam)
		end := int(lParam)
		adjusted := false
		if min := len(nle.prefix); start < min {
			start = min
			adjusted = true
		}
		if max := len(nle.textUTF16()) - len(nle.suffix); end < 0 || end > max {
			end = max
			adjusted = true
		}

		if adjusted {
			nle.SetTextSelection(start, end)
			return 0
		}
	}

	return nle.LineEdit.WndProc(hwnd, msg, wParam, lParam)
}
예제 #5
0
파일: form.go 프로젝트: kumakichi/walk
func (fb *FormBase) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr {
	switch msg {
	case win.WM_ACTIVATE:
		switch win.LOWORD(uint32(wParam)) {
		case win.WA_ACTIVE, win.WA_CLICKACTIVE:
			if fb.prevFocusHWnd != 0 {
				win.SetFocus(fb.prevFocusHWnd)
			}

		case win.WA_INACTIVE:
			fb.prevFocusHWnd = win.GetFocus()
		}
		return 0

	case win.WM_CLOSE:
		fb.closeReason = CloseReasonUnknown
		var canceled bool
		fb.closingPublisher.Publish(&canceled, fb.closeReason)
		if !canceled {
			if fb.owner != nil {
				fb.owner.SetEnabled(true)
				if !win.SetWindowPos(fb.owner.Handle(), win.HWND_NOTOPMOST, 0, 0, 0, 0, win.SWP_NOMOVE|win.SWP_NOSIZE|win.SWP_SHOWWINDOW) {
					lastError("SetWindowPos")
				}
			}

			fb.close()
		}
		return 0

	case win.WM_COMMAND:
		return fb.clientComposite.WndProc(hwnd, msg, wParam, lParam)

	case win.WM_GETMINMAXINFO:
		mmi := (*win.MINMAXINFO)(unsafe.Pointer(lParam))

		layout := fb.clientComposite.Layout()

		var min, max Size
		if layout != nil {
			min = fb.sizeFromClientSize(layout.MinSize())
			max = fb.sizeFromClientSize(layout.MaxSize())
		}

		mmi.PtMinTrackSize = win.POINT{
			int32(maxi(min.Width, fb.minSize.Width)),
			int32(maxi(min.Height, fb.minSize.Height)),
		}
		mmi.PtMaxTrackSize = win.POINT{
			int32(maxi(max.Width, fb.maxSize.Width)),
			int32(maxi(max.Height, fb.maxSize.Height)),
		}
		return 0

	case win.WM_NOTIFY:
		return fb.clientComposite.WndProc(hwnd, msg, wParam, lParam)

	case win.WM_SETTEXT:
		fb.titleChangedPublisher.Publish()

	case win.WM_SIZE, win.WM_SIZING:
		fb.clientComposite.SetBounds(fb.window.ClientBounds())

	case win.WM_SYSCOMMAND:
		if wParam == win.SC_CLOSE {
			fb.closeReason = CloseReasonUser
		}

	case taskbarButtonCreatedMsgId:
		version := win.GetVersion()
		major := version & 0xFF
		minor := version & 0xFF00 >> 8
		// Check that the OS is Win 7 or later (Win 7 is v6.1).
		if major > 6 || (major == 6 && minor > 0) {
			fb.progressIndicator, _ = newTaskbarList3(fb.hWnd)
		}
	}

	return fb.WindowBase.WndProc(hwnd, msg, wParam, lParam)
}