1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Clipboard Viewer 4 * FILE: base/applications/clipbrd/scrollutils.c 5 * PURPOSE: Scrolling related helper functions. 6 * PROGRAMMERS: Ricardo Hanke 7 */ 8 9 #include "precomp.h" 10 11 static int InternalSetScrollInfo(HWND hWnd, int nMin, int nMax, UINT nPage, int nPos, int fnBar) 12 { 13 SCROLLINFO si; 14 15 ZeroMemory(&si, sizeof(si)); 16 si.cbSize = sizeof(si); 17 si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_DISABLENOSCROLL; 18 si.nMin = nMin; 19 si.nMax = nMax; 20 si.nPage = nPage; 21 si.nPos = nPos; 22 23 return SetScrollInfo(hWnd, fnBar, &si, TRUE); 24 } 25 26 void HandleKeyboardScrollEvents(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 27 { 28 switch (wParam) 29 { 30 case VK_UP: 31 { 32 SendMessage(hWnd, WM_VSCROLL, MAKELONG(SB_LINEUP, 0), 0); 33 break; 34 } 35 36 case VK_DOWN: 37 { 38 SendMessage(hWnd, WM_VSCROLL, MAKELONG(SB_LINEDOWN, 0), 0); 39 break; 40 } 41 42 case VK_LEFT: 43 { 44 SendMessage(hWnd, WM_HSCROLL, MAKELONG(SB_LINEUP, 0), 0); 45 break; 46 } 47 48 case VK_RIGHT: 49 { 50 SendMessage(hWnd, WM_HSCROLL, MAKELONG(SB_LINEDOWN, 0), 0); 51 break; 52 } 53 54 case VK_PRIOR: 55 { 56 SendMessage(hWnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0); 57 break; 58 } 59 60 case VK_NEXT: 61 { 62 SendMessage(hWnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0); 63 break; 64 } 65 66 default: 67 { 68 break; 69 } 70 } 71 } 72 73 void HandleMouseScrollEvents(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LPSCROLLSTATE state) 74 { 75 SCROLLINFO si; 76 int Delta; 77 int NewPos; 78 79 si.cbSize = sizeof(si); 80 si.fMask = SIF_PAGE; 81 GetScrollInfo(hWnd, SB_VERT, &si); 82 83 if (Globals.uLinesToScroll == WHEEL_PAGESCROLL) 84 { 85 NewPos = si.nPage; 86 } 87 else 88 { 89 NewPos = Globals.uLinesToScroll * 5; 90 } 91 92 if (GET_WHEEL_DELTA_WPARAM(wParam) > 0) 93 { 94 NewPos = state->CurrentY - NewPos; 95 } 96 else 97 { 98 NewPos = state->CurrentY + NewPos; 99 } 100 101 NewPos = min(state->MaxY, max(0, NewPos)); 102 103 if (NewPos == state->CurrentY) 104 { 105 return; 106 } 107 108 Delta = NewPos - state->CurrentY; 109 110 state->CurrentY = NewPos; 111 112 ScrollWindowEx(hWnd, 0, -Delta, NULL, NULL, NULL, NULL, SW_INVALIDATE); 113 114 si.cbSize = sizeof(si); 115 si.fMask = SIF_POS; 116 si.nPos = state->CurrentY; 117 SetScrollInfo(hWnd, SB_VERT, &si, TRUE); 118 } 119 120 void HandleHorizontalScrollEvents(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LPSCROLLSTATE state) 121 { 122 SCROLLINFO si; 123 int Delta; 124 int NewPos; 125 126 ZeroMemory(&si, sizeof(si)); 127 si.cbSize = sizeof(si); 128 si.fMask = SIF_PAGE | SIF_TRACKPOS; 129 GetScrollInfo(hWnd, SB_HORZ, &si); 130 131 switch (LOWORD(wParam)) 132 { 133 case SB_THUMBPOSITION: 134 case SB_THUMBTRACK: 135 { 136 NewPos = si.nTrackPos; 137 break; 138 } 139 140 case SB_LINELEFT: 141 { 142 NewPos = state->CurrentX - 5; 143 break; 144 } 145 146 case SB_LINERIGHT: 147 { 148 NewPos = state->CurrentX + 5; 149 break; 150 } 151 152 case SB_PAGELEFT: 153 { 154 NewPos = state->CurrentX - si.nPage; 155 break; 156 } 157 158 case SB_PAGERIGHT: 159 { 160 NewPos = state->CurrentX + si.nPage; 161 break; 162 } 163 164 default: 165 { 166 NewPos = state->CurrentX; 167 break; 168 } 169 } 170 171 NewPos = min(state->MaxX, max(0, NewPos)); 172 173 if (NewPos == state->CurrentX) 174 { 175 return; 176 } 177 178 Delta = NewPos - state->CurrentX; 179 180 state->CurrentX = NewPos; 181 182 ScrollWindowEx(hWnd, -Delta, 0, NULL, NULL, NULL, NULL, SW_INVALIDATE); 183 184 si.cbSize = sizeof(si); 185 si.fMask = SIF_POS; 186 si.nPos = state->CurrentX; 187 SetScrollInfo(hWnd, SB_HORZ, &si, TRUE); 188 } 189 190 void HandleVerticalScrollEvents(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LPSCROLLSTATE state) 191 { 192 SCROLLINFO si; 193 int Delta; 194 int NewPos; 195 196 ZeroMemory(&si, sizeof(si)); 197 si.cbSize = sizeof(si); 198 si.fMask = SIF_PAGE | SIF_TRACKPOS; 199 GetScrollInfo(hWnd, SB_VERT, &si); 200 201 switch (LOWORD(wParam)) 202 { 203 case SB_THUMBPOSITION: 204 case SB_THUMBTRACK: 205 { 206 NewPos = si.nTrackPos; 207 break; 208 } 209 210 case SB_LINEUP: 211 { 212 NewPos = state->CurrentY - 5; 213 break; 214 } 215 216 case SB_LINEDOWN: 217 { 218 NewPos = state->CurrentY + 5; 219 break; 220 } 221 222 case SB_PAGEUP: 223 { 224 NewPos = state->CurrentY - si.nPage; 225 break; 226 } 227 228 case SB_PAGEDOWN: 229 { 230 NewPos = state->CurrentY + si.nPage; 231 break; 232 } 233 234 default: 235 { 236 NewPos = state->CurrentY; 237 break; 238 } 239 } 240 241 NewPos = min(state->MaxY, max(0, NewPos)); 242 243 if (NewPos == state->CurrentY) 244 { 245 return; 246 } 247 248 Delta = NewPos - state->CurrentY; 249 250 state->CurrentY = NewPos; 251 252 ScrollWindowEx(hWnd, 0, -Delta, NULL, NULL, NULL, NULL, SW_INVALIDATE); 253 254 si.cbSize = sizeof(si); 255 si.fMask = SIF_POS; 256 si.nPos = state->CurrentY; 257 SetScrollInfo(hWnd, SB_VERT, &si, TRUE); 258 } 259 260 void UpdateWindowScrollState(HWND hWnd, HBITMAP hBitmap, LPSCROLLSTATE lpState) 261 { 262 BITMAP bmp; 263 RECT rc; 264 265 if (!GetObject(hBitmap, sizeof(BITMAP), &bmp)) 266 { 267 bmp.bmWidth = 0; 268 bmp.bmHeight = 0; 269 } 270 271 if (!GetClientRect(hWnd, &rc)) 272 { 273 SetRectEmpty(&rc); 274 } 275 276 lpState->MaxX = max(bmp.bmWidth - rc.right, 0); 277 lpState->CurrentX = min(lpState->CurrentX, lpState->MaxX); 278 InternalSetScrollInfo(hWnd, 0, bmp.bmWidth, rc.right, lpState->CurrentX, SB_HORZ); 279 280 lpState->MaxY = max(bmp.bmHeight - rc.bottom, 0); 281 lpState->CurrentY = min(lpState->CurrentY, lpState->MaxY); 282 InternalSetScrollInfo(hWnd, 0, bmp.bmHeight, rc.bottom, lpState->CurrentY, SB_VERT); 283 } 284 285 BOOL ScrollBlt(PAINTSTRUCT ps, HBITMAP hBmp, SCROLLSTATE state) 286 { 287 RECT rect; 288 BOOL ret; 289 HDC hdc; 290 int xpos; 291 int ypos; 292 293 rect.left = ps.rcPaint.left; 294 rect.top = ps.rcPaint.top; 295 rect.right = (ps.rcPaint.right - ps.rcPaint.left); 296 rect.bottom = (ps.rcPaint.bottom - ps.rcPaint.top); 297 298 xpos = ps.rcPaint.left + state.CurrentX; 299 ypos = ps.rcPaint.top + state.CurrentY; 300 301 ret = FALSE; 302 303 hdc = CreateCompatibleDC(ps.hdc); 304 if (hdc) 305 { 306 if (SelectObject(hdc, hBmp)) 307 { 308 ret = BitBlt(ps.hdc, rect.left, rect.top, rect.right, rect.bottom, hdc, xpos, ypos, SRCCOPY); 309 } 310 DeleteDC(hdc); 311 } 312 313 return ret; 314 } 315