summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-03-25 07:11:10 -0400
committerPietro Gagliardi <[email protected]>2014-03-25 07:11:10 -0400
commit3c0bcb6d68aa68fd2eb8e646ac0d39c831228ca2 (patch)
treefaa68177c5fbe6ba8e0f64fe65e7a97c11df2437
parent0c3b64106cd3bea580e3c558343a64a36d949fd6 (diff)
Made the scrollbars on Windows Areas actually scroll. There are some kinks that need to be worked out before we can move on...
-rw-r--r--area_windows.go77
-rw-r--r--controls_windows.go1
2 files changed, 75 insertions, 3 deletions
diff --git a/area_windows.go b/area_windows.go
index 0351027..f784e73 100644
--- a/area_windows.go
+++ b/area_windows.go
@@ -156,6 +156,74 @@ func getAreaControlSize(hwnd _HWND) (width int, height int) {
int(rect.Bottom - rect.Top)
}
+func scrollArea(hwnd _HWND, wparam _WPARAM, which uintptr) {
+ var si _SCROLLINFO
+
+ cwid, cht := getAreaControlSize(hwnd)
+ pagesize := int32(cwid)
+ maxsize := int32(320)
+ if which == uintptr(_SB_VERT) {
+ pagesize = int32(cht)
+ maxsize = int32(240)
+ }
+
+ si.cbSize = uint32(unsafe.Sizeof(si))
+ si.fMask = _SIF_POS | _SIF_TRACKPOS
+ r1, _, err := _getScrollInfo.Call(
+ uintptr(hwnd),
+ which,
+ uintptr(unsafe.Pointer(&si)))
+ if r1 == 0 { // failure
+ panic(fmt.Errorf("error getting current scroll position for scrolling: %v", err))
+ }
+
+ newpos := si.nPos
+ switch wparam & 0xFFFF {
+ case _SB_LEFT: // also _SB_TOP but Go won't let me
+ newpos = 0
+ case _SB_RIGHT: // also _SB_BOTTOM
+ // see comment in adjustAreaScrollbars() below
+ newpos = maxsize - pagesize
+ case _SB_LINELEFT: // also _SB_LINEUP
+ newpos--
+ case _SB_LINERIGHT: // also _SB_LINEDOWN
+ newpos++
+ case _SB_PAGELEFT: // also _SB_PAGEUP
+ newpos -= pagesize
+ case _SB_PAGERIGHT: // also _SB_PAGEDOWN
+ newpos += pagesize
+ case _SB_THUMBPOSITION:
+ // TODO is this the same as SB_THUMBTRACK instead? MSDN says use of thumb pos is only for that one
+ // do nothing; newpos already has the thumb's position
+ case _SB_THUMBTRACK:
+ newpos = si.nTrackPos
+ } // otherwise just keep the current position (that's what MSDN example code says, anyway)
+
+ // make sure we're not out of range
+ if newpos < 0 {
+ newpos = 0
+ }
+ if newpos > (maxsize - pagesize) {
+ newpos = maxsize - pagesize
+ }
+
+ // TODO is this the right thing to do for SB_THUMBTRACK? or will it conflict?
+ if newpos == si.nPos { // no change; no scrolling
+ return
+ }
+
+ // TODO scroll
+
+ // we actually have to commit the change back to the scrollbar; otherwise the scroll position will merely reset itself
+ si.cbSize = uint32(unsafe.Sizeof(si))
+ si.fMask = _SIF_POS
+ si.nPos = newpos
+ _setScrollInfo.Call(
+ uintptr(hwnd),
+ which,
+ uintptr(unsafe.Pointer(&si)))
+}
+
func adjustAreaScrollbars(hwnd _HWND) {
var si _SCROLLINFO
@@ -164,6 +232,7 @@ func adjustAreaScrollbars(hwnd _HWND) {
// the trick is we want a page to be the width/height of the visible area
// so the scroll range would go from [0..image_dimension - control_dimension]
// but judging from the sample code on MSDN, we don't need to do this; the scrollbar will do it for us
+ // we DO need to handle it when scrolling, though, since the thumb can only go up to this upper limit
// have to do horizontal and vertical separately
si.cbSize = uint32(unsafe.Sizeof(si))
@@ -194,11 +263,13 @@ func areaWndProc(s *sysData) func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lPara
switch uMsg {
case _WM_PAINT:
paintArea(s)
- return _LRESULT(0)
+ return 0
case _WM_HSCROLL:
- fallthrough // TODO
+ scrollArea(hwnd, wParam, _SB_HORZ)
+ return 0
case _WM_VSCROLL:
- fallthrough // TODO
+ scrollArea(hwnd, wParam, _SB_VERT)
+ return 0
case _WM_SIZE:
adjustAreaScrollbars(hwnd) // don't use s.hwnd; this message can be sent before that's loaded
return 0
diff --git a/controls_windows.go b/controls_windows.go
index ee16b95..24adcfa 100644
--- a/controls_windows.go
+++ b/controls_windows.go
@@ -491,6 +491,7 @@ const (
)
var (
+ _getScrollInfo = user32.NewProc("GetScrollInfo")
_getScrollPos = user32.NewProc("GetScrollPos")
_setScrollInfo = user32.NewProc("SetScrollInfo")
_scrollWindowEx = user32.NewProc("ScrollWindowEx")