ReactOS 0.4.15-dev-8096-ga0eec98
scrollutils.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Clipboard Viewer
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Scrolling related helper functions.
5 * COPYRIGHT: Copyright 2015-2018 Ricardo Hanke
6 * Copyright 2015-2018 Hermes Belusca-Maito
7 */
8
9#include "precomp.h"
10
12{
13 // NOTE: Windows uses an offset of 16 pixels
14 switch (wParam)
15 {
16 case VK_UP:
18 break;
19
20 case VK_DOWN:
22 break;
23
24 case VK_LEFT:
26 break;
27
28 case VK_RIGHT:
30 break;
31
32 case VK_PRIOR:
34 break;
35
36 case VK_NEXT:
38 break;
39
40 case VK_HOME:
41 {
43 if (GetKeyState(VK_CONTROL) & 0x8000)
45 break;
46 }
47
48 case VK_END:
49 {
51 if (GetKeyState(VK_CONTROL) & 0x8000)
53 break;
54 }
55
56 default:
57 break;
58 }
59}
60
62{
63 INT nBar;
64 INT nPage;
65 INT iDelta;
66 UINT uLinesToScroll = state->uLinesToScroll;
67 INT zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
68 WORD sbCode;
69
70 assert(uMsg == WM_MOUSEWHEEL || uMsg == WM_MOUSEHWHEEL);
71
72 if (uMsg == WM_MOUSEWHEEL)
73 {
74 nBar = SB_VERT;
75 nPage = state->nPageY;
76
77 /* Accumulate wheel rotation ticks */
78 zDelta += state->iWheelCarryoverY;
79 state->iWheelCarryoverY = zDelta % WHEEL_DELTA;
80 }
81 else // if (uMsg == WM_MOUSEHWHEEL)
82 {
83 nBar = SB_HORZ;
84 nPage = state->nPageX;
85
86 /* Accumulate wheel rotation ticks */
87 zDelta += state->iWheelCarryoverX;
88 state->iWheelCarryoverX = zDelta % WHEEL_DELTA;
89 }
90
91 /*
92 * If the user specified scrolling by pages, do so.
93 * Due to a bug on Windows where, if the window height is
94 * less than the scroll lines delta default value (== 3),
95 * several lines would be skipped when scrolling if we
96 * used the WHEEL_PAGESCROLL value. Instead of this, use
97 * the number of lines per page as the limiting value.
98 * See https://www.strchr.com/corrections_to_raymond_chen_s_wheel_scrolling_code
99 * for more details.
100 */
101 if (uLinesToScroll > nPage) // (uLinesToScroll == WHEEL_PAGESCROLL)
102 uLinesToScroll = nPage;
103 /* If the user specified no wheel scrolling, don't do anything */
104 else if (uLinesToScroll == 0)
105 return;
106
107 /* Compute the scroll direction and the absolute delta value */
108 if (zDelta > 0)
109 {
110 sbCode = SB_LINEUP;
111 }
112 else
113 {
114 sbCode = SB_LINEDOWN;
115 zDelta = -zDelta;
116 }
117
118 /* Compute how many lines we should scroll (in absolute value) */
119 iDelta = (INT)uLinesToScroll * zDelta / WHEEL_DELTA;
120
121 OnScroll(hWnd, nBar, MAKELONG(sbCode, 0), iDelta, state);
122}
123
125{
126 SCROLLINFO si;
127 PINT pCurrent;
128 INT Maximum;
129 INT NewPos;
130 INT OldX, OldY;
131
132 assert(nBar == SB_HORZ || nBar == SB_VERT);
133
135 {
136 if (nBar == SB_HORZ)
137 {
140 }
141 else // if (nBar == SB_VERT)
142 {
145 }
146 return;
147 }
148
149 if (nBar == SB_HORZ)
150 {
151 pCurrent = &state->CurrentX;
152 Maximum = state->MaxX;
153 }
154 else // if (nBar == SB_VERT)
155 {
156 pCurrent = &state->CurrentY;
157 Maximum = state->MaxY;
158 }
159
160 ZeroMemory(&si, sizeof(si));
161 si.cbSize = sizeof(si);
163 GetScrollInfo(hWnd, nBar, &si);
164
165 switch (LOWORD(wParam))
166 {
167 case SB_THUMBPOSITION:
168 case SB_THUMBTRACK:
169 {
170 NewPos = si.nTrackPos;
171 break;
172 }
173
174 case SB_LINEUP: // SB_LINELEFT:
175 {
176 NewPos = si.nPos - iDelta;
177 break;
178 }
179
180 case SB_LINEDOWN: // SB_LINERIGHT:
181 {
182 NewPos = si.nPos + iDelta;
183 break;
184 }
185
186 case SB_PAGEUP: // SB_PAGELEFT:
187 {
188 NewPos = si.nPos - si.nPage;
189 break;
190 }
191
192 case SB_PAGEDOWN: // SB_PAGERIGHT:
193 {
194 NewPos = si.nPos + si.nPage;
195 break;
196 }
197
198 case SB_TOP: // SB_LEFT:
199 {
200 NewPos = si.nMin;
201 break;
202 }
203
204 case SB_BOTTOM: // SB_RIGHT:
205 {
206 NewPos = si.nMax;
207 break;
208 }
209
210 default:
211 {
212 NewPos = si.nPos;
213 break;
214 }
215 }
216
217 NewPos = min(max(NewPos, 0), Maximum);
218
219 if (si.nPos == NewPos)
220 return;
221
222 OldX = state->CurrentX;
223 OldY = state->CurrentY;
224 *pCurrent = NewPos;
225
227 OldX - state->CurrentX,
228 OldY - state->CurrentY,
229 NULL,
230 NULL,
231 NULL,
232 NULL,
235
236 si.fMask = SIF_POS;
237 si.nPos = NewPos;
238 SetScrollInfo(hWnd, nBar, &si, TRUE);
239}
240
242{
243 UINT uLinesToScroll;
244
245 if (!SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &uLinesToScroll, 0))
246 {
247 /* Default value on Windows */
248 state->uLinesToScroll = 3;
249 }
250 else
251 {
252 state->uLinesToScroll = uLinesToScroll;
253 }
254}
255
256void UpdateWindowScrollState(HWND hWnd, INT nMaxWidth, INT nMaxHeight, LPSCROLLSTATE lpState)
257{
258 RECT rc;
259 SCROLLINFO si;
260
261 if (!GetClientRect(hWnd, &rc))
262 SetRectEmpty(&rc);
263
264 ZeroMemory(&si, sizeof(si));
265 si.cbSize = sizeof(si);
267
268 lpState->nMaxWidth = nMaxWidth;
269 lpState->MaxX = max(nMaxWidth - rc.right, 0);
270 lpState->CurrentX = min(lpState->CurrentX, lpState->MaxX);
271 lpState->nPageX = rc.right;
272 si.nMin = 0;
273 si.nMax = nMaxWidth;
274 si.nPage = lpState->nPageX;
275 si.nPos = lpState->CurrentX;
277
278 lpState->nMaxHeight = nMaxHeight;
279 lpState->MaxY = max(nMaxHeight - rc.bottom, 0);
280 lpState->CurrentY = min(lpState->CurrentY, lpState->MaxY);
281 lpState->nPageY = rc.bottom;
282 si.nMin = 0;
283 si.nMax = nMaxHeight;
284 si.nPage = lpState->nPageY;
285 si.nPos = lpState->CurrentY;
287}
static int state
Definition: maze.c:121
HWND hWnd
Definition: settings.c:17
#define CF_OWNERDISPLAY
Definition: constants.h:413
CLIPBOARD_GLOBALS Globals
Definition: clipbrd.c:13
LRESULT SendClipboardOwnerMessage(IN BOOL bUnicode, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
Definition: cliputils.c:12
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define assert(x)
Definition: debug.h:53
unsigned short WORD
Definition: ntddk_ex.h:93
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define LOWORD(l)
Definition: pedump.c:82
#define INT
Definition: polytest.cpp:20
void UpdateLinesToScroll(LPSCROLLSTATE state)
Definition: scrollutils.c:241
void UpdateWindowScrollState(HWND hWnd, INT nMaxWidth, INT nMaxHeight, LPSCROLLSTATE lpState)
Definition: scrollutils.c:256
void OnKeyScroll(HWND hWnd, WPARAM wParam, LPARAM lParam, LPSCROLLSTATE state)
Definition: scrollutils.c:11
void OnScroll(HWND hWnd, INT nBar, WPARAM wParam, INT iDelta, LPSCROLLSTATE state)
Definition: scrollutils.c:124
void OnMouseScroll(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LPSCROLLSTATE state)
Definition: scrollutils.c:61
UINT uDisplayFormat
Definition: precomp.h:47
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
#define max(a, b)
Definition: svc.c:63
#define WHEEL_DELTA
Definition: treelist.c:99
#define WM_MOUSEWHEEL
Definition: treelist.c:96
int32_t INT
Definition: typedefs.h:58
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define ZeroMemory
Definition: winbase.h:1712
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
int * PINT
Definition: windef.h:177
#define WM_VSCROLLCLIPBOARD
Definition: winuser.h:1871
#define SB_THUMBTRACK
Definition: winuser.h:573
#define SB_LINEUP
Definition: winuser.h:564
#define WM_HSCROLLCLIPBOARD
Definition: winuser.h:1875
#define SIF_RANGE
Definition: winuser.h:1235
#define SB_VERT
Definition: winuser.h:553
#define SB_LEFT
Definition: winuser.h:575
#define SB_BOTTOM
Definition: winuser.h:577
#define SW_INVALIDATE
Definition: winuser.h:2579
#define VK_CONTROL
Definition: winuser.h:2203
#define VK_UP
Definition: winuser.h:2225
#define SIF_PAGE
Definition: winuser.h:1233
#define SB_LINERIGHT
Definition: winuser.h:567
#define SIF_TRACKPOS
Definition: winuser.h:1237
#define VK_NEXT
Definition: winuser.h:2221
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define SB_LINELEFT
Definition: winuser.h:566
#define VK_END
Definition: winuser.h:2222
#define VK_HOME
Definition: winuser.h:2223
#define SIF_DISABLENOSCROLL
Definition: winuser.h:1236
BOOL WINAPI UpdateWindow(_In_ HWND)
#define SB_PAGEDOWN
Definition: winuser.h:569
#define SB_LINEDOWN
Definition: winuser.h:565
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
#define VK_LEFT
Definition: winuser.h:2224
#define VK_RIGHT
Definition: winuser.h:2226
#define SB_TOP
Definition: winuser.h:578
#define SIF_POS
Definition: winuser.h:1234
#define VK_DOWN
Definition: winuser.h:2227
#define SW_ERASE
Definition: winuser.h:2580
#define VK_PRIOR
Definition: winuser.h:2220
int WINAPI SetScrollInfo(_In_ HWND, _In_ int, _In_ LPCSCROLLINFO, _In_ BOOL)
#define SB_RIGHT
Definition: winuser.h:576
#define SystemParametersInfo
Definition: winuser.h:5858
BOOL WINAPI GetScrollInfo(_In_ HWND, _In_ int, _Inout_ LPSCROLLINFO)
int WINAPI ScrollWindowEx(_In_ HWND, _In_ int, _In_ int, _In_opt_ LPCRECT, _In_opt_ LPCRECT, _In_opt_ HRGN, _Out_opt_ LPRECT, _In_ UINT)
#define SB_PAGEUP
Definition: winuser.h:568
#define SB_HORZ
Definition: winuser.h:552
SHORT WINAPI GetKeyState(_In_ int)
#define SB_THUMBPOSITION
Definition: winuser.h:572