github.com/secoba/wails/v2@v2.6.4/internal/frontend/desktop/windows/winc/scrollview.go (about) 1 //go:build windows 2 3 /* 4 * Copyright (C) 2019 The Winc Authors. All Rights Reserved. 5 */ 6 7 package winc 8 9 import ( 10 "unsafe" 11 12 "github.com/secoba/wails/v2/internal/frontend/desktop/windows/winc/w32" 13 ) 14 15 type ScrollView struct { 16 ControlBase 17 child Dockable 18 } 19 20 func NewScrollView(parent Controller) *ScrollView { 21 sv := new(ScrollView) 22 23 RegClassOnlyOnce("winc_ScrollView") 24 sv.hwnd = CreateWindow("winc_ScrollView", parent, w32.WS_EX_CONTROLPARENT, 25 w32.WS_CHILD|w32.WS_HSCROLL|w32.WS_VISIBLE|w32.WS_VSCROLL) 26 sv.parent = parent 27 RegMsgHandler(sv) 28 29 sv.SetFont(DefaultFont) 30 sv.SetText("") 31 sv.SetSize(200, 200) 32 return sv 33 } 34 35 func (sv *ScrollView) SetChild(child Dockable) { 36 sv.child = child 37 } 38 39 func (sv *ScrollView) UpdateScrollBars() { 40 w, h := sv.child.Width(), sv.child.Height() 41 sw, sh := sv.Size() 42 43 var si w32.SCROLLINFO 44 si.CbSize = uint32(unsafe.Sizeof(si)) 45 si.FMask = w32.SIF_PAGE | w32.SIF_RANGE 46 47 si.NMax = int32(w - 1) 48 si.NPage = uint32(sw) 49 w32.SetScrollInfo(sv.hwnd, w32.SB_HORZ, &si, true) 50 x := sv.scroll(w32.SB_HORZ, w32.SB_THUMBPOSITION) 51 52 si.NMax = int32(h) 53 si.NPage = uint32(sh) 54 w32.SetScrollInfo(sv.hwnd, w32.SB_VERT, &si, true) 55 y := sv.scroll(w32.SB_VERT, w32.SB_THUMBPOSITION) 56 57 sv.child.SetPos(x, y) 58 } 59 60 func (sv *ScrollView) scroll(sb int32, cmd uint16) int { 61 var pos int32 62 var si w32.SCROLLINFO 63 si.CbSize = uint32(unsafe.Sizeof(si)) 64 si.FMask = w32.SIF_PAGE | w32.SIF_POS | w32.SIF_RANGE | w32.SIF_TRACKPOS 65 66 w32.GetScrollInfo(sv.hwnd, sb, &si) 67 pos = si.NPos 68 69 switch cmd { 70 case w32.SB_LINELEFT: // == win.SB_LINEUP 71 pos -= 20 72 73 case w32.SB_LINERIGHT: // == win.SB_LINEDOWN 74 pos += 20 75 76 case w32.SB_PAGELEFT: // == win.SB_PAGEUP 77 pos -= int32(si.NPage) 78 79 case w32.SB_PAGERIGHT: // == win.SB_PAGEDOWN 80 pos += int32(si.NPage) 81 82 case w32.SB_THUMBTRACK: 83 pos = si.NTrackPos 84 } 85 86 if pos < 0 { 87 pos = 0 88 } 89 if pos > si.NMax+1-int32(si.NPage) { 90 pos = si.NMax + 1 - int32(si.NPage) 91 } 92 93 si.FMask = w32.SIF_POS 94 si.NPos = pos 95 w32.SetScrollInfo(sv.hwnd, sb, &si, true) 96 97 return -int(pos) 98 } 99 100 func (sv *ScrollView) WndProc(msg uint32, wparam, lparam uintptr) uintptr { 101 if sv.child != nil { 102 switch msg { 103 case w32.WM_PAINT: 104 sv.UpdateScrollBars() 105 106 case w32.WM_HSCROLL: 107 x, y := sv.child.Pos() 108 x = sv.scroll(w32.SB_HORZ, w32.LOWORD(uint32(wparam))) 109 sv.child.SetPos(x, y) 110 111 case w32.WM_VSCROLL: 112 x, y := sv.child.Pos() 113 y = sv.scroll(w32.SB_VERT, w32.LOWORD(uint32(wparam))) 114 sv.child.SetPos(x, y) 115 116 case w32.WM_SIZE, w32.WM_SIZING: 117 sv.UpdateScrollBars() 118 } 119 } 120 return w32.DefWindowProc(sv.hwnd, msg, wparam, lparam) 121 }