[PRINTING]
[reactos.git] / reactos / base / applications / clipbrd / scrollutils.c
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 releated 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 }