Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1022 lines
30 KiB

  1. // WTL Version 3.1
  2. // Copyright (C) 1997-2000 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This file is a part of Windows Template Library.
  6. // The code and information is provided "as-is" without
  7. // warranty of any kind, either expressed or implied.
  8. #ifndef __ATLSCRL_H__
  9. #define __ATLSCRL_H__
  10. #pragma once
  11. #ifndef __cplusplus
  12. #error ATL requires C++ compilation (use a .cpp suffix)
  13. #endif
  14. #ifndef __ATLAPP_H__
  15. #error atlscrl.h requires atlapp.h to be included first
  16. #endif
  17. #ifndef __ATLWIN_H__
  18. #error atlscrl.h requires atlwin.h to be included first
  19. #endif
  20. #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
  21. #include <zmouse.h>
  22. #endif //!((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
  23. namespace WTL
  24. {
  25. /////////////////////////////////////////////////////////////////////////////
  26. // Forward declarations
  27. template <class T> class CScrollImpl;
  28. template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits> class CScrollWindowImpl;
  29. template <class T> class CMapScrollImpl;
  30. template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits> class CMapScrollWindowImpl;
  31. #if defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400)
  32. template <class TBase = CWindow> class CFSBWindowT;
  33. #endif //defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400)
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CScrollImpl - Provides scrolling support to any window
  36. // Scroll extended styles
  37. #define SCRL_SCROLLCHILDREN 0x00000001
  38. #define SCRL_ERASEBACKGROUND 0x00000002
  39. #define SCRL_NOTHUMBTRACKING 0x00000004
  40. #if (WINVER >= 0x0500)
  41. #define SCRL_SMOOTHSCROLL 0x00000008
  42. #endif //(WINVER >= 0x0500)
  43. template <class T>
  44. class CScrollImpl
  45. {
  46. public:
  47. enum { uSCROLL_FLAGS = SW_INVALIDATE };
  48. POINT m_ptOffset;
  49. SIZE m_sizeAll;
  50. SIZE m_sizeLine;
  51. SIZE m_sizePage;
  52. SIZE m_sizeClient;
  53. int m_zDelta; // current wheel value
  54. int m_nWheelLines; // number of lines to scroll on wheel
  55. #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
  56. UINT m_uMsgMouseWheel; // MSH_MOUSEWHEEL
  57. // Note that this message must be forwarded from a top level window
  58. #endif //!((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
  59. UINT m_uScrollFlags;
  60. DWORD m_dwExtendedStyle; // scroll specific extended styles
  61. // Constructor
  62. CScrollImpl() : m_zDelta(0), m_nWheelLines(3), m_uScrollFlags(0U), m_dwExtendedStyle(0)
  63. {
  64. m_ptOffset.x = 0;
  65. m_ptOffset.y = 0;
  66. m_sizeAll.cx = 0;
  67. m_sizeAll.cy = 0;
  68. m_sizePage.cx = 0;
  69. m_sizePage.cy = 0;
  70. m_sizeLine.cx = 0;
  71. m_sizeLine.cy = 0;
  72. m_sizeClient.cx = 0;
  73. m_sizeClient.cy = 0;
  74. SetScrollExtendedStyle(SCRL_SCROLLCHILDREN | SCRL_ERASEBACKGROUND);
  75. }
  76. // Attributes & Operations
  77. DWORD GetScrollExtendedStyle() const
  78. {
  79. return m_dwExtendedStyle;
  80. }
  81. DWORD SetScrollExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
  82. {
  83. DWORD dwPrevStyle = m_dwExtendedStyle;
  84. if(dwMask == 0)
  85. m_dwExtendedStyle = dwExtendedStyle;
  86. else
  87. m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
  88. // cache scroll flags
  89. T* pT = static_cast<T*>(this);
  90. pT; // avoid level 4 warning
  91. m_uScrollFlags = pT->uSCROLL_FLAGS | (IsScrollingChildren() ? SW_SCROLLCHILDREN : 0) | (IsErasingBackground() ? SW_ERASE : 0);
  92. #if (WINVER >= 0x0500)
  93. m_uScrollFlags |= (IsSmoothScroll() ? SW_SMOOTHSCROLL : 0);
  94. #endif //(WINVER >= 0x0500)
  95. return dwPrevStyle;
  96. }
  97. // offset operations
  98. void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE)
  99. {
  100. T* pT = static_cast<T*>(this);
  101. ATLASSERT(::IsWindow(pT->m_hWnd));
  102. m_ptOffset.x = x;
  103. m_ptOffset.y = y;
  104. SCROLLINFO si;
  105. si.cbSize = sizeof(si);
  106. si.fMask = SIF_POS;
  107. si.nPos = m_ptOffset.x;
  108. pT->SetScrollInfo(SB_HORZ, &si, bRedraw);
  109. si.nPos = m_ptOffset.y;
  110. pT->SetScrollInfo(SB_VERT, &si, bRedraw);
  111. if(bRedraw)
  112. pT->Invalidate();
  113. }
  114. void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE)
  115. {
  116. SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw);
  117. }
  118. void GetScrollOffset(POINT& ptOffset) const
  119. {
  120. ptOffset = m_ptOffset;
  121. }
  122. // size operations
  123. void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE)
  124. {
  125. T* pT = static_cast<T*>(this);
  126. ATLASSERT(::IsWindow(pT->m_hWnd));
  127. m_sizeAll.cx = cx;
  128. m_sizeAll.cy = cy;
  129. m_ptOffset.x = 0;
  130. m_ptOffset.y = 0;
  131. SCROLLINFO si;
  132. si.cbSize = sizeof(si);
  133. si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
  134. si.nMin = 0;
  135. si.nMax = m_sizeAll.cx - 1;
  136. si.nPage = m_sizeClient.cx;
  137. si.nPos = m_ptOffset.x;
  138. pT->SetScrollInfo(SB_HORZ, &si, bRedraw);
  139. si.nMax = m_sizeAll.cy - 1;
  140. si.nPage = m_sizeClient.cy;
  141. si.nPos = m_ptOffset.y;
  142. pT->SetScrollInfo(SB_VERT, &si, bRedraw);
  143. SetScrollLine(0, 0);
  144. SetScrollPage(0, 0);
  145. if(bRedraw)
  146. pT->Invalidate();
  147. }
  148. void SetScrollSize(SIZE size, BOOL bRedraw = TRUE)
  149. {
  150. SetScrollSize(size.cx, size.cy, bRedraw);
  151. }
  152. void GetScrollSize(SIZE& sizeWnd) const
  153. {
  154. sizeWnd = m_sizeAll;
  155. }
  156. // line operations
  157. void SetScrollLine(int cxLine, int cyLine)
  158. {
  159. ATLASSERT(cxLine >= 0 && cyLine >= 0);
  160. ATLASSERT(m_sizeAll.cx != 0 && m_sizeAll.cy != 0);
  161. m_sizeLine.cx = CalcLineOrPage(cxLine, m_sizeAll.cx, 100);
  162. m_sizeLine.cy = CalcLineOrPage(cyLine, m_sizeAll.cy, 100);
  163. }
  164. void SetScrollLine(SIZE sizeLine)
  165. {
  166. SetScrollLine(sizeLine.cx, sizeLine.cy);
  167. }
  168. void GetScrollLine(SIZE& sizeLine) const
  169. {
  170. sizeLine = m_sizeLine;
  171. }
  172. // page operations
  173. void SetScrollPage(int cxPage, int cyPage)
  174. {
  175. ATLASSERT(cxPage >= 0 && cyPage >= 0);
  176. ATLASSERT(m_sizeAll.cx != 0 && m_sizeAll.cy != 0);
  177. m_sizePage.cx = CalcLineOrPage(cxPage, m_sizeAll.cx, 10);
  178. m_sizePage.cy = CalcLineOrPage(cyPage, m_sizeAll.cy, 10);
  179. }
  180. void SetScrollPage(SIZE sizePage)
  181. {
  182. SetScrollPage(sizePage.cx, sizePage.cy);
  183. }
  184. void GetScrollPage(SIZE& sizePage) const
  185. {
  186. sizePage = m_sizePage;
  187. }
  188. // commands
  189. void ScrollLineDown()
  190. {
  191. T* pT = static_cast<T*>(this);
  192. ATLASSERT(::IsWindow(pT->m_hWnd));
  193. pT->DoScroll(SB_VERT, SB_LINEDOWN, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
  194. }
  195. void ScrollLineUp()
  196. {
  197. T* pT = static_cast<T*>(this);
  198. ATLASSERT(::IsWindow(pT->m_hWnd));
  199. pT->DoScroll(SB_VERT, SB_LINEUP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
  200. }
  201. void ScrollPageDown()
  202. {
  203. T* pT = static_cast<T*>(this);
  204. ATLASSERT(::IsWindow(pT->m_hWnd));
  205. pT->DoScroll(SB_VERT, SB_PAGEDOWN, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
  206. }
  207. void ScrollPageUp()
  208. {
  209. T* pT = static_cast<T*>(this);
  210. ATLASSERT(::IsWindow(pT->m_hWnd));
  211. pT->DoScroll(SB_VERT, SB_PAGEUP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
  212. }
  213. void ScrollTop()
  214. {
  215. T* pT = static_cast<T*>(this);
  216. ATLASSERT(::IsWindow(pT->m_hWnd));
  217. pT->DoScroll(SB_VERT, SB_TOP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
  218. }
  219. void ScrollBottom()
  220. {
  221. T* pT = static_cast<T*>(this);
  222. ATLASSERT(::IsWindow(pT->m_hWnd));
  223. pT->DoScroll(SB_VERT, SB_BOTTOM, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
  224. }
  225. void ScrollLineRight()
  226. {
  227. T* pT = static_cast<T*>(this);
  228. ATLASSERT(::IsWindow(pT->m_hWnd));
  229. pT->DoScroll(SB_HORZ, SB_LINEDOWN, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
  230. }
  231. void ScrollLineLeft()
  232. {
  233. T* pT = static_cast<T*>(this);
  234. ATLASSERT(::IsWindow(pT->m_hWnd));
  235. pT->DoScroll(SB_HORZ, SB_LINEUP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
  236. }
  237. void ScrollPageRight()
  238. {
  239. T* pT = static_cast<T*>(this);
  240. ATLASSERT(::IsWindow(pT->m_hWnd));
  241. pT->DoScroll(SB_HORZ, SB_PAGEDOWN, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
  242. }
  243. void ScrollPageLeft()
  244. {
  245. T* pT = static_cast<T*>(this);
  246. ATLASSERT(::IsWindow(pT->m_hWnd));
  247. pT->DoScroll(SB_HORZ, SB_PAGEUP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
  248. }
  249. void ScrollAllLeft()
  250. {
  251. T* pT = static_cast<T*>(this);
  252. ATLASSERT(::IsWindow(pT->m_hWnd));
  253. pT->DoScroll(SB_HORZ, SB_TOP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
  254. }
  255. void ScrollAllRight()
  256. {
  257. T* pT = static_cast<T*>(this);
  258. ATLASSERT(::IsWindow(pT->m_hWnd));
  259. pT->DoScroll(SB_HORZ, SB_BOTTOM, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
  260. }
  261. BEGIN_MSG_MAP(CScrollImpl< T >)
  262. MESSAGE_HANDLER(WM_CREATE, OnCreate)
  263. MESSAGE_HANDLER(WM_VSCROLL, OnVScroll)
  264. MESSAGE_HANDLER(WM_HSCROLL, OnHScroll)
  265. MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
  266. #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
  267. MESSAGE_HANDLER(m_uMsgMouseWheel, OnMouseWheel)
  268. #endif //(_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
  269. MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
  270. MESSAGE_HANDLER(WM_SIZE, OnSize)
  271. MESSAGE_HANDLER(WM_PAINT, OnPaint)
  272. MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
  273. // standard scroll commands
  274. ALT_MSG_MAP(1)
  275. COMMAND_ID_HANDLER(ID_SCROLL_UP, OnScrollUp)
  276. COMMAND_ID_HANDLER(ID_SCROLL_DOWN, OnScrollDown)
  277. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, OnScrollPageUp)
  278. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, OnScrollPageDown)
  279. COMMAND_ID_HANDLER(ID_SCROLL_TOP, OnScrollTop)
  280. COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, OnScrollBottom)
  281. COMMAND_ID_HANDLER(ID_SCROLL_LEFT, OnScrollLeft)
  282. COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, OnScrollRight)
  283. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, OnScrollPageLeft)
  284. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, OnScrollPageRight)
  285. COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, OnScrollAllLeft)
  286. COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, OnScrollAllRight)
  287. END_MSG_MAP()
  288. LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  289. {
  290. GetSystemSettings();
  291. bHandled = FALSE;
  292. return 1;
  293. }
  294. LRESULT OnVScroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  295. {
  296. T* pT = static_cast<T*>(this);
  297. ATLASSERT(::IsWindow(pT->m_hWnd));
  298. pT->DoScroll(SB_VERT, (int)(short)LOWORD(wParam), (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
  299. return 0;
  300. }
  301. LRESULT OnHScroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  302. {
  303. T* pT = static_cast<T*>(this);
  304. ATLASSERT(::IsWindow(pT->m_hWnd));
  305. pT->DoScroll(SB_HORZ, (int)(short)LOWORD(wParam), (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
  306. return 0;
  307. }
  308. LRESULT OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  309. {
  310. T* pT = static_cast<T*>(this);
  311. ATLASSERT(::IsWindow(pT->m_hWnd));
  312. #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
  313. uMsg;
  314. int zDelta = (int)(short)HIWORD(wParam);
  315. #else
  316. int zDelta = (uMsg == WM_MOUSEWHEEL) ? (int)(short)HIWORD(wParam) : (int)wParam;
  317. #endif //!((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
  318. int nScrollCode = (m_nWheelLines == WHEEL_PAGESCROLL) ? ((zDelta > 0) ? SB_PAGEUP : SB_PAGEDOWN) : ((zDelta > 0) ? SB_LINEUP : SB_LINEDOWN);
  319. m_zDelta += zDelta; // cumulative
  320. int zTotal = (m_nWheelLines == WHEEL_PAGESCROLL) ? abs(m_zDelta) : abs(m_zDelta) * m_nWheelLines;
  321. if((pT->GetStyle() & WS_VSCROLL) != 0)
  322. {
  323. for(short i = 0; i < zTotal; i += WHEEL_DELTA)
  324. {
  325. pT->DoScroll(SB_VERT, nScrollCode, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy);
  326. pT->UpdateWindow();
  327. }
  328. }
  329. else // can't scroll vertically, scroll horizontally
  330. {
  331. for(short i = 0; i < zTotal; i += WHEEL_DELTA)
  332. {
  333. pT->DoScroll(SB_HORZ, nScrollCode, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx);
  334. pT->UpdateWindow();
  335. }
  336. }
  337. int nSteps = m_zDelta / WHEEL_DELTA;
  338. m_zDelta -= nSteps * WHEEL_DELTA;
  339. return 0;
  340. }
  341. LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  342. {
  343. GetSystemSettings();
  344. return 0;
  345. }
  346. LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
  347. {
  348. T* pT = static_cast<T*>(this);
  349. ATLASSERT(::IsWindow(pT->m_hWnd));
  350. m_sizeClient.cx = GET_X_LPARAM(lParam);
  351. m_sizeClient.cy = GET_Y_LPARAM(lParam);
  352. SCROLLINFO si;
  353. si.cbSize = sizeof(si);
  354. si.fMask = SIF_PAGE | SIF_POS;
  355. si.nPage = m_sizeClient.cx;
  356. si.nPos = m_ptOffset.x;
  357. pT->SetScrollInfo(SB_HORZ, &si, FALSE);
  358. si.nPage = m_sizeClient.cy;
  359. si.nPos = m_ptOffset.y;
  360. pT->SetScrollInfo(SB_VERT, &si, FALSE);
  361. bool bUpdate = false;
  362. int cxMax = m_sizeAll.cx - m_sizeClient.cx;
  363. int cyMax = m_sizeAll.cy - m_sizeClient.cy;
  364. int x = m_ptOffset.x;
  365. int y = m_ptOffset.y;
  366. if(m_ptOffset.x > cxMax)
  367. {
  368. bUpdate = true;
  369. x = (cxMax >= 0) ? cxMax : 0;
  370. }
  371. if(m_ptOffset.y > cyMax)
  372. {
  373. bUpdate = true;
  374. y = (cyMax >= 0) ? cyMax : 0;
  375. }
  376. if(bUpdate)
  377. SetScrollOffset(x, y);
  378. bHandled = FALSE;
  379. return 1;
  380. }
  381. LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  382. {
  383. T* pT = static_cast<T*>(this);
  384. ATLASSERT(::IsWindow(pT->m_hWnd));
  385. if(wParam != NULL)
  386. {
  387. CDCHandle dc = (HDC)wParam;
  388. dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
  389. pT->DoPaint(dc);
  390. }
  391. else
  392. {
  393. CPaintDC dc(pT->m_hWnd);
  394. dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
  395. pT->DoPaint(dc.m_hDC);
  396. }
  397. return 0;
  398. }
  399. // scrolling handlers
  400. LRESULT OnScrollUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  401. {
  402. ScrollLineUp();
  403. return 0;
  404. }
  405. LRESULT OnScrollDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  406. {
  407. ScrollLineDown();
  408. return 0;
  409. }
  410. LRESULT OnScrollPageUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  411. {
  412. ScrollPageUp();
  413. return 0;
  414. }
  415. LRESULT OnScrollPageDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  416. {
  417. ScrollPageDown();
  418. return 0;
  419. }
  420. LRESULT OnScrollTop(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  421. {
  422. ScrollTop();
  423. return 0;
  424. }
  425. LRESULT OnScrollBottom(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  426. {
  427. ScrollBottom();
  428. return 0;
  429. }
  430. LRESULT OnScrollLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  431. {
  432. ScrollLineLeft();
  433. return 0;
  434. }
  435. LRESULT OnScrollRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  436. {
  437. ScrollLineRight();
  438. return 0;
  439. }
  440. LRESULT OnScrollPageLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  441. {
  442. ScrollPageLeft();
  443. return 0;
  444. }
  445. LRESULT OnScrollPageRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  446. {
  447. ScrollPageRight();
  448. return 0;
  449. }
  450. LRESULT OnScrollAllLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  451. {
  452. ScrollAllLeft();
  453. return 0;
  454. }
  455. LRESULT OnScrollAllRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  456. {
  457. ScrollAllRight();
  458. return 0;
  459. }
  460. // Overrideables
  461. void DoPaint(CDCHandle /*dc*/)
  462. {
  463. // must be implemented in a derived class
  464. ATLASSERT(FALSE);
  465. }
  466. // Implementation
  467. void DoScroll(int nType, int nScrollCode, int& cxyOffset, int cxySizeAll, int cxySizePage, int cxySizeLine)
  468. {
  469. T* pT = static_cast<T*>(this);
  470. RECT rect;
  471. pT->GetClientRect(&rect);
  472. int cxyClient = (nType == SB_VERT) ? rect.bottom : rect.right;
  473. int cxyMax = cxySizeAll - cxyClient;
  474. if(cxyMax < 0) // can't scroll, client area is bigger
  475. return;
  476. BOOL bUpdate = TRUE;
  477. int cxyScroll = 0;
  478. switch(nScrollCode)
  479. {
  480. case SB_TOP: // top or all left
  481. cxyScroll = cxyOffset;
  482. cxyOffset = 0;
  483. break;
  484. case SB_BOTTOM: // bottom or all right
  485. cxyScroll = cxyOffset - cxyMax;
  486. cxyOffset = cxyMax;
  487. break;
  488. case SB_LINEUP: // line up or line left
  489. if(cxyOffset >= cxySizeLine)
  490. {
  491. cxyScroll = cxySizeLine;
  492. cxyOffset -= cxySizeLine;
  493. }
  494. else
  495. {
  496. cxyScroll = cxyOffset;
  497. cxyOffset = 0;
  498. }
  499. break;
  500. case SB_LINEDOWN: // line down or line right
  501. if(cxyOffset < cxyMax - cxySizeLine)
  502. {
  503. cxyScroll = -cxySizeLine;
  504. cxyOffset += cxySizeLine;
  505. }
  506. else
  507. {
  508. cxyScroll = cxyOffset - cxyMax;
  509. cxyOffset = cxyMax;
  510. }
  511. break;
  512. case SB_PAGEUP: // page up or page left
  513. if(cxyOffset >= cxySizePage)
  514. {
  515. cxyScroll = cxySizePage;
  516. cxyOffset -= cxySizePage;
  517. }
  518. else
  519. {
  520. cxyScroll = cxyOffset;
  521. cxyOffset = 0;
  522. }
  523. break;
  524. case SB_PAGEDOWN: // page down or page right
  525. if(cxyOffset < cxyMax - cxySizePage)
  526. {
  527. cxyScroll = -cxySizePage;
  528. cxyOffset += cxySizePage;
  529. }
  530. else
  531. {
  532. cxyScroll = cxyOffset - cxyMax;
  533. cxyOffset = cxyMax;
  534. }
  535. break;
  536. case SB_THUMBTRACK:
  537. if(IsNoThumbTracking())
  538. break;
  539. // else fall through
  540. case SB_THUMBPOSITION:
  541. {
  542. SCROLLINFO si;
  543. si.cbSize = sizeof(SCROLLINFO);
  544. si.fMask = SIF_TRACKPOS;
  545. if(pT->GetScrollInfo(nType, &si))
  546. {
  547. cxyScroll = cxyOffset - si.nTrackPos;
  548. cxyOffset = si.nTrackPos;
  549. }
  550. }
  551. break;
  552. case SB_ENDSCROLL:
  553. default:
  554. bUpdate = FALSE;
  555. break;
  556. }
  557. if(bUpdate && cxyScroll != 0)
  558. {
  559. pT->SetScrollPos(nType, cxyOffset, TRUE);
  560. if(nType == SB_VERT)
  561. pT->ScrollWindowEx(0, cxyScroll, m_uScrollFlags);
  562. else
  563. pT->ScrollWindowEx(cxyScroll, 0, m_uScrollFlags);
  564. }
  565. }
  566. int CalcLineOrPage(int nVal, int nMax, int nDiv)
  567. {
  568. if(nVal == 0)
  569. {
  570. nVal = nMax / nDiv;
  571. if(nVal < 1)
  572. nVal = 1;
  573. }
  574. else if(nVal > nMax)
  575. nVal = nMax;
  576. return nVal;
  577. }
  578. void GetSystemSettings()
  579. {
  580. #ifndef SPI_GETWHEELSCROLLLINES
  581. const UINT SPI_GETWHEELSCROLLLINES = 104;
  582. #endif //!SPI_GETWHEELSCROLLLINES
  583. ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &m_nWheelLines, 0);
  584. #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
  585. if(m_uMsgMouseWheel != 0)
  586. m_uMsgMouseWheel = ::RegisterWindowMessage(MSH_MOUSEWHEEL);
  587. HWND hWndWheel = FindWindow(MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE);
  588. if(::IsWindow(hWndWheel))
  589. {
  590. UINT uMsgScrollLines = ::RegisterWindowMessage(MSH_SCROLL_LINES);
  591. if(uMsgScrollLines != 0)
  592. m_nWheelLines = ::SendMessage(hWndWheel, uMsgScrollLines, 0, 0L);
  593. }
  594. #endif //!((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
  595. }
  596. bool IsScrollingChildren() const
  597. {
  598. return (m_dwExtendedStyle & SCRL_SCROLLCHILDREN) != 0;
  599. }
  600. bool IsErasingBackground() const
  601. {
  602. return (m_dwExtendedStyle & SCRL_ERASEBACKGROUND) != 0;
  603. }
  604. bool IsNoThumbTracking() const
  605. {
  606. return (m_dwExtendedStyle & SCRL_NOTHUMBTRACKING) != 0;
  607. }
  608. #if (WINVER >= 0x0500)
  609. bool IsSmoothScroll() const
  610. {
  611. return (m_dwExtendedStyle & SCRL_SMOOTHSCROLL) != 0;
  612. }
  613. #endif //(WINVER >= 0x0500)
  614. };
  615. /////////////////////////////////////////////////////////////////////////////
  616. // CScrollWindowImpl - Implements a scrollable window
  617. template <class T, class TBase /*= CWindow */, class TWinTraits /*= CControlWinTraits */ >
  618. class ATL_NO_VTABLE CScrollWindowImpl : public CWindowImpl<T, TBase, TWinTraits>, public CScrollImpl< T >
  619. {
  620. public:
  621. BEGIN_MSG_MAP(CScrollImpl< T >)
  622. MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
  623. MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
  624. MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
  625. #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
  626. MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
  627. #endif //(_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
  628. MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
  629. MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
  630. MESSAGE_HANDLER(WM_PAINT, CScrollImpl< T >::OnPaint)
  631. MESSAGE_HANDLER(WM_PRINTCLIENT, CScrollImpl< T >::OnPaint)
  632. ALT_MSG_MAP(1)
  633. COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
  634. COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
  635. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
  636. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
  637. COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
  638. COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
  639. COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
  640. COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
  641. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
  642. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
  643. COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
  644. COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
  645. END_MSG_MAP()
  646. };
  647. /////////////////////////////////////////////////////////////////////////////
  648. // CMapScrollImpl - Provides mapping and scrolling support to any window
  649. template <class T>
  650. class CMapScrollImpl : public CScrollImpl< T >
  651. {
  652. public:
  653. int m_nMapMode;
  654. RECT m_rectLogAll;
  655. SIZE m_sizeLogLine;
  656. SIZE m_sizeLogPage;
  657. // Constructor
  658. CMapScrollImpl() : m_nMapMode(MM_TEXT)
  659. {
  660. ::SetRectEmpty(&m_rectLogAll);
  661. m_sizeLogPage.cx = 0;
  662. m_sizeLogPage.cy = 0;
  663. m_sizeLogLine.cx = 0;
  664. m_sizeLogLine.cy = 0;
  665. }
  666. // Attributes & Operations
  667. // mapping mode operations
  668. void SetScrollMapMode(int nMapMode)
  669. {
  670. ATLASSERT(nMapMode >= MM_MIN && nMapMode <= MM_MAX_FIXEDSCALE);
  671. m_nMapMode = nMapMode;
  672. }
  673. int GetScrollMapMode() const
  674. {
  675. ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
  676. return m_nMapMode;
  677. }
  678. // offset operations
  679. void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE)
  680. {
  681. ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
  682. POINT ptOff = { x, y };
  683. // block: convert logical to device units
  684. {
  685. CWindowDC dc(NULL);
  686. dc.SetMapMode(m_nMapMode);
  687. dc.LPtoDP(&ptOff);
  688. }
  689. CScrollImpl< T >::SetScrollOffset(ptOff, bRedraw);
  690. }
  691. void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE)
  692. {
  693. SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw);
  694. }
  695. void GetScrollOffset(POINT& ptOffset) const
  696. {
  697. ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
  698. ptOffset = m_ptOffset;
  699. // block: convert logical to device units
  700. {
  701. CWindowDC dc(NULL);
  702. dc.SetMapMode(m_nMapMode);
  703. dc.DPtoLP(&ptOffset);
  704. }
  705. }
  706. // size operations
  707. void SetScrollSize(int xMin, int yMin, int xMax, int yMax, BOOL bRedraw = TRUE)
  708. {
  709. ATLASSERT(xMax > xMin && yMax > yMin);
  710. ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
  711. ::SetRect(&m_rectLogAll, xMin, yMax, xMax, yMin);
  712. SIZE sizeAll;
  713. sizeAll.cx = xMax - xMin + 1;
  714. sizeAll.cy = yMax - xMin + 1;
  715. // block: convert logical to device units
  716. {
  717. CWindowDC dc(NULL);
  718. dc.SetMapMode(m_nMapMode);
  719. dc.LPtoDP(&sizeAll);
  720. }
  721. CScrollImpl< T >::SetScrollSize(sizeAll, bRedraw);
  722. SetScrollLine(0, 0);
  723. SetScrollPage(0, 0);
  724. }
  725. void SetScrollSize(RECT& rcScroll, BOOL bRedraw = TRUE)
  726. {
  727. SetScrollSize(rcScroll.left, rcScroll.top, rcScroll.right, rcScroll.bottom, bRedraw);
  728. }
  729. void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE)
  730. {
  731. SetScrollSize(0, 0, cx, cy, bRedraw);
  732. }
  733. void SetScrollSize(SIZE size, BOOL bRedraw = NULL)
  734. {
  735. SetScrollSize(0, 0, size.cx, size.cy, bRedraw);
  736. }
  737. void GetScrollSize(RECT& rcScroll) const
  738. {
  739. ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
  740. rcScroll = m_rectLogAll;
  741. }
  742. // line operations
  743. void SetScrollLine(int cxLine, int cyLine)
  744. {
  745. ATLASSERT(cxLine >= 0 && cyLine >= 0);
  746. ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
  747. m_sizeLogLine.cx = cxLine;
  748. m_sizeLogLine.cy = cyLine;
  749. SIZE sizeLine = m_sizeLogLine;
  750. // block: convert logical to device units
  751. {
  752. CWindowDC dc(NULL);
  753. dc.SetMapMode(m_nMapMode);
  754. dc.LPtoDP(&sizeLine);
  755. }
  756. CScrollImpl< T >::SetScrollLine(sizeLine);
  757. }
  758. void SetScrollLine(SIZE sizeLine)
  759. {
  760. SetScrollLine(sizeLine.cx, sizeLine.cy);
  761. }
  762. void GetScrollLine(SIZE& sizeLine) const
  763. {
  764. ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
  765. sizeLine = m_sizeLogLine;
  766. }
  767. // page operations
  768. void SetScrollPage(int cxPage, int cyPage)
  769. {
  770. ATLASSERT(cxPage >= 0 && cyPage >= 0);
  771. ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
  772. m_sizeLogPage.cx = cxPage;
  773. m_sizeLogPage.cy = cyPage;
  774. SIZE sizePage = m_sizeLogPage;
  775. // block: convert logical to device units
  776. {
  777. CWindowDC dc(NULL);
  778. dc.SetMapMode(m_nMapMode);
  779. dc.LPtoDP(&sizePage);
  780. }
  781. CScrollImpl< T >::SetScrollPage(sizePage);
  782. }
  783. void SetScrollPage(SIZE sizePage)
  784. {
  785. SetScrollPage(sizePage.cx, sizePage.cy);
  786. }
  787. void GetScrollPage(SIZE& sizePage) const
  788. {
  789. ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE);
  790. sizePage = m_sizeLogPage;
  791. }
  792. BEGIN_MSG_MAP(CMapScrollImpl< T >)
  793. MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
  794. MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
  795. MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
  796. #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
  797. MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
  798. #endif //(_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
  799. MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
  800. MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
  801. MESSAGE_HANDLER(WM_PAINT, OnPaint)
  802. MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
  803. ALT_MSG_MAP(1)
  804. COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
  805. COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
  806. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
  807. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
  808. COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
  809. COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
  810. COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
  811. COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
  812. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
  813. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
  814. COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
  815. COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
  816. END_MSG_MAP()
  817. LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  818. {
  819. T* pT = static_cast<T*>(this);
  820. ATLASSERT(::IsWindow(pT->m_hWnd));
  821. if(wParam != NULL)
  822. {
  823. CDCHandle dc = (HDC)wParam;
  824. dc.SetMapMode(m_nMapMode);
  825. if(m_nMapMode == MM_TEXT)
  826. dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
  827. else
  828. dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y + m_sizeAll.cy);
  829. dc.SetWindowOrg(m_rectLogAll.left, m_rectLogAll.bottom);
  830. pT->DoPaint(dc);
  831. }
  832. else
  833. {
  834. CPaintDC dc(pT->m_hWnd);
  835. dc.SetMapMode(m_nMapMode);
  836. if(m_nMapMode == MM_TEXT)
  837. dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
  838. else
  839. dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y + m_sizeAll.cy);
  840. dc.SetWindowOrg(m_rectLogAll.left, m_rectLogAll.bottom);
  841. pT->DoPaint(dc.m_hDC);
  842. }
  843. return 0;
  844. }
  845. };
  846. /////////////////////////////////////////////////////////////////////////////
  847. // CMapScrollWindowImpl - Implements scrolling window with mapping
  848. template <class T, class TBase /*= CWindow */, class TWinTraits /*= CControlWinTraits */ >
  849. class ATL_NO_VTABLE CMapScrollWindowImpl : public CWindowImpl< T, TBase, TWinTraits >, public CMapScrollImpl< T >
  850. {
  851. public:
  852. BEGIN_MSG_MAP(CMapScrollWindowImpl< T >)
  853. MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll)
  854. MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll)
  855. MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel)
  856. #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
  857. MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel)
  858. #endif //(_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
  859. MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange)
  860. MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize)
  861. MESSAGE_HANDLER(WM_PAINT, CMapScrollImpl< T >::OnPaint)
  862. MESSAGE_HANDLER(WM_PRINTCLIENT, CMapScrollImpl< T >::OnPaint)
  863. ALT_MSG_MAP(1)
  864. COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp)
  865. COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown)
  866. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp)
  867. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown)
  868. COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop)
  869. COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom)
  870. COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft)
  871. COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight)
  872. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft)
  873. COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight)
  874. COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft)
  875. COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight)
  876. END_MSG_MAP()
  877. };
  878. /////////////////////////////////////////////////////////////////////////////
  879. // CFSBWindow - Use as a base instead of CWindow to get flat scroll bar support
  880. #if defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400)
  881. template <class TBase /*= CWindow */ > class CFSBWindowT : public TBase, public CFlatScrollBarImpl<CFSBWindowT< TBase > >
  882. {
  883. public:
  884. // Constructors
  885. CFSBWindowT(HWND hWnd = NULL) : TBase(hWnd)
  886. { }
  887. CFSBWindowT< TBase >& operator=(HWND hWnd)
  888. {
  889. m_hWnd = hWnd;
  890. return *this;
  891. }
  892. // CWindow overrides that use flat scroll bar API
  893. // (only those methods that are used by scroll window classes)
  894. int SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE)
  895. {
  896. ATLASSERT(::IsWindow(m_hWnd));
  897. return FlatSB_SetScrollPos(nBar, nPos, bRedraw);
  898. }
  899. BOOL GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo)
  900. {
  901. ATLASSERT(::IsWindow(m_hWnd));
  902. return FlatSB_GetScrollInfo(nBar, lpScrollInfo);
  903. }
  904. BOOL SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE)
  905. {
  906. ATLASSERT(::IsWindow(m_hWnd));
  907. return FlatSB_SetScrollInfo(nBar, lpScrollInfo, bRedraw);
  908. }
  909. };
  910. typedef CFSBWindowT<CWindow> CFSBWindow;
  911. #endif //defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400)
  912. }; //namespace WTL
  913. #endif //__ATLSCRL_H__