Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: third_party/wtl/include/atlscrl.h

Issue 703753005: More Windows build fixes. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: remove generated files Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/wtl/include/atlresce.h ('k') | third_party/wtl/include/atlsplit.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Windows Template Library - WTL version 8.0
2 // Copyright (C) Microsoft Corporation. All rights reserved.
3 //
4 // This file is a part of the Windows Template Library.
5 // The use and distribution terms for this software are covered by the
6 // Microsoft Permissive License (Ms-PL) which can be found in the file
7 // Ms-PL.txt at the root of this distribution.
8
9 #ifndef __ATLSCRL_H__
10 #define __ATLSCRL_H__
11
12 #pragma once
13
14 #ifndef __cplusplus
15 #error ATL requires C++ compilation (use a .cpp suffix)
16 #endif
17
18 #ifndef __ATLAPP_H__
19 #error atlscrl.h requires atlapp.h to be included first
20 #endif
21
22 #ifndef __ATLWIN_H__
23 #error atlscrl.h requires atlwin.h to be included first
24 #endif
25
26 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_ WCE)
27 #include <zmouse.h>
28 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_ WIN32_WCE)
29
30 #ifndef GET_WHEEL_DELTA_WPARAM
31 #define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
32 #endif
33
34 #ifndef WM_MOUSEHWHEEL
35 #define WM_MOUSEHWHEEL 0x020E
36 #endif
37
38
39 ///////////////////////////////////////////////////////////////////////////////
40 // Classes in this file:
41 //
42 // CScrollImpl<T>
43 // CScrollWindowImpl<T, TBase, TWinTraits>
44 // CMapScrollImpl<T>
45 // CMapScrollWindowImpl<T, TBase, TWinTraits>
46 // CFSBWindowT<TBase>
47 // CZoomScrollImpl<T>
48 // CZoomScrollWindowImpl<T, TBase, TWinTraits>
49 // CScrollContainerImpl<T, TBase, TWinTraits>
50 // CScrollContainer
51
52 namespace WTL
53 {
54
55 ///////////////////////////////////////////////////////////////////////////////
56 // CScrollImpl - Provides scrolling support to any window
57
58 // Scroll extended styles
59 #define SCRL_SCROLLCHILDREN 0x00000001
60 #define SCRL_ERASEBACKGROUND 0x00000002
61 #define SCRL_NOTHUMBTRACKING 0x00000004
62 #if (WINVER >= 0x0500)
63 #define SCRL_SMOOTHSCROLL 0x00000008
64 #endif // (WINVER >= 0x0500)
65 #define SCRL_DISABLENOSCROLLV 0x00000010
66 #define SCRL_DISABLENOSCROLLH 0x00000020
67 #define SCRL_DISABLENOSCROLL (SCRL_DISABLENOSCROLLV | SCRL_DISABLENOSCROLLH)
68
69
70 template <class T>
71 class CScrollImpl
72 {
73 public:
74 enum { uSCROLL_FLAGS = SW_INVALIDATE };
75
76 POINT m_ptOffset;
77 SIZE m_sizeAll;
78 SIZE m_sizeLine;
79 SIZE m_sizePage;
80 SIZE m_sizeClient;
81 int m_zDelta; // current wheel value
82 int m_nWheelLines; // number of lines to scroll on wheel
83 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_ WCE)
84 // Note that this message must be forwarded from a top level window
85 UINT m_uMsgMouseWheel; // MSH_MOUSEWHEEL
86 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_ WIN32_WCE)
87 int m_zHDelta; // current horizontal wheel value
88 int m_nHWheelChars; // number of chars to scroll on horizontal w heel
89 UINT m_uScrollFlags;
90 DWORD m_dwExtendedStyle; // scroll specific extended styles
91
92 // Constructor
93 CScrollImpl() : m_zDelta(0), m_nWheelLines(3),
94 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_ WCE)
95 m_uMsgMouseWheel(0U),
96 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_ WIN32_WCE)
97 m_zHDelta(0), m_nHWheelChars(3),
98 m_uScrollFlags(0U), m_dwExtendedStyle(0)
99 {
100 m_ptOffset.x = 0;
101 m_ptOffset.y = 0;
102 m_sizeAll.cx = 0;
103 m_sizeAll.cy = 0;
104 m_sizePage.cx = 0;
105 m_sizePage.cy = 0;
106 m_sizeLine.cx = 0;
107 m_sizeLine.cy = 0;
108 m_sizeClient.cx = 0;
109 m_sizeClient.cy = 0;
110
111 SetScrollExtendedStyle(SCRL_SCROLLCHILDREN | SCRL_ERASEBACKGROUN D);
112 }
113
114 // Attributes & Operations
115 DWORD GetScrollExtendedStyle() const
116 {
117 return m_dwExtendedStyle;
118 }
119
120 DWORD SetScrollExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
121 {
122 DWORD dwPrevStyle = m_dwExtendedStyle;
123 if(dwMask == 0)
124 m_dwExtendedStyle = dwExtendedStyle;
125 else
126 m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwE xtendedStyle & dwMask);
127 // cache scroll flags
128 T* pT = static_cast<T*>(this);
129 pT; // avoid level 4 warning
130 m_uScrollFlags = pT->uSCROLL_FLAGS | (IsScrollingChildren() ? SW _SCROLLCHILDREN : 0) | (IsErasingBackground() ? SW_ERASE : 0);
131 #if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
132 m_uScrollFlags |= (IsSmoothScroll() ? SW_SMOOTHSCROLL : 0);
133 #endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
134 return dwPrevStyle;
135 }
136
137 // offset operations
138 void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE)
139 {
140 T* pT = static_cast<T*>(this);
141 ATLASSERT(::IsWindow(pT->m_hWnd));
142
143 pT->AdjustScrollOffset(x, y);
144
145 int dx = m_ptOffset.x - x;
146 int dy = m_ptOffset.y - y;
147 m_ptOffset.x = x;
148 m_ptOffset.y = y;
149
150 // block: set horizontal scroll bar
151 {
152 SCROLLINFO si = { sizeof(SCROLLINFO) };
153 si.fMask = SIF_POS;
154 if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0)
155 si.fMask |= SIF_DISABLENOSCROLL;
156 si.nPos = m_ptOffset.x;
157 pT->SetScrollInfo(SB_HORZ, &si, bRedraw);
158 }
159
160 // block: set vertical scroll bar
161 {
162 SCROLLINFO si = { sizeof(SCROLLINFO) };
163 si.fMask = SIF_POS;
164 if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0)
165 si.fMask |= SIF_DISABLENOSCROLL;
166 si.nPos = m_ptOffset.y;
167 pT->SetScrollInfo(SB_VERT, &si, bRedraw);
168 }
169
170 // Move all children if needed
171 if(IsScrollingChildren() && (dx != 0 || dy != 0))
172 {
173 for(HWND hWndChild = ::GetWindow(pT->m_hWnd, GW_CHILD); hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT))
174 {
175 RECT rect = { 0 };
176 ::GetWindowRect(hWndChild, &rect);
177 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&re ct, 1);
178 ::SetWindowPos(hWndChild, NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
179 }
180 }
181
182 if(bRedraw)
183 pT->Invalidate();
184 }
185
186 void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE)
187 {
188 SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw);
189 }
190
191 void GetScrollOffset(POINT& ptOffset) const
192 {
193 ptOffset = m_ptOffset;
194 }
195
196 // size operations
197 void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE, bool bResetOffse t = true)
198 {
199 T* pT = static_cast<T*>(this);
200 ATLASSERT(::IsWindow(pT->m_hWnd));
201
202 m_sizeAll.cx = cx;
203 m_sizeAll.cy = cy;
204
205 int x = 0;
206 int y = 0;
207 if(!bResetOffset)
208 {
209 x = m_ptOffset.x;
210 y = m_ptOffset.y;
211 pT->AdjustScrollOffset(x, y);
212 }
213
214 int dx = m_ptOffset.x - x;
215 int dy = m_ptOffset.y - y;
216 m_ptOffset.x = x;
217 m_ptOffset.y = y;
218
219 // block: set horizontal scroll bar
220 {
221 SCROLLINFO si = { sizeof(SCROLLINFO) };
222 si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
223 if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0)
224 si.fMask |= SIF_DISABLENOSCROLL;
225 si.nMin = 0;
226 si.nMax = m_sizeAll.cx - 1;
227 si.nPage = m_sizeClient.cx;
228 si.nPos = m_ptOffset.x;
229 pT->SetScrollInfo(SB_HORZ, &si, bRedraw);
230 }
231
232 // block: set vertical scroll bar
233 {
234 SCROLLINFO si = { sizeof(SCROLLINFO) };
235 si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
236 if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0)
237 si.fMask |= SIF_DISABLENOSCROLL;
238 si.nMin = 0;
239 si.nMax = m_sizeAll.cy - 1;
240 si.nPage = m_sizeClient.cy;
241 si.nPos = m_ptOffset.y;
242 pT->SetScrollInfo(SB_VERT, &si, bRedraw);
243 }
244
245 // Move all children if needed
246 if(IsScrollingChildren() && (dx != 0 || dy != 0))
247 {
248 for(HWND hWndChild = ::GetWindow(pT->m_hWnd, GW_CHILD); hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT))
249 {
250 RECT rect = { 0 };
251 ::GetWindowRect(hWndChild, &rect);
252 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&re ct, 1);
253 ::SetWindowPos(hWndChild, NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
254 }
255 }
256
257 SetScrollLine(0, 0);
258 SetScrollPage(0, 0);
259
260 if(bRedraw)
261 pT->Invalidate();
262 }
263
264 void SetScrollSize(SIZE size, BOOL bRedraw = TRUE, bool bResetOffset = t rue)
265 {
266 SetScrollSize(size.cx, size.cy, bRedraw, bResetOffset);
267 }
268
269 void GetScrollSize(SIZE& sizeWnd) const
270 {
271 sizeWnd = m_sizeAll;
272 }
273
274 // line operations
275 void SetScrollLine(int cxLine, int cyLine)
276 {
277 ATLASSERT(cxLine >= 0 && cyLine >= 0);
278 ATLASSERT(m_sizeAll.cx != 0 && m_sizeAll.cy != 0);
279
280 m_sizeLine.cx = T::CalcLineOrPage(cxLine, m_sizeAll.cx, 100);
281 m_sizeLine.cy = T::CalcLineOrPage(cyLine, m_sizeAll.cy, 100);
282 }
283
284 void SetScrollLine(SIZE sizeLine)
285 {
286 SetScrollLine(sizeLine.cx, sizeLine.cy);
287 }
288
289 void GetScrollLine(SIZE& sizeLine) const
290 {
291 sizeLine = m_sizeLine;
292 }
293
294 // page operations
295 void SetScrollPage(int cxPage, int cyPage)
296 {
297 ATLASSERT(cxPage >= 0 && cyPage >= 0);
298 ATLASSERT(m_sizeAll.cx != 0 && m_sizeAll.cy != 0);
299
300 m_sizePage.cx = T::CalcLineOrPage(cxPage, m_sizeAll.cx, 10);
301 m_sizePage.cy = T::CalcLineOrPage(cyPage, m_sizeAll.cy, 10);
302 }
303
304 void SetScrollPage(SIZE sizePage)
305 {
306 SetScrollPage(sizePage.cx, sizePage.cy);
307 }
308
309 void GetScrollPage(SIZE& sizePage) const
310 {
311 sizePage = m_sizePage;
312 }
313
314 // commands
315 void ScrollLineDown()
316 {
317 T* pT = static_cast<T*>(this);
318 ATLASSERT(::IsWindow(pT->m_hWnd));
319 pT->DoScroll(SB_VERT, SB_LINEDOWN, (int&)m_ptOffset.y, m_sizeAll .cy, m_sizePage.cy, m_sizeLine.cy);
320 }
321
322 void ScrollLineUp()
323 {
324 T* pT = static_cast<T*>(this);
325 ATLASSERT(::IsWindow(pT->m_hWnd));
326 pT->DoScroll(SB_VERT, SB_LINEUP, (int&)m_ptOffset.y, m_sizeAll.c y, m_sizePage.cy, m_sizeLine.cy);
327 }
328
329 void ScrollPageDown()
330 {
331 T* pT = static_cast<T*>(this);
332 ATLASSERT(::IsWindow(pT->m_hWnd));
333 pT->DoScroll(SB_VERT, SB_PAGEDOWN, (int&)m_ptOffset.y, m_sizeAll .cy, m_sizePage.cy, m_sizeLine.cy);
334 }
335
336 void ScrollPageUp()
337 {
338 T* pT = static_cast<T*>(this);
339 ATLASSERT(::IsWindow(pT->m_hWnd));
340 pT->DoScroll(SB_VERT, SB_PAGEUP, (int&)m_ptOffset.y, m_sizeAll.c y, m_sizePage.cy, m_sizeLine.cy);
341 }
342
343 void ScrollTop()
344 {
345 T* pT = static_cast<T*>(this);
346 ATLASSERT(::IsWindow(pT->m_hWnd));
347 pT->DoScroll(SB_VERT, SB_TOP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
348 }
349
350 void ScrollBottom()
351 {
352 T* pT = static_cast<T*>(this);
353 ATLASSERT(::IsWindow(pT->m_hWnd));
354 pT->DoScroll(SB_VERT, SB_BOTTOM, (int&)m_ptOffset.y, m_sizeAll.c y, m_sizePage.cy, m_sizeLine.cy);
355 }
356
357 void ScrollLineRight()
358 {
359 T* pT = static_cast<T*>(this);
360 ATLASSERT(::IsWindow(pT->m_hWnd));
361 pT->DoScroll(SB_HORZ, SB_LINEDOWN, (int&)m_ptOffset.x, m_sizeAll .cx, m_sizePage.cx, m_sizeLine.cx);
362 }
363
364 void ScrollLineLeft()
365 {
366 T* pT = static_cast<T*>(this);
367 ATLASSERT(::IsWindow(pT->m_hWnd));
368 pT->DoScroll(SB_HORZ, SB_LINEUP, (int&)m_ptOffset.x, m_sizeAll.c x, m_sizePage.cx, m_sizeLine.cx);
369 }
370
371 void ScrollPageRight()
372 {
373 T* pT = static_cast<T*>(this);
374 ATLASSERT(::IsWindow(pT->m_hWnd));
375 pT->DoScroll(SB_HORZ, SB_PAGEDOWN, (int&)m_ptOffset.x, m_sizeAll .cx, m_sizePage.cx, m_sizeLine.cx);
376 }
377
378 void ScrollPageLeft()
379 {
380 T* pT = static_cast<T*>(this);
381 ATLASSERT(::IsWindow(pT->m_hWnd));
382 pT->DoScroll(SB_HORZ, SB_PAGEUP, (int&)m_ptOffset.x, m_sizeAll.c x, m_sizePage.cx, m_sizeLine.cx);
383 }
384
385 void ScrollAllLeft()
386 {
387 T* pT = static_cast<T*>(this);
388 ATLASSERT(::IsWindow(pT->m_hWnd));
389 pT->DoScroll(SB_HORZ, SB_TOP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
390 }
391
392 void ScrollAllRight()
393 {
394 T* pT = static_cast<T*>(this);
395 ATLASSERT(::IsWindow(pT->m_hWnd));
396 pT->DoScroll(SB_HORZ, SB_BOTTOM, (int&)m_ptOffset.x, m_sizeAll.c x, m_sizePage.cx, m_sizeLine.cx);
397 }
398
399 // scroll to make point/view/window visible
400 void ScrollToView(POINT pt)
401 {
402 T* pT = static_cast<T*>(this);
403 ATLASSERT(::IsWindow(pT->m_hWnd));
404 RECT rect = { pt.x, pt.y, pt.x, pt.y };
405 pT->ScrollToView(rect);
406 }
407
408 void ScrollToView(RECT& rect)
409 {
410 T* pT = static_cast<T*>(this);
411 ATLASSERT(::IsWindow(pT->m_hWnd));
412
413 RECT rcClient = { 0 };
414 pT->GetClientRect(&rcClient);
415
416 int x = m_ptOffset.x;
417 if(rect.left < m_ptOffset.x)
418 x = rect.left;
419 else if(rect.right > (m_ptOffset.x + rcClient.right))
420 x = rect.right - rcClient.right;
421
422 int y = m_ptOffset.y;
423 if(rect.top < m_ptOffset.y)
424 y = rect.top;
425 else if(rect.bottom > (m_ptOffset.y + rcClient.bottom))
426 y = rect.bottom - rcClient.bottom;
427
428 SetScrollOffset(x, y);
429 }
430
431 void ScrollToView(HWND hWnd)
432 {
433 T* pT = static_cast<T*>(this);
434 ATLASSERT(::IsWindow(pT->m_hWnd));
435
436 RECT rect = { 0 };
437 ::GetWindowRect(hWnd, &rect);
438 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 2);
439 ScrollToView(rect);
440 }
441
442 BEGIN_MSG_MAP(CScrollImpl)
443 MESSAGE_HANDLER(WM_CREATE, OnCreate)
444 MESSAGE_HANDLER(WM_VSCROLL, OnVScroll)
445 MESSAGE_HANDLER(WM_HSCROLL, OnHScroll)
446 MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
447 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_ WCE)
448 MESSAGE_HANDLER(m_uMsgMouseWheel, OnMouseWheel)
449 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_ WIN32_WCE)
450 MESSAGE_HANDLER(WM_MOUSEHWHEEL, OnMouseHWheel)
451 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
452 MESSAGE_HANDLER(WM_SIZE, OnSize)
453 MESSAGE_HANDLER(WM_PAINT, OnPaint)
454 #ifndef _WIN32_WCE
455 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
456 #endif // !_WIN32_WCE
457 // standard scroll commands
458 ALT_MSG_MAP(1)
459 COMMAND_ID_HANDLER(ID_SCROLL_UP, OnScrollUp)
460 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, OnScrollDown)
461 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, OnScrollPageUp)
462 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, OnScrollPageDown)
463 COMMAND_ID_HANDLER(ID_SCROLL_TOP, OnScrollTop)
464 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, OnScrollBottom)
465 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, OnScrollLeft)
466 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, OnScrollRight)
467 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, OnScrollPageLeft)
468 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, OnScrollPageRight)
469 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, OnScrollAllLeft)
470 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, OnScrollAllRight)
471 END_MSG_MAP()
472
473 LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BO OL& bHandled)
474 {
475 GetSystemSettings();
476 bHandled = FALSE;
477 return 1;
478 }
479
480 LRESULT OnVScroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
481 {
482 T* pT = static_cast<T*>(this);
483 ATLASSERT(::IsWindow(pT->m_hWnd));
484 pT->DoScroll(SB_VERT, (int)(short)LOWORD(wParam), (int&)m_ptOffs et.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
485 return 0;
486 }
487
488 LRESULT OnHScroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
489 {
490 T* pT = static_cast<T*>(this);
491 ATLASSERT(::IsWindow(pT->m_hWnd));
492 pT->DoScroll(SB_HORZ, (int)(short)LOWORD(wParam), (int&)m_ptOffs et.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
493 return 0;
494 }
495
496 LRESULT OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
497 {
498 T* pT = static_cast<T*>(this);
499 ATLASSERT(::IsWindow(pT->m_hWnd));
500
501 #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) || defined(_WIN32_WCE)
502 uMsg;
503 int zDelta = (int)GET_WHEEL_DELTA_WPARAM(wParam);
504 #else
505 int zDelta = (uMsg == WM_MOUSEWHEEL) ? (int)GET_WHEEL_DELTA_WPAR AM(wParam) : (int)wParam;
506 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) || defined(_WI N32_WCE))
507 int nScrollCode = (m_nWheelLines == WHEEL_PAGESCROLL) ? ((zDelta > 0) ? SB_PAGEUP : SB_PAGEDOWN) : ((zDelta > 0) ? SB_LINEUP : SB_LINEDOWN);
508 m_zDelta += zDelta; // cumulative
509 int zTotal = (m_nWheelLines == WHEEL_PAGESCROLL) ? abs(m_zDelta) : abs(m_zDelta) * m_nWheelLines;
510 if(m_sizeAll.cy > m_sizeClient.cy)
511 {
512 for(int i = 0; i < zTotal; i += WHEEL_DELTA)
513 {
514 pT->DoScroll(SB_VERT, nScrollCode, (int&)m_ptOff set.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
515 pT->UpdateWindow();
516 }
517 }
518 else // can't scroll vertically, scroll horizontally
519 {
520 for(int i = 0; i < zTotal; i += WHEEL_DELTA)
521 {
522 pT->DoScroll(SB_HORZ, nScrollCode, (int&)m_ptOff set.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
523 pT->UpdateWindow();
524 }
525 }
526 m_zDelta %= WHEEL_DELTA;
527
528 return 0;
529 }
530
531 LRESULT OnMouseHWheel(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, B OOL& /*bHandled*/)
532 {
533 T* pT = static_cast<T*>(this);
534 ATLASSERT(::IsWindow(pT->m_hWnd));
535
536 int zDelta = (int)GET_WHEEL_DELTA_WPARAM(wParam);
537 int nScrollCode = (m_nHWheelChars == WHEEL_PAGESCROLL) ? ((zDelt a > 0) ? SB_PAGERIGHT : SB_PAGELEFT) : ((zDelta > 0) ? SB_LINERIGHT : SB_LINELEF T);
538 m_zHDelta += zDelta; // cumulative
539 int zTotal = (m_nHWheelChars == WHEEL_PAGESCROLL) ? abs(m_zHDelt a) : abs(m_zHDelta) * m_nHWheelChars;
540 if(m_sizeAll.cx > m_sizeClient.cx)
541 {
542 for(int i = 0; i < zTotal; i += WHEEL_DELTA)
543 {
544 pT->DoScroll(SB_HORZ, nScrollCode, (int&)m_ptOff set.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
545 pT->UpdateWindow();
546 }
547 }
548 m_zHDelta %= WHEEL_DELTA;
549
550 return 0;
551 }
552
553 LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPara m*/, BOOL& /*bHandled*/)
554 {
555 GetSystemSettings();
556 return 0;
557 }
558
559 LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bH andled)
560 {
561 T* pT = static_cast<T*>(this);
562 ATLASSERT(::IsWindow(pT->m_hWnd));
563
564 m_sizeClient.cx = GET_X_LPARAM(lParam);
565 m_sizeClient.cy = GET_Y_LPARAM(lParam);
566
567 // block: set horizontal scroll bar
568 {
569 SCROLLINFO si = { sizeof(SCROLLINFO) };
570 si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
571 si.nMin = 0;
572 si.nMax = m_sizeAll.cx - 1;
573 if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0)
574 si.fMask |= SIF_DISABLENOSCROLL;
575 si.nPage = m_sizeClient.cx;
576 si.nPos = m_ptOffset.x;
577 pT->SetScrollInfo(SB_HORZ, &si, TRUE);
578 }
579
580 // block: set vertical scroll bar
581 {
582 SCROLLINFO si = { sizeof(SCROLLINFO) };
583 si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
584 si.nMin = 0;
585 si.nMax = m_sizeAll.cy - 1;
586 if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0)
587 si.fMask |= SIF_DISABLENOSCROLL;
588 si.nPage = m_sizeClient.cy;
589 si.nPos = m_ptOffset.y;
590 pT->SetScrollInfo(SB_VERT, &si, TRUE);
591 }
592
593 int x = m_ptOffset.x;
594 int y = m_ptOffset.y;
595 if(pT->AdjustScrollOffset(x, y))
596 {
597 // Children will be moved in SetScrollOffset, if needed
598 pT->ScrollWindowEx(m_ptOffset.x - x, m_ptOffset.y - y, ( m_uScrollFlags & ~SCRL_SCROLLCHILDREN));
599 SetScrollOffset(x, y, FALSE);
600 }
601
602 bHandled = FALSE;
603 return 1;
604 }
605
606 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& / *bHandled*/)
607 {
608 T* pT = static_cast<T*>(this);
609 ATLASSERT(::IsWindow(pT->m_hWnd));
610 if(wParam != NULL)
611 {
612 CDCHandle dc = (HDC)wParam;
613 POINT ptViewportOrg = { 0, 0 };
614 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewp ortOrg);
615 pT->DoPaint(dc);
616 dc.SetViewportOrg(ptViewportOrg);
617 }
618 else
619 {
620 CPaintDC dc(pT->m_hWnd);
621 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
622 pT->DoPaint(dc.m_hDC);
623 }
624 return 0;
625 }
626
627 // scrolling handlers
628 LRESULT OnScrollUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
629 {
630 ScrollLineUp();
631 return 0;
632 }
633
634 LRESULT OnScrollDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl* /, BOOL& /*bHandled*/)
635 {
636 ScrollLineDown();
637 return 0;
638 }
639
640 LRESULT OnScrollPageUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCt l*/, BOOL& /*bHandled*/)
641 {
642 ScrollPageUp();
643 return 0;
644 }
645
646 LRESULT OnScrollPageDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWnd Ctl*/, BOOL& /*bHandled*/)
647 {
648 ScrollPageDown();
649 return 0;
650 }
651
652 LRESULT OnScrollTop(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/ , BOOL& /*bHandled*/)
653 {
654 ScrollTop();
655 return 0;
656 }
657
658 LRESULT OnScrollBottom(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCt l*/, BOOL& /*bHandled*/)
659 {
660 ScrollBottom();
661 return 0;
662 }
663
664 LRESULT OnScrollLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl* /, BOOL& /*bHandled*/)
665 {
666 ScrollLineLeft();
667 return 0;
668 }
669
670 LRESULT OnScrollRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl */, BOOL& /*bHandled*/)
671 {
672 ScrollLineRight();
673 return 0;
674 }
675
676 LRESULT OnScrollPageLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWnd Ctl*/, BOOL& /*bHandled*/)
677 {
678 ScrollPageLeft();
679 return 0;
680 }
681
682 LRESULT OnScrollPageRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWn dCtl*/, BOOL& /*bHandled*/)
683 {
684 ScrollPageRight();
685 return 0;
686 }
687
688 LRESULT OnScrollAllLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndC tl*/, BOOL& /*bHandled*/)
689 {
690 ScrollAllLeft();
691 return 0;
692 }
693
694 LRESULT OnScrollAllRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWnd Ctl*/, BOOL& /*bHandled*/)
695 {
696 ScrollAllRight();
697 return 0;
698 }
699
700 // Overrideables
701 void DoPaint(CDCHandle /*dc*/)
702 {
703 // must be implemented in a derived class
704 ATLASSERT(FALSE);
705 }
706
707 // Implementation
708 void DoScroll(int nType, int nScrollCode, int& cxyOffset, int cxySizeAll , int cxySizePage, int cxySizeLine)
709 {
710 T* pT = static_cast<T*>(this);
711 RECT rect = { 0 };
712 pT->GetClientRect(&rect);
713 int cxyClient = (nType == SB_VERT) ? rect.bottom : rect.right;
714 int cxyMax = cxySizeAll - cxyClient;
715
716 if(cxyMax < 0) // can't scroll, client area is bigger
717 return;
718
719 bool bUpdate = true;
720 int cxyScroll = 0;
721
722 switch(nScrollCode)
723 {
724 case SB_TOP: // top or all left
725 cxyScroll = cxyOffset;
726 cxyOffset = 0;
727 break;
728 case SB_BOTTOM: // bottom or all right
729 cxyScroll = cxyOffset - cxyMax;
730 cxyOffset = cxyMax;
731 break;
732 case SB_LINEUP: // line up or line left
733 if(cxyOffset >= cxySizeLine)
734 {
735 cxyScroll = cxySizeLine;
736 cxyOffset -= cxySizeLine;
737 }
738 else
739 {
740 cxyScroll = cxyOffset;
741 cxyOffset = 0;
742 }
743 break;
744 case SB_LINEDOWN: // line down or line right
745 if(cxyOffset < cxyMax - cxySizeLine)
746 {
747 cxyScroll = -cxySizeLine;
748 cxyOffset += cxySizeLine;
749 }
750 else
751 {
752 cxyScroll = cxyOffset - cxyMax;
753 cxyOffset = cxyMax;
754 }
755 break;
756 case SB_PAGEUP: // page up or page left
757 if(cxyOffset >= cxySizePage)
758 {
759 cxyScroll = cxySizePage;
760 cxyOffset -= cxySizePage;
761 }
762 else
763 {
764 cxyScroll = cxyOffset;
765 cxyOffset = 0;
766 }
767 break;
768 case SB_PAGEDOWN: // page down or page right
769 if(cxyOffset < cxyMax - cxySizePage)
770 {
771 cxyScroll = -cxySizePage;
772 cxyOffset += cxySizePage;
773 }
774 else
775 {
776 cxyScroll = cxyOffset - cxyMax;
777 cxyOffset = cxyMax;
778 }
779 break;
780 case SB_THUMBTRACK:
781 if(IsNoThumbTracking())
782 break;
783 // else fall through
784 case SB_THUMBPOSITION:
785 {
786 SCROLLINFO si = { sizeof(SCROLLINFO), SIF_TRACKP OS };
787 if(pT->GetScrollInfo(nType, &si))
788 {
789 cxyScroll = cxyOffset - si.nTrackPos;
790 cxyOffset = si.nTrackPos;
791 }
792 }
793 break;
794 case SB_ENDSCROLL:
795 default:
796 bUpdate = false;
797 break;
798 }
799
800 if(bUpdate && cxyScroll != 0)
801 {
802 pT->SetScrollPos(nType, cxyOffset, TRUE);
803 if(nType == SB_VERT)
804 pT->ScrollWindowEx(0, cxyScroll, m_uScrollFlags) ;
805 else
806 pT->ScrollWindowEx(cxyScroll, 0, m_uScrollFlags) ;
807 }
808 }
809
810 static int CalcLineOrPage(int nVal, int nMax, int nDiv)
811 {
812 if(nVal == 0)
813 {
814 nVal = nMax / nDiv;
815 if(nVal < 1)
816 nVal = 1;
817 }
818 else if(nVal > nMax)
819 {
820 nVal = nMax;
821 }
822
823 return nVal;
824 }
825
826 bool AdjustScrollOffset(int& x, int& y)
827 {
828 int xOld = x;
829 int yOld = y;
830
831 int cxMax = m_sizeAll.cx - m_sizeClient.cx;
832 if(x > cxMax)
833 x = (cxMax >= 0) ? cxMax : 0;
834 else if(x < 0)
835 x = 0;
836
837 int cyMax = m_sizeAll.cy - m_sizeClient.cy;
838 if(y > cyMax)
839 y = (cyMax >= 0) ? cyMax : 0;
840 else if(y < 0)
841 y = 0;
842
843 return (x != xOld || y != yOld);
844 }
845
846 void GetSystemSettings()
847 {
848 #ifndef _WIN32_WCE
849 #ifndef SPI_GETWHEELSCROLLLINES
850 const UINT SPI_GETWHEELSCROLLLINES = 104;
851 #endif // !SPI_GETWHEELSCROLLLINES
852 ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &m_nWheelLine s, 0);
853
854 #ifndef SPI_GETWHEELSCROLLCHARS
855 const UINT SPI_GETWHEELSCROLLCHARS = 0x006C;
856 #endif // !SPI_GETWHEELSCROLLCHARS
857 ::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &m_nHWheelCha rs, 0);
858
859 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
860 if(m_uMsgMouseWheel != 0)
861 m_uMsgMouseWheel = ::RegisterWindowMessage(MSH_MOUSEWHEE L);
862
863 HWND hWndWheel = FindWindow(MSH_WHEELMODULE_CLASS, MSH_WHEELMODU LE_TITLE);
864 if(::IsWindow(hWndWheel))
865 {
866 UINT uMsgScrollLines = ::RegisterWindowMessage(MSH_SCROL L_LINES);
867 if(uMsgScrollLines != 0)
868 m_nWheelLines = (int)::SendMessage(hWndWheel, uM sgScrollLines, 0, 0L);
869 }
870 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
871 #endif // !_WIN32_WCE
872 }
873
874 bool IsScrollingChildren() const
875 {
876 return (m_dwExtendedStyle & SCRL_SCROLLCHILDREN) != 0;
877 }
878
879 bool IsErasingBackground() const
880 {
881 return (m_dwExtendedStyle & SCRL_ERASEBACKGROUND) != 0;
882 }
883
884 bool IsNoThumbTracking() const
885 {
886 return (m_dwExtendedStyle & SCRL_NOTHUMBTRACKING) != 0;
887 }
888
889 #if (WINVER >= 0x0500)
890 bool IsSmoothScroll() const
891 {
892 return (m_dwExtendedStyle & SCRL_SMOOTHSCROLL) != 0;
893 }
894 #endif // (WINVER >= 0x0500)
895 };
896
897
898 ///////////////////////////////////////////////////////////////////////////////
899 // CScrollWindowImpl - Implements a scrollable window
900
901 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlW inTraits>
902 class ATL_NO_VTABLE CScrollWindowImpl : public ATL::CWindowImpl<T, TBase, TWinTr aits>, public CScrollImpl< T >
903 {
904 public:
905 BEGIN_MSG_MAP(CScrollWindowImpl)
906 MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
907 MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
908 MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
909 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_ WCE)
910 MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel )
911 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_ WIN32_WCE)
912 MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
913 MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingCha nge)
914 MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
915 MESSAGE_HANDLER(WM_PAINT, CScrollImpl< T >::OnPaint)
916 #ifndef _WIN32_WCE
917 MESSAGE_HANDLER(WM_PRINTCLIENT, CScrollImpl< T >::OnPaint)
918 #endif // !_WIN32_WCE
919 ALT_MSG_MAP(1)
920 COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
921 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDow n)
922 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScroll PageUp)
923 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScro llPageDown)
924 COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
925 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollB ottom)
926 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLef t)
927 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRi ght)
928 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScro llPageLeft)
929 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScr ollPageRight)
930 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrol lAllLeft)
931 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScro llAllRight)
932 END_MSG_MAP()
933 };
934
935
936 ///////////////////////////////////////////////////////////////////////////////
937 // CMapScrollImpl - Provides mapping and scrolling support to any window
938
939 #ifndef _WIN32_WCE
940
941 template <class T>
942 class CMapScrollImpl : public CScrollImpl< T >
943 {
944 public:
945 int m_nMapMode;
946 RECT m_rectLogAll;
947 SIZE m_sizeLogLine;
948 SIZE m_sizeLogPage;
949
950 // Constructor
951 CMapScrollImpl() : m_nMapMode(MM_TEXT)
952 {
953 ::SetRectEmpty(&m_rectLogAll);
954 m_sizeLogPage.cx = 0;
955 m_sizeLogPage.cy = 0;
956 m_sizeLogLine.cx = 0;
957 m_sizeLogLine.cy = 0;
958 }
959
960 // Attributes & Operations
961 // mapping mode operations
962 void SetScrollMapMode(int nMapMode)
963 {
964 ATLASSERT(nMapMode >= MM_MIN && nMapMode <= MM_MAX_FIXEDSCALE);
965 m_nMapMode = nMapMode;
966 }
967
968 int GetScrollMapMode() const
969 {
970 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCAL E);
971 return m_nMapMode;
972 }
973
974 // offset operations
975 void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE)
976 {
977 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCAL E);
978 POINT ptOff = { x, y };
979 // block: convert logical to device units
980 {
981 CWindowDC dc(NULL);
982 dc.SetMapMode(m_nMapMode);
983 dc.LPtoDP(&ptOff);
984 }
985 CScrollImpl< T >::SetScrollOffset(ptOff, bRedraw);
986 }
987
988 void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE)
989 {
990 SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw);
991 }
992
993 void GetScrollOffset(POINT& ptOffset) const
994 {
995 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCAL E);
996 ptOffset = m_ptOffset;
997 // block: convert device to logical units
998 {
999 CWindowDC dc(NULL);
1000 dc.SetMapMode(m_nMapMode);
1001 dc.DPtoLP(&ptOffset);
1002 }
1003 }
1004
1005 // size operations
1006 void SetScrollSize(int xMin, int yMin, int xMax, int yMax, BOOL bRedraw = TRUE, bool bResetOffset = true)
1007 {
1008 ATLASSERT(xMax > xMin && yMax > yMin);
1009 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCAL E);
1010
1011 ::SetRect(&m_rectLogAll, xMin, yMin, xMax, yMax);
1012
1013 SIZE sizeAll = { 0 };
1014 sizeAll.cx = xMax - xMin + 1;
1015 sizeAll.cy = yMax - yMin + 1;
1016 // block: convert logical to device units
1017 {
1018 CWindowDC dc(NULL);
1019 dc.SetMapMode(m_nMapMode);
1020 dc.LPtoDP(&sizeAll);
1021 }
1022 CScrollImpl< T >::SetScrollSize(sizeAll, bRedraw, bResetOffset);
1023 SetScrollLine(0, 0);
1024 SetScrollPage(0, 0);
1025 }
1026
1027 void SetScrollSize(RECT& rcScroll, BOOL bRedraw = TRUE, bool bResetOffse t = true)
1028 {
1029 SetScrollSize(rcScroll.left, rcScroll.top, rcScroll.right, rcScr oll.bottom, bRedraw, bResetOffset);
1030 }
1031
1032 void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE, bool bResetOffse t = true)
1033 {
1034 SetScrollSize(0, 0, cx, cy, bRedraw, bResetOffset);
1035 }
1036
1037 void SetScrollSize(SIZE size, BOOL bRedraw = TRUE, bool bResetOffset = t rue)
1038 {
1039 SetScrollSize(0, 0, size.cx, size.cy, bRedraw, bResetOffset);
1040 }
1041
1042 void GetScrollSize(RECT& rcScroll) const
1043 {
1044 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCAL E);
1045 rcScroll = m_rectLogAll;
1046 }
1047
1048 // line operations
1049 void SetScrollLine(int cxLine, int cyLine)
1050 {
1051 ATLASSERT(cxLine >= 0 && cyLine >= 0);
1052 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCAL E);
1053
1054 m_sizeLogLine.cx = cxLine;
1055 m_sizeLogLine.cy = cyLine;
1056 SIZE sizeLine = m_sizeLogLine;
1057 // block: convert logical to device units
1058 {
1059 CWindowDC dc(NULL);
1060 dc.SetMapMode(m_nMapMode);
1061 dc.LPtoDP(&sizeLine);
1062 }
1063 CScrollImpl< T >::SetScrollLine(sizeLine);
1064 }
1065
1066 void SetScrollLine(SIZE sizeLine)
1067 {
1068 SetScrollLine(sizeLine.cx, sizeLine.cy);
1069 }
1070
1071 void GetScrollLine(SIZE& sizeLine) const
1072 {
1073 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCAL E);
1074 sizeLine = m_sizeLogLine;
1075 }
1076
1077 // page operations
1078 void SetScrollPage(int cxPage, int cyPage)
1079 {
1080 ATLASSERT(cxPage >= 0 && cyPage >= 0);
1081 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCAL E);
1082
1083 m_sizeLogPage.cx = cxPage;
1084 m_sizeLogPage.cy = cyPage;
1085 SIZE sizePage = m_sizeLogPage;
1086 // block: convert logical to device units
1087 {
1088 CWindowDC dc(NULL);
1089 dc.SetMapMode(m_nMapMode);
1090 dc.LPtoDP(&sizePage);
1091 }
1092 CScrollImpl< T >::SetScrollPage(sizePage);
1093 }
1094
1095 void SetScrollPage(SIZE sizePage)
1096 {
1097 SetScrollPage(sizePage.cx, sizePage.cy);
1098 }
1099
1100 void GetScrollPage(SIZE& sizePage) const
1101 {
1102 ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCAL E);
1103 sizePage = m_sizeLogPage;
1104 }
1105
1106 BEGIN_MSG_MAP(CMapScrollImpl)
1107 MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
1108 MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
1109 MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
1110 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1111 MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel )
1112 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1113 MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
1114 MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingCha nge)
1115 MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
1116 MESSAGE_HANDLER(WM_PAINT, OnPaint)
1117 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
1118 ALT_MSG_MAP(1)
1119 COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
1120 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDow n)
1121 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScroll PageUp)
1122 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScro llPageDown)
1123 COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
1124 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollB ottom)
1125 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLef t)
1126 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRi ght)
1127 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScro llPageLeft)
1128 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScr ollPageRight)
1129 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrol lAllLeft)
1130 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScro llAllRight)
1131 END_MSG_MAP()
1132
1133 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& / *bHandled*/)
1134 {
1135 T* pT = static_cast<T*>(this);
1136 ATLASSERT(::IsWindow(pT->m_hWnd));
1137 if(wParam != NULL)
1138 {
1139 CDCHandle dc = (HDC)wParam;
1140 int nMapModeSav = dc.GetMapMode();
1141 dc.SetMapMode(m_nMapMode);
1142 POINT ptViewportOrg = { 0, 0 };
1143 if(m_nMapMode == MM_TEXT)
1144 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg);
1145 else
1146 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y + m_sizeAll.cy, &ptViewportOrg);
1147 POINT ptWindowOrg = { 0, 0 };
1148 dc.SetWindowOrg(m_rectLogAll.left, m_rectLogAll.top, &pt WindowOrg);
1149
1150 pT->DoPaint(dc);
1151
1152 dc.SetMapMode(nMapModeSav);
1153 dc.SetViewportOrg(ptViewportOrg);
1154 dc.SetWindowOrg(ptWindowOrg);
1155 }
1156 else
1157 {
1158 CPaintDC dc(pT->m_hWnd);
1159 dc.SetMapMode(m_nMapMode);
1160 if(m_nMapMode == MM_TEXT)
1161 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
1162 else
1163 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y + m_sizeAll.cy);
1164 dc.SetWindowOrg(m_rectLogAll.left, m_rectLogAll.top);
1165 pT->DoPaint(dc.m_hDC);
1166 }
1167 return 0;
1168 }
1169 };
1170
1171 #endif // !_WIN32_WCE
1172
1173
1174 ///////////////////////////////////////////////////////////////////////////////
1175 // CMapScrollWindowImpl - Implements scrolling window with mapping
1176
1177 #ifndef _WIN32_WCE
1178
1179 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlW inTraits>
1180 class ATL_NO_VTABLE CMapScrollWindowImpl : public ATL::CWindowImpl< T, TBase, TW inTraits >, public CMapScrollImpl< T >
1181 {
1182 public:
1183 BEGIN_MSG_MAP(CMapScrollWindowImpl)
1184 MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
1185 MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
1186 MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
1187 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1188 MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel )
1189 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1190 MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
1191 MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingCha nge)
1192 MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
1193 MESSAGE_HANDLER(WM_PAINT, CMapScrollImpl< T >::OnPaint)
1194 MESSAGE_HANDLER(WM_PRINTCLIENT, CMapScrollImpl< T >::OnPaint)
1195 ALT_MSG_MAP(1)
1196 COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
1197 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDow n)
1198 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScroll PageUp)
1199 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScro llPageDown)
1200 COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
1201 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollB ottom)
1202 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLef t)
1203 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRi ght)
1204 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScro llPageLeft)
1205 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScr ollPageRight)
1206 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrol lAllLeft)
1207 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScro llAllRight)
1208 END_MSG_MAP()
1209 };
1210
1211 #endif // !_WIN32_WCE
1212
1213
1214 ///////////////////////////////////////////////////////////////////////////////
1215 // CFSBWindow - Use as a base instead of CWindow to get flat scroll bar support
1216
1217 #if defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
1218
1219 template <class TBase = ATL::CWindow>
1220 class CFSBWindowT : public TBase, public CFlatScrollBarImpl<CFSBWindowT< TBase > >
1221 {
1222 public:
1223 // Constructors
1224 CFSBWindowT(HWND hWnd = NULL) : TBase(hWnd)
1225 { }
1226
1227 CFSBWindowT< TBase >& operator =(HWND hWnd)
1228 {
1229 m_hWnd = hWnd;
1230 return *this;
1231 }
1232
1233 // CWindow overrides that use flat scroll bar API
1234 // (only those methods that are used by scroll window classes)
1235 int SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE)
1236 {
1237 ATLASSERT(::IsWindow(m_hWnd));
1238 return FlatSB_SetScrollPos(nBar, nPos, bRedraw);
1239 }
1240
1241 BOOL GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo)
1242 {
1243 ATLASSERT(::IsWindow(m_hWnd));
1244 return FlatSB_GetScrollInfo(nBar, lpScrollInfo);
1245 }
1246
1247 BOOL SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = T RUE)
1248 {
1249 ATLASSERT(::IsWindow(m_hWnd));
1250 return FlatSB_SetScrollInfo(nBar, lpScrollInfo, bRedraw);
1251 }
1252 };
1253
1254 typedef CFSBWindowT<ATL::CWindow> CFSBWindow;
1255
1256 #endif // defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400) && !defined(_WIN32_WC E)
1257
1258
1259 ///////////////////////////////////////////////////////////////////////////////
1260 // CZoomScrollImpl - Provides zooming and scrolling support to any window
1261
1262 #ifndef _WIN32_WCE
1263
1264 // The zoom modes that can be set with the SetZoomMode method
1265 enum
1266 {
1267 ZOOMMODE_OFF,
1268 ZOOMMODE_IN, // If left mouse button is clicked or dragged, zoom in on point clicked or rectangle dragged.
1269 ZOOMMODE_OUT // If left mouse button clicked, zoom out on point clicke d.
1270 };
1271
1272 // Notification to parent that zoom scale changed as a result of user mouse acti on.
1273 #define ZSN_ZOOMCHANGED (NM_FIRST - 50)
1274
1275 template <class T>
1276 class CZoomScrollImpl : public CScrollImpl< T >
1277 {
1278 public:
1279 enum { m_cxyMinZoomRect = 12 }; // min rect size to zoom in on rect.
1280
1281 // Data members
1282 SIZE m_sizeLogAll;
1283 SIZE m_sizeLogLine;
1284 SIZE m_sizeLogPage;
1285 float m_fZoomScale;
1286 float m_fZoomScaleMin;
1287 float m_fZoomDelta; // Used in ZOOMMODE_IN and ZOOMMODE_OUT on left-bu tton click.
1288 int m_nZoomMode;
1289 RECT m_rcTrack;
1290 bool m_bTracking;
1291
1292 // Constructor
1293 CZoomScrollImpl():
1294 m_fZoomScale(1.0),
1295 m_fZoomScaleMin(0.5),
1296 m_fZoomDelta(0.5),
1297 m_nZoomMode(ZOOMMODE_OFF),
1298 m_bTracking(false)
1299 {
1300 m_sizeLogAll.cx = 0;
1301 m_sizeLogAll.cy = 0;
1302 m_sizeLogPage.cx = 0;
1303 m_sizeLogPage.cy = 0;
1304 m_sizeLogLine.cx = 0;
1305 m_sizeLogLine.cy = 0;
1306 ::SetRectEmpty(&m_rcTrack);
1307 }
1308
1309 // Attributes & Operations
1310
1311 // size operations
1312 void SetScrollSize(int cxLog, int cyLog, BOOL bRedraw = TRUE, bool bRese tOffset = true)
1313 {
1314 ATLASSERT(cxLog >= 0 && cyLog >= 0);
1315
1316 // Set up the defaults
1317 if (cxLog == 0 && cyLog == 0)
1318 {
1319 cxLog = 1;
1320 cyLog = 1;
1321 }
1322
1323 m_sizeLogAll.cx = cxLog;
1324 m_sizeLogAll.cy = cyLog;
1325 SIZE sizeAll = { 0 };
1326 sizeAll.cx = (int)((float)m_sizeLogAll.cx * m_fZoomScale);
1327 sizeAll.cy = (int)((float)m_sizeLogAll.cy * m_fZoomScale);
1328
1329 CScrollImpl< T >::SetScrollSize(sizeAll, bRedraw, bResetOffset);
1330 }
1331
1332 void SetScrollSize(SIZE sizeLog, BOOL bRedraw = TRUE, bool bResetOffset = true)
1333 {
1334 SetScrollSize(sizeLog.cx, sizeLog.cy, bRedraw, bResetOffset);
1335 }
1336
1337 void GetScrollSize(SIZE& sizeLog) const
1338 {
1339 sizeLog = m_sizeLogAll;
1340 }
1341
1342 // line operations
1343 void SetScrollLine(int cxLogLine, int cyLogLine)
1344 {
1345 ATLASSERT(cxLogLine >= 0 && cyLogLine >= 0);
1346
1347 m_sizeLogLine.cx = cxLogLine;
1348 m_sizeLogLine.cy = cyLogLine;
1349
1350 SIZE sizeLine = { 0 };
1351 sizeLine.cx = (int)((float)m_sizeLogLine.cx * m_fZoomScale);
1352 sizeLine.cy = (int)((float)m_sizeLogLine.cy * m_fZoomScale);
1353 CScrollImpl< T >::SetScrollLine(sizeLine);
1354 }
1355
1356 void SetScrollLine(SIZE sizeLogLine)
1357 {
1358 SetScrollLine(sizeLogLine.cx, sizeLogLine.cy);
1359 }
1360
1361 void GetScrollLine(SIZE& sizeLogLine) const
1362 {
1363 sizeLogLine = m_sizeLogLine;
1364 }
1365
1366 // page operations
1367 void SetScrollPage(int cxLogPage, int cyLogPage)
1368 {
1369 ATLASSERT(cxLogPage >= 0 && cyLogPage >= 0);
1370
1371 m_sizeLogPage.cx = cxLogPage;
1372 m_sizeLogPage.cy = cyLogPage;
1373
1374 SIZE sizePage = { 0 };
1375 sizePage.cx = (int)((float)m_sizeLogPage.cx * m_fZoomScale);
1376 sizePage.cy = (int)((float)m_sizeLogPage.cy * m_fZoomScale);
1377
1378 CScrollImpl< T >::SetScrollPage(sizePage);
1379 }
1380
1381 void SetScrollPage(SIZE sizeLogPage)
1382 {
1383 SetScrollPage(sizeLogPage.cx, sizeLogPage.cy);
1384 }
1385
1386 void GetScrollPage(SIZE& sizeLogPage) const
1387 {
1388 sizeLogPage = m_sizeLogPage;
1389 }
1390
1391 void SetZoomScale(float fZoomScale)
1392 {
1393 ATLASSERT(fZoomScale > 0);
1394
1395 if(fZoomScale > 0 && fZoomScale >= m_fZoomScaleMin)
1396 m_fZoomScale = fZoomScale;
1397 }
1398
1399 float GetZoomScale() const
1400 {
1401 return m_fZoomScale;
1402 }
1403
1404 void SetZoomScaleMin(float fZoomScaleMin)
1405 {
1406 m_fZoomScaleMin = fZoomScaleMin;
1407 }
1408
1409 float GetZoomScaleMin() const
1410 {
1411 return m_fZoomScaleMin;
1412 }
1413
1414 void SetZoomDelta(float fZoomDelta)
1415 {
1416 ATLASSERT(fZoomDelta >= 0);
1417
1418 if(fZoomDelta >= 0)
1419 m_fZoomDelta = fZoomDelta;
1420 }
1421
1422 float GetZoomDelta() const
1423 {
1424 return m_fZoomDelta;
1425 }
1426
1427 void SetZoomMode(int nZoomMode)
1428 {
1429 m_nZoomMode = nZoomMode;
1430 }
1431
1432 int GetZoomMode() const
1433 {
1434 return m_nZoomMode;
1435 }
1436
1437 void Zoom(int x, int y, float fZoomScale)
1438 {
1439 if(fZoomScale <= 0)
1440 return;
1441
1442 fZoomScale = __max(fZoomScale, m_fZoomScaleMin);
1443
1444 T* pT = static_cast<T*>(this);
1445 POINT pt = { x, y };
1446 if(!pT->PtInDevRect(pt))
1447 return;
1448
1449 pT->ViewDPtoLP(&pt);
1450 pT->Zoom(fZoomScale, false);
1451 pT->CenterOnLogicalPoint(pt);
1452 }
1453
1454 void Zoom(POINT pt, float fZoomScale)
1455 {
1456 T* pT = static_cast<T*>(this);
1457 pT->Zoom(pt.x, pt.y, fZoomScale);
1458 }
1459
1460 void Zoom(RECT& rc)
1461 {
1462 T* pT = static_cast<T*>(this);
1463 RECT rcZoom = rc;
1464 pT->NormalizeRect(rcZoom);
1465 SIZE size = { rcZoom.right - rcZoom.left, rcZoom.bottom - rcZoom .top };
1466 POINT pt = { rcZoom.left + size.cx / 2, rcZoom.top + size.cy / 2 };
1467 if(size.cx < m_cxyMinZoomRect || size.cy < m_cxyMinZoomRect)
1468 {
1469 pT->Zoom(pt, m_fZoomScale + m_fZoomDelta);
1470 return;
1471 }
1472
1473 ATLASSERT(size.cx > 0 && size.cy > 0);
1474
1475 float fScaleH = (float)(m_sizeClient.cx + 1) / (float)size.cx;
1476 float fScaleV = (float)(m_sizeClient.cy + 1) / (float)size.cy;
1477 float fZoomScale = __min(fScaleH, fScaleV) * m_fZoomScale;
1478 pT->Zoom(pt, fZoomScale);
1479 }
1480
1481 void Zoom(float fZoomScale, bool bCenter = true)
1482 {
1483 if(fZoomScale <= 0)
1484 return;
1485
1486 fZoomScale = __max(fZoomScale, m_fZoomScaleMin);
1487
1488
1489 T* pT = static_cast<T*>(this);
1490 POINT pt = { 0 };
1491 if(bCenter)
1492 {
1493 RECT rc;
1494 ::GetClientRect(pT->m_hWnd, &rc);
1495 pt.x = rc.right / 2;
1496 pt.y = rc.bottom / 2;
1497 pT->ViewDPtoLP(&pt);
1498 }
1499
1500 // Modify the Viewport extent
1501 m_fZoomScale = fZoomScale;
1502 SIZE sizeAll = { 0 };
1503 sizeAll.cx = (int)((float)m_sizeLogAll.cx * fZoomScale);
1504 sizeAll.cy = (int)((float)m_sizeLogAll.cy * fZoomScale);
1505
1506 // Update scroll bars and window
1507 CScrollImpl< T >::SetScrollSize(sizeAll);
1508
1509 if(bCenter)
1510 pT->CenterOnLogicalPoint(pt);
1511 }
1512
1513 // Helper functions
1514 void PrepareDC(CDCHandle dc)
1515 {
1516 ATLASSERT(m_sizeAll.cx >= 0 && m_sizeAll.cy >= 0);
1517 dc.SetMapMode(MM_ANISOTROPIC);
1518 dc.SetWindowExt(m_sizeLogAll);
1519 dc.SetViewportExt(m_sizeAll);
1520 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
1521 }
1522
1523 void ViewDPtoLP(LPPOINT lpPoints, int nCount = 1)
1524 {
1525 ATLASSERT(lpPoints);
1526 T* pT = static_cast<T*>(this);
1527 ATLASSERT(::IsWindow(pT->m_hWnd));
1528
1529 CWindowDC dc(pT->m_hWnd);
1530 pT->PrepareDC(dc.m_hDC);
1531 dc.DPtoLP(lpPoints, nCount);
1532 }
1533
1534 void ViewLPtoDP(LPPOINT lpPoints, int nCount = 1)
1535 {
1536 ATLASSERT(lpPoints);
1537 T* pT = static_cast<T*>(this);
1538 ATLASSERT(::IsWindow(pT->m_hWnd));
1539
1540 CWindowDC dc(pT->m_hWnd);
1541 pT->PrepareDC(dc.m_hDC);
1542 dc.LPtoDP(lpPoints, nCount);
1543 }
1544
1545 void ClientToDevice(POINT &pt)
1546 {
1547 pt.x += m_ptOffset.x;
1548 pt.y += m_ptOffset.y;
1549 }
1550
1551 void DeviceToClient(POINT &pt)
1552 {
1553 pt.x -= m_ptOffset.x;
1554 pt.y -= m_ptOffset.y;
1555 }
1556
1557 void CenterOnPoint(POINT pt)
1558 {
1559 T* pT = static_cast<T*>(this);
1560 RECT rect;
1561 pT->GetClientRect(&rect);
1562
1563 int xOfs = pt.x - (rect.right / 2) + m_ptOffset.x;
1564 if(xOfs < 0)
1565 {
1566 xOfs = 0;
1567 }
1568 else
1569 {
1570 int xMax = __max((int)(m_sizeAll.cx - rect.right), 0);
1571 if(xOfs > xMax)
1572 xOfs = xMax;
1573 }
1574
1575 int yOfs = pt.y - (rect.bottom / 2) + m_ptOffset.y;
1576 if(yOfs < 0)
1577 {
1578 yOfs = 0;
1579 }
1580 else
1581 {
1582 int yMax = __max((int)(m_sizeAll.cy - rect.bottom), 0);
1583 if(yOfs > yMax)
1584 yOfs = yMax;
1585 }
1586
1587 CScrollImpl< T >::SetScrollOffset(xOfs, yOfs);
1588 }
1589
1590 void CenterOnLogicalPoint(POINT ptLog)
1591 {
1592 T* pT = static_cast<T*>(this);
1593 pT->ViewLPtoDP(&ptLog);
1594 pT->DeviceToClient(ptLog);
1595 pT->CenterOnPoint(ptLog);
1596 }
1597
1598 BOOL PtInDevRect(POINT pt)
1599 {
1600 RECT rc = { 0, 0, m_sizeAll.cx, m_sizeAll.cy };
1601 ::OffsetRect(&rc, -m_ptOffset.x, -m_ptOffset.y);
1602 return ::PtInRect(&rc, pt);
1603 }
1604
1605 void NormalizeRect(RECT& rc)
1606 {
1607 if(rc.left > rc.right)
1608 {
1609 int r = rc.right;
1610 rc.right = rc.left;
1611 rc.left = r;
1612 }
1613 if(rc.top > rc.bottom)
1614 {
1615 int b = rc.bottom;
1616 rc.bottom = rc.top;
1617 rc.top = b;
1618 }
1619 }
1620
1621 void DrawTrackRect()
1622 {
1623 T* pT = static_cast<T*>(this);
1624 const SIZE sizeLines = { 2, 2 };
1625 RECT rc = m_rcTrack;
1626 pT->NormalizeRect(rc);
1627 if(!::IsRectEmpty(&rc))
1628 {
1629 ::MapWindowPoints(pT->m_hWnd, NULL, (LPPOINT)&rc, 2);
1630 CWindowDC dc(NULL);
1631 dc.DrawDragRect(&rc, sizeLines, NULL, sizeLines);
1632 }
1633 }
1634
1635 void NotifyParentZoomChanged()
1636 {
1637 T* pT = static_cast<T*>(this);
1638 int nId = pT->GetDlgCtrlID();
1639 NMHDR nmhdr = { pT->m_hWnd, nId, ZSN_ZOOMCHANGED };
1640 ::SendMessage(pT->GetParent(), WM_NOTIFY, (WPARAM)nId, (LPARAM)& nmhdr);
1641 }
1642
1643 BEGIN_MSG_MAP(CZoomScrollImpl)
1644 MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
1645 MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
1646 MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
1647 MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
1648 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1649 MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel )
1650 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1651 MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
1652 MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingCha nge)
1653 MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
1654 MESSAGE_HANDLER(WM_PAINT, OnPaint)
1655 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
1656 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
1657 MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
1658 MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
1659 MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
1660 ALT_MSG_MAP(1)
1661 COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
1662 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDow n)
1663 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScroll PageUp)
1664 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScro llPageDown)
1665 COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
1666 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollB ottom)
1667 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLef t)
1668 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRi ght)
1669 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScro llPageLeft)
1670 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScr ollPageRight)
1671 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrol lAllLeft)
1672 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScro llAllRight)
1673 END_MSG_MAP()
1674
1675 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& / *bHandled*/)
1676 {
1677 T* pT = static_cast<T*>(this);
1678 ATLASSERT(::IsWindow(pT->m_hWnd));
1679 ATLASSERT(m_sizeLogAll.cx >= 0 && m_sizeLogAll.cy >= 0);
1680 ATLASSERT(m_sizeAll.cx >= 0 && m_sizeAll.cy >= 0);
1681
1682 if(wParam != NULL)
1683 {
1684 CDCHandle dc = (HDC)wParam;
1685 int nMapModeSav = dc.GetMapMode();
1686 dc.SetMapMode(MM_ANISOTROPIC);
1687 SIZE szWindowExt = { 0, 0 };
1688 dc.SetWindowExt(m_sizeLogAll, &szWindowExt);
1689 SIZE szViewportExt = { 0, 0 };
1690 dc.SetViewportExt(m_sizeAll, &szViewportExt);
1691 POINT ptViewportOrg = { 0, 0 };
1692 dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewp ortOrg);
1693
1694 pT->DoPaint(dc);
1695
1696 dc.SetMapMode(nMapModeSav);
1697 dc.SetWindowExt(szWindowExt);
1698 dc.SetViewportExt(szViewportExt);
1699 dc.SetViewportOrg(ptViewportOrg);
1700 }
1701 else
1702 {
1703 CPaintDC dc(pT->m_hWnd);
1704 pT->PrepareDC(dc.m_hDC);
1705 pT->DoPaint(dc.m_hDC);
1706 }
1707 return 0;
1708 }
1709
1710 LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, B OOL& bHandled)
1711 {
1712 if(m_nZoomMode == ZOOMMODE_IN && !m_bTracking)
1713 {
1714 T* pT = static_cast<T*>(this);
1715 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1716 if(pT->PtInDevRect(pt))
1717 {
1718 pT->SetCapture();
1719 m_bTracking = true;
1720 ::SetRect(&m_rcTrack, pt.x, pt.y, pt.x, pt.y);
1721 }
1722 }
1723 bHandled = FALSE;
1724 return 0;
1725 }
1726
1727 LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOO L& bHandled)
1728 {
1729 if(m_bTracking)
1730 {
1731 T* pT = static_cast<T*>(this);
1732 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1733 if(pT->PtInDevRect(pt))
1734 {
1735 pT->DrawTrackRect();
1736 m_rcTrack.right = pt.x;
1737 m_rcTrack.bottom = pt.y;
1738 pT->DrawTrackRect();
1739 }
1740 }
1741 bHandled = FALSE;
1742 return 0;
1743 }
1744
1745 LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOO L& bHandled)
1746 {
1747 ::ReleaseCapture();
1748 if(m_nZoomMode == ZOOMMODE_OUT)
1749 {
1750 T* pT = static_cast<T*>(this);
1751 pT->Zoom(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), m_f ZoomScale - m_fZoomDelta);
1752 pT->NotifyParentZoomChanged();
1753 }
1754 bHandled = FALSE;
1755 return 0;
1756 }
1757
1758 LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPar am*/, BOOL& bHandled)
1759 {
1760 if(m_bTracking)
1761 {
1762 m_bTracking = false;
1763 T* pT = static_cast<T*>(this);
1764 pT->DrawTrackRect();
1765 pT->Zoom(m_rcTrack);
1766 pT->NotifyParentZoomChanged();
1767 ::SetRectEmpty(&m_rcTrack);
1768 }
1769 bHandled = FALSE;
1770 return 0;
1771 }
1772
1773 LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& b Handled)
1774 {
1775 if(LOWORD(lParam) == HTCLIENT && m_nZoomMode != ZOOMMODE_OFF)
1776 {
1777 T* pT = static_cast<T*>(this);
1778 if((HWND)wParam == pT->m_hWnd)
1779 {
1780 DWORD dwPos = ::GetMessagePos();
1781 POINT pt = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(d wPos) };
1782 pT->ScreenToClient(&pt);
1783 if(pT->PtInDevRect(pt))
1784 {
1785 ::SetCursor(::LoadCursor(NULL, IDC_CROSS ));
1786 return 1;
1787 }
1788 }
1789 }
1790 bHandled = FALSE;
1791 return 0;
1792 }
1793 };
1794
1795 ///////////////////////////////////////////////////////////////////////////////
1796 // CZoomScrollWindowImpl - Implements scrolling window with zooming
1797
1798 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlW inTraits>
1799 class ATL_NO_VTABLE CZoomScrollWindowImpl : public ATL::CWindowImpl< T, TBase, T WinTraits >, public CZoomScrollImpl< T >
1800 {
1801 public:
1802 BEGIN_MSG_MAP(CZoomScrollWindowImpl)
1803 MESSAGE_HANDLER(WM_SETCURSOR, CZoomScrollImpl< T >::OnSetCursor)
1804 MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
1805 MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
1806 MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
1807 #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1808 MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel )
1809 #endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
1810 MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel)
1811 MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingCha nge)
1812 MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
1813 MESSAGE_HANDLER(WM_PAINT, CZoomScrollImpl< T >::OnPaint)
1814 MESSAGE_HANDLER(WM_PRINTCLIENT, CZoomScrollImpl< T >::OnPaint)
1815 MESSAGE_HANDLER(WM_LBUTTONDOWN, CZoomScrollImpl< T >::OnLButtonD own)
1816 MESSAGE_HANDLER(WM_MOUSEMOVE, CZoomScrollImpl< T >::OnMouseMove)
1817 MESSAGE_HANDLER(WM_LBUTTONUP, CZoomScrollImpl< T >::OnLButtonUp)
1818 MESSAGE_HANDLER(WM_CAPTURECHANGED, CZoomScrollImpl< T >::OnCaptu reChanged)
1819 ALT_MSG_MAP(1)
1820 COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
1821 COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDow n)
1822 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScroll PageUp)
1823 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScro llPageDown)
1824 COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
1825 COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollB ottom)
1826 COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLef t)
1827 COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRi ght)
1828 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScro llPageLeft)
1829 COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScr ollPageRight)
1830 COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrol lAllLeft)
1831 COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScro llAllRight)
1832 END_MSG_MAP()
1833 };
1834
1835 #endif // !_WIN32_WCE
1836
1837
1838 ///////////////////////////////////////////////////////////////////////////////
1839 // CScrollContainer
1840
1841 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlW inTraits>
1842 class ATL_NO_VTABLE CScrollContainerImpl : public CScrollWindowImpl< T, TBase, T WinTraits >
1843 {
1844 public:
1845 DECLARE_WND_CLASS_EX(NULL, 0, -1)
1846
1847 typedef CScrollWindowImpl< T, TBase, TWinTraits > _baseClass;
1848
1849 // Data members
1850 ATL::CWindow m_wndClient;
1851 bool m_bAutoSizeClient;
1852 bool m_bDrawEdgeIfEmpty;
1853
1854 // Constructor
1855 CScrollContainerImpl() : m_bAutoSizeClient(true), m_bDrawEdgeIfEmpty(fal se)
1856 {
1857 // Set CScrollWindowImpl extended style
1858 SetScrollExtendedStyle(SCRL_SCROLLCHILDREN);
1859 }
1860
1861 // Attributes
1862 HWND GetClient() const
1863 {
1864 return m_wndClient;
1865 }
1866
1867 HWND SetClient(HWND hWndClient, bool bClientSizeAsMin = true)
1868 {
1869 ATLASSERT(::IsWindow(m_hWnd));
1870
1871 HWND hWndOldClient = m_wndClient;
1872 m_wndClient = hWndClient;
1873
1874 SetRedraw(FALSE);
1875 SetScrollSize(1, 1, FALSE);
1876
1877 if(m_wndClient.m_hWnd != NULL)
1878 {
1879 m_wndClient.SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
1880
1881 if(bClientSizeAsMin)
1882 {
1883 RECT rect = { 0 };
1884 m_wndClient.GetWindowRect(&rect);
1885 if((rect.right - rect.left) > 0 && (rect.bottom - rect.top) > 0)
1886 SetScrollSize(rect.right - rect.left, re ct.bottom - rect.top, FALSE);
1887 }
1888
1889 T* pT = static_cast<T*>(this);
1890 pT->UpdateLayout();
1891 }
1892
1893 SetRedraw(TRUE);
1894 RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATE NOW | RDW_ALLCHILDREN);
1895
1896 return hWndOldClient;
1897 }
1898
1899 // Message map and handlers
1900 BEGIN_MSG_MAP(CScrollContainerImpl)
1901 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
1902 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
1903 MESSAGE_HANDLER(WM_SIZE, OnSize)
1904 CHAIN_MSG_MAP(_baseClass)
1905 FORWARD_NOTIFICATIONS()
1906 ALT_MSG_MAP(1)
1907 CHAIN_MSG_MAP_ALT(_baseClass, 1)
1908 END_MSG_MAP()
1909
1910 LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
1911 {
1912 if(m_wndClient.m_hWnd != NULL)
1913 m_wndClient.SetFocus();
1914
1915 return 0;
1916 }
1917
1918 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPa ram*/, BOOL& /*bHandled*/)
1919 {
1920 return 1; // no background needed
1921 }
1922
1923 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled */)
1924 {
1925 BOOL bTmp = TRUE;
1926 LRESULT lRet = _baseClass::OnSize(uMsg, wParam, lParam, bTmp);
1927
1928 T* pT = static_cast<T*>(this);
1929 pT->UpdateLayout();
1930
1931 return lRet;
1932 }
1933
1934 // Overrides for CScrollWindowImpl
1935 void DoPaint(CDCHandle dc)
1936 {
1937 if(!m_bAutoSizeClient || m_wndClient.m_hWnd == NULL)
1938 {
1939 T* pT = static_cast<T*>(this);
1940 RECT rect = { 0 };
1941 pT->GetContainerRect(rect);
1942
1943 if(m_bDrawEdgeIfEmpty && m_wndClient.m_hWnd == NULL)
1944 dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJ UST);
1945
1946 dc.FillRect(&rect, COLOR_APPWORKSPACE);
1947 }
1948 }
1949
1950 void ScrollToView(POINT pt)
1951 {
1952 CScrollWindowImpl< T, TBase, TWinTraits >::ScrollToView(pt);
1953 }
1954
1955 void ScrollToView(RECT& rect)
1956 {
1957 CScrollWindowImpl< T, TBase, TWinTraits >::ScrollToView(rect);
1958 }
1959
1960 void ScrollToView(HWND hWnd) // client window coordinates
1961 {
1962 T* pT = static_cast<T*>(this);
1963 pT; // avoid level 4 warning
1964 ATLASSERT(::IsWindow(pT->m_hWnd));
1965 ATLASSERT(m_wndClient.IsWindow());
1966
1967 RECT rect = { 0 };
1968 ::GetWindowRect(hWnd, &rect);
1969 ::MapWindowPoints(NULL, m_wndClient.m_hWnd, (LPPOINT)&rect, 2);
1970 ScrollToView(rect);
1971 }
1972
1973 // Implementation - overrideable methods
1974 void UpdateLayout()
1975 {
1976 ATLASSERT(::IsWindow(m_hWnd));
1977
1978 if(m_bAutoSizeClient && m_wndClient.m_hWnd != NULL)
1979 {
1980 T* pT = static_cast<T*>(this);
1981 RECT rect = { 0 };
1982 pT->GetContainerRect(rect);
1983
1984 m_wndClient.SetWindowPos(NULL, &rect, SWP_NOZORDER | SWP _NOMOVE);
1985 }
1986 else
1987 {
1988 Invalidate();
1989 }
1990 }
1991
1992 void GetContainerRect(RECT& rect)
1993 {
1994 GetClientRect(&rect);
1995
1996 if(rect.right < m_sizeAll.cx)
1997 rect.right = m_sizeAll.cx;
1998
1999 if(rect.bottom < m_sizeAll.cy)
2000 rect.bottom = m_sizeAll.cy;
2001 }
2002 };
2003
2004 class CScrollContainer : public CScrollContainerImpl<CScrollContainer>
2005 {
2006 public:
2007 DECLARE_WND_CLASS_EX(_T("WTL_ScrollContainer"), 0, -1)
2008 };
2009
2010 }; // namespace WTL
2011
2012 #endif // __ATLSCRL_H__
OLDNEW
« no previous file with comments | « third_party/wtl/include/atlresce.h ('k') | third_party/wtl/include/atlsplit.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698