XTPMarkupScrollViewer.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:32k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPMarkupButton.cpp: implementation of the CXTPMarkupButton class.
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Common/XTPWinThemeWrapper.h"
  22. #include "XTPMarkupContext.h"
  23. #include "XTPMarkupDrawingContext.h"
  24. #include "XTPMarkupScrollViewer.h"
  25. #include "XTPMarkupBuilder.h"
  26. #ifdef _DEBUG
  27. #undef THIS_FILE
  28. static char THIS_FILE[]=__FILE__;
  29. #define new DEBUG_NEW
  30. #endif
  31. #define XTP_HTSCROLLUP          60          // <combine CXTPScrollBase::HitTestScrollBar@POINT>
  32. #define XTP_HTSCROLLDOWN        61          // <combine CXTPScrollBase::HitTestScrollBar@POINT>
  33. #define XTP_HTSCROLLUPPAGE      62          // <combine CXTPScrollBase::HitTestScrollBar@POINT>
  34. #define XTP_HTSCROLLDOWNPAGE    63          // <combine CXTPScrollBase::HitTestScrollBar@POINT>
  35. #define XTP_HTSCROLLTHUMB       64          // <combine CXTPScrollBase::HitTestScrollBar@POINT>
  36. #define XTP_HTSCROLLPOPUP       65          // <combine CXTPScrollBase::HitTestScrollBar@POINT>
  37. #define IDSYS_SCROLL 63345
  38. IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupScrollBar, CXTPMarkupControl)
  39. void CXTPMarkupScrollBar::RegisterMarkupClass()
  40. {
  41. }
  42. CXTPMarkupScrollBar::CXTPMarkupScrollBar()
  43. {
  44. m_orientation = xtpMarkupOrientationVertical;
  45. m_pSBTrack = NULL;
  46. ZeroMemory(&m_spi, sizeof(m_spi));
  47. ZeroMemory(&m_si, sizeof(m_si));
  48. }
  49. void CXTPMarkupScrollBar::SetScrollInfo(SCROLLINFO* pScrollInfo)
  50. {
  51. if (m_si.nMax != pScrollInfo->nMax || m_si.nPage != pScrollInfo->nPage || m_si.nPos != pScrollInfo->nPos)
  52. {
  53. m_si = *pScrollInfo;
  54. m_bArrangeDirty = TRUE;
  55. }
  56. }
  57. void CXTPMarkupScrollBar::GetScrollInfo(SCROLLINFO* pScrollInfo)
  58. {
  59. *pScrollInfo = m_si;
  60. }
  61. int CXTPMarkupScrollBar::HitTestScrollBar(POINT pt) const
  62. {
  63. if (!IsEnabled())
  64. return HTNOWHERE;
  65. int px = m_spi.fVert ? pt.y : pt.x;
  66. if (!::PtInRect(&m_spi.rc, pt))
  67. return HTNOWHERE;
  68. if (px < m_spi.pxUpArrow)
  69. return XTP_HTSCROLLUP;
  70. if (m_spi.pxPopup > 0 && px > m_spi.pxPopup)
  71. return XTP_HTSCROLLPOPUP;
  72. if (px >= m_spi.pxDownArrow)
  73. return XTP_HTSCROLLDOWN;
  74. if (px < m_spi.pxThumbTop)
  75. return XTP_HTSCROLLUPPAGE;
  76. if (px < m_spi.pxThumbBottom)
  77. return XTP_HTSCROLLTHUMB;
  78. if (px < m_spi.pxDownArrow)
  79. return XTP_HTSCROLLDOWNPAGE;
  80. return HTERROR;
  81. }
  82. //////////////////////////////////////////////////////////////////////////
  83. // Scrolling
  84. void CXTPMarkupScrollBar::EndScroll(BOOL fCancel)
  85. {
  86. SCROLLBARTRACKINFO* pSBTrack = m_pSBTrack;
  87. if (pSBTrack)
  88. {
  89. pSBTrack->cmdSB = 0;
  90. ReleaseCapture();
  91. if (pSBTrack->bTrackThumb)
  92. {
  93. if (fCancel)
  94. {
  95. pSBTrack->posOld = pSBTrack->pSBInfo->pos;
  96. }
  97. DoScroll(SB_THUMBPOSITION, pSBTrack->posOld);
  98. RedrawScrollBar();
  99. }
  100. else
  101. {
  102. if (pSBTrack->hTimerSB != 0)
  103. {
  104. ::KillTimer(pSBTrack->hWndTrack, pSBTrack->hTimerSB);
  105. pSBTrack->hTimerSB = 0;
  106. }
  107. }
  108. DoScroll(SB_ENDSCROLL, 0);
  109. }
  110. }
  111. int CXTPMarkupScrollBar::SBPosFromPx(CXTPMarkupScrollBar::SCROLLBARPOSINFO*  pSBInfo, int px)
  112. {
  113. if (px < pSBInfo->pxMin)
  114. {
  115. return pSBInfo->posMin;
  116. }
  117. if (px >= pSBInfo->pxMin + pSBInfo->cpx)
  118. {
  119. return (pSBInfo->posMax - (pSBInfo->page ? pSBInfo->page - 1 : 0));
  120. }
  121. if (pSBInfo->cpx)
  122. return (pSBInfo->posMin + MulDiv(pSBInfo->posMax - pSBInfo->posMin -
  123. (pSBInfo->page ? pSBInfo->page - 1 : 0),
  124. px - pSBInfo->pxMin, pSBInfo->cpx));
  125. else
  126. return (pSBInfo->posMin - 1);
  127. }
  128. void CXTPMarkupScrollBar::MoveThumb(int px)
  129. {
  130. SCROLLBARTRACKINFO* pSBTrack = m_pSBTrack;
  131. if ((pSBTrack == NULL) || (px == pSBTrack->pxOld))
  132. return;
  133. SCROLLBARPOSINFO* pSBInfo = m_pSBTrack->pSBInfo;
  134. pxReCalc:
  135. pSBTrack->posNew = SBPosFromPx(pSBInfo, px);
  136. if (pSBTrack->posNew != pSBTrack->posOld)
  137. {
  138. DoScroll(SB_THUMBTRACK, pSBTrack->posNew);
  139. pSBTrack->posOld = pSBTrack->posNew;
  140. if (px >= pSBInfo->pxMin + pSBInfo->cpx)
  141. {
  142. px = pSBInfo->pxMin + pSBInfo->cpx;
  143. goto pxReCalc;
  144. }
  145. }
  146. pSBInfo->pxThumbTop = px;
  147. pSBInfo->pxThumbBottom = pSBInfo->pxThumbTop + pSBInfo->cpxThumb;
  148. pSBTrack->pxOld = px;
  149. RedrawScrollBar();
  150. }
  151. void CXTPMarkupScrollBar::TrackThumb(UINT message, CPoint pt)
  152. {
  153. SCROLLBARTRACKINFO* pSBTrack = m_pSBTrack;
  154. if (!pSBTrack)
  155. return;
  156. SCROLLBARPOSINFO* pSBInfo = pSBTrack->pSBInfo;
  157. if (HIBYTE(message) != HIBYTE(WM_MOUSEFIRST))
  158. return;
  159. if (pSBInfo == NULL)
  160. return;
  161. int px;
  162. if (!PtInRect(&pSBTrack->rcTrack, pt))
  163. px = pSBInfo->pxStart;
  164. else
  165. {
  166. px = (pSBTrack->pSBInfo->fVert ? pt.y : pt.x) + pSBTrack->dpxThumb;
  167. if (px < pSBInfo->pxMin)
  168. px = pSBInfo->pxMin;
  169. else if (px >= pSBInfo->pxMin + pSBInfo->cpx)
  170. px = pSBInfo->pxMin + pSBInfo->cpx;
  171. }
  172. MoveThumb(px);
  173. if (message == WM_LBUTTONUP || GetKeyState(VK_LBUTTON) >= 0)
  174. {
  175. EndScroll(FALSE);
  176. }
  177. }
  178. void CXTPMarkupScrollBar::TrackBox(UINT message, CPoint point)
  179. {
  180. SCROLLBARTRACKINFO* pSBTrack = m_pSBTrack;
  181. if (pSBTrack == NULL)
  182. return;
  183. if (message != WM_NULL && HIBYTE(message) != HIBYTE(WM_MOUSEFIRST))
  184. return;
  185. if ((pSBTrack->cmdSB == SB_PAGEUP || pSBTrack->cmdSB == SB_PAGEDOWN))
  186. {
  187. int* pLength = (int *)&pSBTrack->rcTrack;
  188. if (pSBTrack->pSBInfo->fVert)
  189. pLength++;
  190. if (pSBTrack->cmdSB == SB_PAGEUP)
  191. pLength[2] = pSBTrack->pSBInfo->pxThumbTop;
  192. else
  193. pLength[0] = pSBTrack->pSBInfo->pxThumbBottom;
  194. }
  195. BOOL fHit = PtInRect(&pSBTrack->rcTrack, point);
  196. BOOL fHitChanged = fHit != (BOOL)pSBTrack->fHitOld;
  197. if (fHitChanged)
  198. {
  199. pSBTrack->fHitOld = fHit;
  200. RedrawScrollBar();
  201. }
  202. int cmsTimer = GetDoubleClickTime() / 10;
  203. switch (message)
  204. {
  205. case WM_LBUTTONUP:
  206. EndScroll(FALSE);
  207. break;
  208. case WM_LBUTTONDOWN:
  209. pSBTrack->hTimerSB = 0;
  210. cmsTimer = GetDoubleClickTime() * 4 / 5;
  211. /*
  212. *** FALL THRU **
  213. */
  214. case WM_MOUSEMOVE:
  215. if (fHit && fHitChanged)
  216. {
  217. pSBTrack->hTimerSB = ::SetTimer(m_pSBTrack->hWndTrack, IDSYS_SCROLL, cmsTimer, NULL);
  218. DoScroll(pSBTrack->cmdSB, 0);
  219. }
  220. }
  221. }
  222. void CXTPMarkupScrollBar::ContScroll()
  223. {
  224. SCROLLBARTRACKINFO* pSBTrack = m_pSBTrack;
  225. ASSERT(pSBTrack);
  226. if (pSBTrack == NULL)
  227. return;
  228. CPoint pt;
  229. GetCursorPos(&pt);
  230. ScreenToClient(m_pSBTrack->hWndTrack, &pt);
  231. TrackBox(WM_NULL, pt);
  232. if (pSBTrack->fHitOld)
  233. {
  234. pSBTrack->hTimerSB = ::SetTimer(m_pSBTrack->hWndTrack, IDSYS_SCROLL, GetDoubleClickTime() / 10, NULL);
  235. DoScroll(pSBTrack->cmdSB, 0);
  236. }
  237. }
  238. void CXTPMarkupScrollBar::CalcTrackDragRect(SCROLLBARTRACKINFO* pSBTrack) const
  239. {
  240. int     cx;
  241. int     cy;
  242. LPINT   pwX, pwY;
  243. pwX = pwY = (LPINT)&pSBTrack->rcTrack;
  244. if (pSBTrack->pSBInfo->fVert)
  245. {
  246. cy = GetSystemMetrics(SM_CYVTHUMB);
  247. pwY++;
  248. }
  249. else
  250. {
  251. cy = GetSystemMetrics(SM_CXHTHUMB);
  252. pwX++;
  253. }
  254. cx = (pSBTrack->pSBInfo->pxRight - pSBTrack->pSBInfo->pxLeft) * 8;
  255. cy *= 2;
  256. *(pwX + 0) = pSBTrack->pSBInfo->pxLeft - cx;
  257. *(pwY + 0) = pSBTrack->pSBInfo->pxTop - cy;
  258. *(pwX + 2) = pSBTrack->pSBInfo->pxRight + cx;
  259. *(pwY + 2) = pSBTrack->pSBInfo->pxBottom + cy;
  260. }
  261. void CXTPMarkupScrollBar::DoScroll(int cmd, int pos)
  262. {
  263. CXTPMarkupScrollViewer* pViewer = MARKUP_DYNAMICCAST(CXTPMarkupScrollViewer, GetLogicalParent());
  264. if (pViewer)
  265. {
  266. pViewer->Scroll(m_spi.fVert ? SB_VERT : SB_HORZ, cmd, pos);
  267. }
  268. }
  269. void CXTPMarkupScrollBar::ScreenToClient(HWND hWnd,  LPPOINT lpPoint)
  270. {
  271. ::ScreenToClient(hWnd, lpPoint);
  272. CXTPMarkupMouseEventArgs e(0);
  273. e.m_hWnd = hWnd;
  274. e.m_point = *lpPoint;
  275. *lpPoint = e.GetPosition(this);
  276. }
  277. void CXTPMarkupScrollBar::PerformTrackInit(HWND hWnd, CPoint point, SCROLLBARPOSINFO* pSBInfo, BOOL bDirect)
  278. {
  279. int px = m_spi.fVert ? point.y : point.x;
  280. SCROLLBARTRACKINFO* pSBTrack = new SCROLLBARTRACKINFO;
  281. memset(pSBTrack, 0, sizeof(SCROLLBARTRACKINFO));
  282. pSBTrack->cmdSB = (UINT)-1;
  283. pSBTrack->bTrackThumb = FALSE;
  284. pSBTrack->pSBInfo = pSBInfo;
  285. pSBTrack->hWndTrack = hWnd;
  286. m_pSBTrack = pSBTrack;
  287. RECT rcSB;
  288. LPINT pwX = (LPINT)&rcSB;
  289. LPINT pwY = pwX + 1;
  290. if (!pSBInfo->fVert)
  291. pwX = pwY--;
  292. *(pwX + 0) = pSBInfo->pxLeft;
  293. *(pwY + 0) = pSBInfo->pxTop;
  294. *(pwX + 2) = pSBInfo->pxRight;
  295. *(pwY + 2) = pSBInfo->pxBottom;
  296. if (px < pSBInfo->pxUpArrow)
  297. {
  298. pSBInfo->ht = XTP_HTSCROLLUP;
  299. pSBTrack->cmdSB = SB_LINEUP;
  300. *(pwY + 2) = pSBInfo->pxUpArrow;
  301. }
  302. else if (px >= pSBInfo->pxDownArrow)
  303. {
  304. pSBInfo->ht = XTP_HTSCROLLDOWN;
  305. pSBTrack->cmdSB = SB_LINEDOWN;
  306. *(pwY + 0) = pSBInfo->pxDownArrow;
  307. }
  308. else if (px < pSBInfo->pxThumbTop)
  309. {
  310. pSBInfo->ht = XTP_HTSCROLLUPPAGE;
  311. pSBTrack->cmdSB = SB_PAGEUP;
  312. *(pwY + 0) = pSBInfo->pxUpArrow;
  313. *(pwY + 2) = pSBInfo->pxThumbTop;
  314. }
  315. else if (px < pSBInfo->pxThumbBottom)
  316. {
  317. pSBInfo->ht = XTP_HTSCROLLTHUMB;
  318. DoThumbPos:
  319. if (pSBInfo->pxDownArrow - pSBInfo->pxUpArrow <= pSBInfo->cpxThumb)
  320. {
  321. delete m_pSBTrack;
  322. m_pSBTrack = NULL;
  323. return;
  324. }
  325. pSBTrack->cmdSB = SB_THUMBPOSITION;
  326. CalcTrackDragRect(pSBTrack);
  327. pSBTrack->pxOld = pSBInfo->pxStart = pSBInfo->pxThumbTop;
  328. pSBTrack->posNew = pSBTrack->posOld = pSBInfo->pos;
  329. pSBTrack->dpxThumb = pSBInfo->pxStart - px;
  330. pSBTrack->bTrackThumb = TRUE;
  331. ::SetCapture(hWnd);
  332. DoScroll(SB_THUMBTRACK, pSBTrack->posOld);
  333. }
  334. else if (px < pSBInfo->pxDownArrow)
  335. {
  336. pSBInfo->ht = XTP_HTSCROLLDOWNPAGE;
  337. pSBTrack->cmdSB = SB_PAGEDOWN;
  338. *(pwY + 0) = pSBInfo->pxThumbBottom;
  339. *(pwY + 2) = pSBInfo->pxDownArrow;
  340. }
  341. if ((bDirect && pSBTrack->cmdSB != SB_LINEUP && pSBTrack->cmdSB != SB_LINEDOWN))
  342. {
  343. if (pSBTrack->cmdSB != SB_THUMBPOSITION)
  344. {
  345. goto DoThumbPos;
  346. }
  347. pSBTrack->dpxThumb = -(pSBInfo->cpxThumb / 2);
  348. }
  349. ::SetCapture(hWnd);
  350. if (pSBTrack->cmdSB != SB_THUMBPOSITION)
  351. {
  352. CopyRect(&pSBTrack->rcTrack, &rcSB);
  353. }
  354. if (!pSBTrack->bTrackThumb)
  355. {
  356. TrackBox(WM_LBUTTONDOWN, point);
  357. }
  358. else
  359. {
  360. TrackThumb(WM_LBUTTONDOWN, point);
  361. }
  362. while (::GetCapture() == hWnd)
  363. {
  364. MSG msg;
  365. while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
  366. {
  367. if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
  368. return;
  369. DispatchMessage(&msg);
  370. }
  371. if (!::GetMessage(&msg, NULL, 0, 0))
  372. {
  373. AfxPostQuitMessage((int)msg.wParam);
  374. break;
  375. }
  376. if (!IsWindow(hWnd))
  377. break;
  378. UINT cmd = msg.message;
  379. if (cmd == WM_TIMER && msg.wParam == IDSYS_SCROLL)
  380. {
  381. ContScroll();
  382. }
  383. else if (cmd >= WM_MOUSEFIRST && cmd <= WM_MOUSELAST)
  384. {
  385. CPoint ptScreen = msg.pt;
  386. ScreenToClient(hWnd, &ptScreen);
  387. if (!pSBTrack->bTrackThumb)
  388. {
  389. TrackBox(cmd, ptScreen);
  390. }
  391. else
  392. {
  393. TrackThumb(cmd, ptScreen);
  394. }
  395. }
  396. else
  397. {
  398. TranslateMessage(&msg);
  399. DispatchMessage(&msg);
  400. }
  401. }
  402. if (pSBTrack->hTimerSB != 0)
  403. {
  404. ::KillTimer(hWnd, pSBTrack->hTimerSB);
  405. }
  406. delete m_pSBTrack;
  407. m_pSBTrack = NULL;
  408. if (IsWindow(hWnd))
  409. {
  410. GetCursorPos(&point);
  411. ScreenToClient(hWnd, &point);
  412. m_spi.ht = HitTestScrollBar(point);
  413. RedrawScrollBar();
  414. }
  415. }
  416. void CXTPMarkupScrollBar::OnMouseLeave(CXTPMarkupMouseEventArgs* e)
  417. {
  418. if (m_spi.ht != HTNOWHERE)
  419. {
  420. m_spi.ht = HTNOWHERE;
  421. RedrawScrollBar();
  422. }
  423. CXTPMarkupControl::OnMouseLeave(e);
  424. }
  425. void CXTPMarkupScrollBar::OnMouseEnter(CXTPMarkupMouseEventArgs* e)
  426. {
  427. CXTPMarkupControl::OnMouseEnter(e);
  428. }
  429. void CXTPMarkupScrollBar::OnMouseMove(CXTPMarkupMouseEventArgs* e)
  430. {
  431. int ht = HitTestScrollBar(e->GetPosition(this));
  432. if (ht != m_spi.ht)
  433. {
  434. m_spi.ht = ht;
  435. RedrawScrollBar();
  436. }
  437. e->SetHandled();
  438. }
  439. void CXTPMarkupScrollBar::OnMouseLeftButtonUp(CXTPMarkupMouseButtonEventArgs* e)
  440. {
  441. CXTPMarkupControl::OnMouseLeftButtonUp(e);
  442. }
  443. void CXTPMarkupScrollBar::OnMouseLeftButtonDown(CXTPMarkupMouseButtonEventArgs* e)
  444. {
  445. e->SetHandled();
  446. if (IsEnabled())
  447. {
  448. PerformTrackInit(e->m_hWnd, e->GetPosition(this), &m_spi, (GetKeyState(VK_SHIFT) < 0) ? TRUE : FALSE);
  449. }
  450. }
  451. void CXTPMarkupScrollBar::RedrawScrollBar()
  452. {
  453. InvalidateVisual();
  454. }
  455. void CXTPMarkupScrollBar::CalcScrollBarInfo(LPRECT lprc, SCROLLBARPOSINFO* pSBInfo, SCROLLINFO* pSI)
  456. {
  457. int cpx;
  458. DWORD dwRange;
  459. int denom;
  460. BOOL fVert = pSBInfo->fVert = (m_orientation == xtpMarkupOrientationVertical);
  461. pSBInfo->rc = *lprc;
  462. pSBInfo->pxPopup = 0;
  463. if (fVert)
  464. {
  465. pSBInfo->pxTop = lprc->top;
  466. pSBInfo->pxBottom = lprc->bottom;
  467. pSBInfo->pxLeft = lprc->left;
  468. pSBInfo->pxRight = lprc->right;
  469. pSBInfo->cpxThumb = GetSystemMetrics(SM_CYVSCROLL);
  470. }
  471. else
  472. {
  473. pSBInfo->pxTop = lprc->left;
  474. pSBInfo->pxBottom = lprc->right;
  475. pSBInfo->pxLeft = lprc->top;
  476. pSBInfo->pxRight = lprc->bottom;
  477. pSBInfo->cpxThumb = GetSystemMetrics(SM_CXHSCROLL);
  478. }
  479. pSBInfo->pos = pSI->nPos;
  480. pSBInfo->page = pSI->nPage;
  481. pSBInfo->posMin = pSI->nMin;
  482. pSBInfo->posMax = pSI->nMax;
  483. dwRange = ((DWORD)(pSBInfo->posMax - pSBInfo->posMin)) + 1;
  484. cpx = min((pSBInfo->pxBottom - pSBInfo->pxTop) / 2, pSBInfo->cpxThumb);
  485. pSBInfo->pxUpArrow  = pSBInfo->pxTop    + cpx;
  486. pSBInfo->pxDownArrow = pSBInfo->pxBottom - cpx;
  487. if ((pSBInfo->page != 0) && (dwRange != 0))
  488. {
  489. int i = MulDiv(pSBInfo->pxDownArrow - pSBInfo->pxUpArrow,
  490. pSBInfo->page, dwRange);
  491. pSBInfo->cpxThumb = max(pSBInfo->cpxThumb / 2, i);
  492. }
  493. pSBInfo->pxMin = pSBInfo->pxTop + cpx;
  494. pSBInfo->cpx = pSBInfo->pxBottom - cpx - pSBInfo->cpxThumb - pSBInfo->pxMin;
  495. denom = dwRange - (pSBInfo->page ? pSBInfo->page : 1);
  496. if (denom)
  497. pSBInfo->pxThumbTop = MulDiv(pSBInfo->pos - pSBInfo->posMin,
  498. pSBInfo->cpx, denom) + pSBInfo->pxMin;
  499. else
  500. pSBInfo->pxThumbTop = pSBInfo->pxMin;
  501. pSBInfo->pxThumbBottom = pSBInfo->pxThumbTop + pSBInfo->cpxThumb;
  502. }
  503. CSize CXTPMarkupScrollBar::ArrangeOverride(CSize szFinalSize)
  504. {
  505. CalcScrollBarInfo(CRect(0, 0, szFinalSize.cx, szFinalSize.cy), &m_spi, &m_si);
  506. return szFinalSize;
  507. }
  508. CSize CXTPMarkupScrollBar::MeasureOverride(CXTPMarkupDrawingContext* /*pDC*/, CSize /*szAvailableSize*/)
  509. {
  510. BOOL bHorizontal = (m_orientation == xtpMarkupOrientationHorizontal);
  511. if (bHorizontal)
  512. return CSize(0, GetSystemMetrics(SM_CYHSCROLL));
  513. return CSize(GetSystemMetrics(SM_CXVSCROLL), 0);
  514. }
  515. BOOL CXTPMarkupScrollBar::IsEnabled() const
  516. {
  517. return m_spi.posMax - m_spi.posMin - m_spi.page + 1 > 0;
  518. }
  519. void CXTPMarkupScrollBar::OnRender(CXTPMarkupDrawingContext* pDC)
  520. {
  521. #define GETPARTSTATE(ht, pressed, hot, normal, disabled) 
  522. (!bEnabled ? disabled : nPressetHt == ht ? pressed : nHotHt == ht ? hot : normal)
  523. SCROLLBARTRACKINFO* pSBTrack = m_pSBTrack;
  524. SCROLLBARPOSINFO* pSBInfo = &m_spi;
  525. BOOL nPressetHt = pSBTrack ? (pSBTrack->bTrackThumb || pSBTrack->fHitOld ? pSBInfo->ht : -1) : -1;
  526. BOOL nHotHt = pSBTrack ? -1 : pSBInfo->ht;
  527. int cWidth = (pSBInfo->pxRight - pSBInfo->pxLeft);
  528. if (cWidth <= 0)
  529. {
  530. return;
  531. }
  532. BOOL bEnabled = IsEnabled();
  533. int nBtnTrackSize =   pSBInfo->pxThumbBottom - pSBInfo->pxThumbTop;
  534. int nBtnTrackPos = pSBInfo->pxThumbTop - pSBInfo->pxUpArrow;
  535. if (!bEnabled || pSBInfo->pxThumbBottom > pSBInfo->pxDownArrow)
  536. nBtnTrackPos = nBtnTrackSize = 0;
  537. BOOL bUseVisualStyle = TRUE;
  538. CXTPWinThemeWrapper m_themeScrollBar;
  539. m_themeScrollBar.OpenTheme(0, L"SCROLLBAR");
  540. COLORREF clrFace = GetSysColor(COLOR_3DFACE);
  541. COLORREF m_crBackHilite = clrFace, m_crBackPushed = clrFace, m_crBack = clrFace;
  542. if (pSBInfo->fVert)
  543. {
  544. CRect rcVScroll(pSBInfo->rc);
  545. CRect rcArrowUp(rcVScroll.left, rcVScroll.top, rcVScroll.right, pSBInfo->pxUpArrow);
  546. CRect rcArrowDown(rcVScroll.left, pSBInfo->pxDownArrow, rcVScroll.right, rcVScroll.bottom);
  547. CRect rcTrack(rcVScroll.left, rcArrowUp.bottom, rcVScroll.right, rcArrowDown.top);
  548. CRect rcLowerTrack(rcTrack.left, rcTrack.top, rcTrack.right, rcTrack.top + nBtnTrackPos);
  549. CRect rcBtnTrack(rcTrack.left, rcLowerTrack.bottom, rcTrack.right, rcLowerTrack.bottom + nBtnTrackSize);
  550. CRect rcUpperTrack(rcTrack.left, rcBtnTrack.bottom, rcTrack.right, rcTrack.bottom);
  551. if (bUseVisualStyle  && m_themeScrollBar.IsAppThemed())
  552. {
  553. m_themeScrollBar.DrawThemeBackground(pDC->GetSafeHdc(), SBP_ARROWBTN, GETPARTSTATE(XTP_HTSCROLLUP, ABS_UPPRESSED, ABS_UPHOT, ABS_UPNORMAL, ABS_UPDISABLED),  rcArrowUp, NULL);
  554. m_themeScrollBar.DrawThemeBackground(pDC->GetSafeHdc(), SBP_ARROWBTN, GETPARTSTATE(XTP_HTSCROLLDOWN, ABS_DOWNPRESSED, ABS_DOWNHOT, ABS_DOWNNORMAL, ABS_DOWNDISABLED),  rcArrowDown, NULL);
  555. if (!rcTrack.IsRectEmpty())
  556. {
  557. if (!rcLowerTrack.IsRectEmpty())
  558. m_themeScrollBar.DrawThemeBackground(pDC->GetSafeHdc(), SBP_LOWERTRACKVERT, GETPARTSTATE(XTP_HTSCROLLUPPAGE, SCRBS_PRESSED, SCRBS_HOT, SCRBS_NORMAL, SCRBS_DISABLED),  rcLowerTrack, NULL);
  559. if (!rcBtnTrack.IsRectEmpty())
  560. {
  561. m_themeScrollBar.DrawThemeBackground(pDC->GetSafeHdc(), SBP_THUMBBTNVERT, GETPARTSTATE(XTP_HTSCROLLTHUMB, SCRBS_PRESSED, SCRBS_HOT, SCRBS_NORMAL, SCRBS_DISABLED),  rcBtnTrack, NULL);
  562. if (rcBtnTrack.Height() > 13)
  563. m_themeScrollBar.DrawThemeBackground(pDC->GetSafeHdc(), SBP_GRIPPERVERT, GETPARTSTATE(XTP_HTSCROLLTHUMB, SCRBS_PRESSED, SCRBS_HOT, SCRBS_NORMAL, SCRBS_DISABLED),  rcBtnTrack, NULL);
  564. }
  565. if (!rcUpperTrack.IsRectEmpty())
  566. m_themeScrollBar.DrawThemeBackground(pDC->GetSafeHdc(), SBP_UPPERTRACKVERT, GETPARTSTATE(XTP_HTSCROLLDOWNPAGE, SCRBS_PRESSED, SCRBS_HOT, SCRBS_NORMAL, SCRBS_DISABLED),  rcUpperTrack, NULL);
  567. }
  568. }
  569. else
  570. {
  571. {
  572. DrawFrameControl(pDC->GetSafeHdc(), &rcArrowUp, DFC_SCROLL, DFCS_SCROLLUP | (!bEnabled ? DFCS_INACTIVE : 0) | (nPressetHt == XTP_HTSCROLLUP ? DFCS_PUSHED : 0));
  573. DrawFrameControl(pDC->GetSafeHdc(), &rcArrowDown, DFC_SCROLL, DFCS_SCROLLDOWN | (!bEnabled ? DFCS_INACTIVE : 0)  | (nPressetHt == XTP_HTSCROLLDOWN ? DFCS_PUSHED : 0));
  574. }
  575. HBRUSH hbrRet = (HBRUSH)SendMessage(::GetDesktopWindow(), WM_CTLCOLORSCROLLBAR, (WPARAM)pDC->GetSafeHdc(), 0);
  576. SetBkColor(pDC->GetSafeHdc(), GetSysColor(COLOR_3DHILIGHT));
  577. SetTextColor(pDC->GetSafeHdc(), GetSysColor(COLOR_BTNFACE));
  578. ::FillRect(pDC->GetSafeHdc(), &rcTrack, hbrRet);
  579. if (nPressetHt == XTP_HTSCROLLUPPAGE)
  580. {
  581. ::InvertRect(pDC->GetSafeHdc(), &rcLowerTrack);
  582. }
  583. if (!rcTrack.IsRectEmpty() && !rcBtnTrack.IsRectEmpty())
  584. {
  585. pDC->FillSolidRect(rcBtnTrack, nPressetHt == XTP_HTSCROLLTHUMB ? m_crBackPushed : nHotHt == XTP_HTSCROLLTHUMB ? m_crBackHilite : m_crBack);
  586. DrawEdge(pDC->GetSafeHdc(), &rcBtnTrack, EDGE_RAISED, (UINT)(BF_ADJUST | BF_RECT));
  587. }
  588. if (nPressetHt == XTP_HTSCROLLDOWNPAGE)
  589. {
  590. ::InvertRect(pDC->GetSafeHdc(), &rcUpperTrack);
  591. }
  592. }
  593. }
  594. else
  595. {
  596. CRect rcHScroll(pSBInfo->rc);
  597. CRect rcArrowLeft(rcHScroll.left, rcHScroll.top, pSBInfo->pxUpArrow, rcHScroll.bottom);
  598. CRect rcArrowRight(pSBInfo->pxDownArrow, rcHScroll.top, rcHScroll.right, rcHScroll.bottom);
  599. CRect rcTrack(rcArrowLeft.right, rcHScroll.top, rcArrowRight.left, rcHScroll.bottom);
  600. CRect rcLowerTrack(rcTrack.left, rcTrack.top, rcTrack.left + nBtnTrackPos, rcTrack.bottom);
  601. CRect rcBtnTrack(rcLowerTrack.right, rcTrack.top, rcLowerTrack.right + nBtnTrackSize, rcTrack.bottom);
  602. CRect rcUpperTrack(rcBtnTrack.right, rcTrack.top, rcTrack.right, rcTrack.bottom);
  603. if (bUseVisualStyle  && m_themeScrollBar.IsAppThemed())
  604. {
  605. m_themeScrollBar.DrawThemeBackground(pDC->GetSafeHdc(), SBP_ARROWBTN, GETPARTSTATE(XTP_HTSCROLLUP, ABS_LEFTPRESSED, ABS_LEFTHOT, ABS_LEFTNORMAL, ABS_LEFTDISABLED),  rcArrowLeft, NULL);
  606. m_themeScrollBar.DrawThemeBackground(pDC->GetSafeHdc(), SBP_ARROWBTN, GETPARTSTATE(XTP_HTSCROLLDOWN, ABS_RIGHTPRESSED, ABS_RIGHTHOT, ABS_RIGHTNORMAL, ABS_RIGHTDISABLED),  rcArrowRight, NULL);
  607. if (!rcTrack.IsRectEmpty())
  608. {
  609. if (!rcLowerTrack.IsRectEmpty())
  610. m_themeScrollBar.DrawThemeBackground(pDC->GetSafeHdc(), SBP_LOWERTRACKHORZ, GETPARTSTATE(XTP_HTSCROLLUPPAGE, SCRBS_PRESSED, SCRBS_HOT, SCRBS_NORMAL, SCRBS_DISABLED),  rcLowerTrack, NULL);
  611. if (!rcBtnTrack.IsRectEmpty())
  612. {
  613. m_themeScrollBar.DrawThemeBackground(pDC->GetSafeHdc(), SBP_THUMBBTNHORZ, GETPARTSTATE(XTP_HTSCROLLTHUMB, SCRBS_PRESSED, SCRBS_HOT, SCRBS_NORMAL, SCRBS_DISABLED),  rcBtnTrack, NULL);
  614. if (rcBtnTrack.Width() > 13)
  615. m_themeScrollBar.DrawThemeBackground(pDC->GetSafeHdc(), SBP_GRIPPERHORZ, GETPARTSTATE(XTP_HTSCROLLTHUMB, SCRBS_PRESSED, SCRBS_HOT, SCRBS_NORMAL, SCRBS_DISABLED),  rcBtnTrack, NULL);
  616. }
  617. if (!rcUpperTrack.IsRectEmpty())
  618. m_themeScrollBar.DrawThemeBackground(pDC->GetSafeHdc(), SBP_UPPERTRACKHORZ, GETPARTSTATE(XTP_HTSCROLLDOWNPAGE, SCRBS_PRESSED, SCRBS_HOT, SCRBS_NORMAL, SCRBS_DISABLED),  rcUpperTrack, NULL);
  619. }
  620. }
  621. else
  622. {
  623. {
  624. DrawFrameControl(pDC->GetSafeHdc(), &rcArrowLeft, DFC_SCROLL, DFCS_SCROLLLEFT | (!bEnabled ? DFCS_INACTIVE : 0) | (nPressetHt == XTP_HTSCROLLUP ? DFCS_PUSHED : 0));
  625. DrawFrameControl(pDC->GetSafeHdc(), &rcArrowRight, DFC_SCROLL, DFCS_SCROLLRIGHT | (!bEnabled ? DFCS_INACTIVE : 0)  | (nPressetHt == XTP_HTSCROLLDOWN ? DFCS_PUSHED : 0));
  626. }
  627. HBRUSH hbrRet = (HBRUSH)SendMessage(::GetDesktopWindow(), WM_CTLCOLORSCROLLBAR, (WPARAM)pDC->GetSafeHdc(), 0);
  628. SetBkColor(pDC->GetSafeHdc(), GetSysColor(COLOR_3DHILIGHT));
  629. SetTextColor(pDC->GetSafeHdc(), GetSysColor(COLOR_BTNFACE));
  630. ::FillRect(pDC->GetSafeHdc(), &rcTrack, hbrRet);
  631. if (nPressetHt == XTP_HTSCROLLUPPAGE)
  632. {
  633. ::InvertRect(pDC->GetSafeHdc(), &rcLowerTrack);
  634. }
  635. if (!rcTrack.IsRectEmpty() && !rcBtnTrack.IsRectEmpty())
  636. {
  637. pDC->FillSolidRect(rcBtnTrack, nPressetHt == XTP_HTSCROLLTHUMB ? m_crBackPushed : nHotHt == XTP_HTSCROLLTHUMB ? m_crBackHilite : m_crBack);
  638. {
  639. DrawEdge(pDC->GetSafeHdc(), &rcBtnTrack, EDGE_RAISED, (UINT)(BF_ADJUST | BF_RECT));
  640. }
  641. }
  642. if (nPressetHt == XTP_HTSCROLLDOWNPAGE)
  643. {
  644. ::InvertRect(pDC->GetSafeHdc(), &rcUpperTrack);
  645. }
  646. }
  647. }
  648. }
  649. //////////////////////////////////////////////////////////////////////////
  650. // CXTPMarkupScrollBarGripper
  651. class CXTPMarkupScrollBarGripper : public CXTPMarkupUIElement
  652. {
  653. DECLARE_MARKUPCLASS(CXTPMarkupScrollBarGripper)
  654. public:
  655. void OnRender(CXTPMarkupDrawingContext* pDC);
  656. };
  657. IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupScrollBarGripper, CXTPMarkupUIElement)
  658. void CXTPMarkupScrollBarGripper::RegisterMarkupClass()
  659. {
  660. }
  661. void CXTPMarkupScrollBarGripper::OnRender(CXTPMarkupDrawingContext* pDC)
  662. {
  663. CRect rc(GetFinalRect());
  664. pDC->FillSolidRect(rc, GetSysColor(COLOR_BTNFACE));
  665. }
  666. //////////////////////////////////////////////////////////////////////////
  667. // CXTPMarkupScrollViewer
  668. CXTPMarkupDependencyProperty* CXTPMarkupScrollViewer::m_pVerticalScrollBarVisibilityProperty = NULL;
  669. CXTPMarkupDependencyProperty* CXTPMarkupScrollViewer::m_pHorizontalScrollBarVisibilityProperty = NULL;
  670. IMPLEMENT_MARKUPCLASS(L"ScrollViewer", CXTPMarkupScrollViewer, CXTPMarkupContentControl)
  671. void CXTPMarkupScrollViewer::RegisterMarkupClass()
  672. {
  673. m_pVerticalScrollBarVisibilityProperty = CXTPMarkupDependencyProperty::Register(L"VerticalScrollBarVisibility", MARKUP_TYPE(CXTPMarkupEnum), MARKUP_TYPE(CXTPMarkupScrollViewer),
  674. new CXTPMarkupPropertyMetadata(NULL, &CXTPMarkupBuilder::ConvertScrollBarVisibility, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  675. m_pHorizontalScrollBarVisibilityProperty = CXTPMarkupDependencyProperty::Register(L"HorizontalScrollBarVisibility", MARKUP_TYPE(CXTPMarkupEnum), MARKUP_TYPE(CXTPMarkupScrollViewer),
  676. new CXTPMarkupPropertyMetadata(NULL, &CXTPMarkupBuilder::ConvertScrollBarVisibility, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  677. }
  678. CXTPMarkupScrollViewer::CXTPMarkupScrollViewer()
  679. {
  680. m_pVerticalScrollBar = NULL;
  681. m_pHorizontalScrollBar = NULL;
  682. m_pScrollBarGripper = NULL;
  683. m_xOffset = m_yOffset = 0;
  684. SetValue(m_pClipToBoundsProperty, CXTPMarkupBool::CreateTrueValue());
  685. }
  686. CXTPMarkupScrollViewer::~CXTPMarkupScrollViewer()
  687. {
  688. MARKUP_RELEASE(m_pVerticalScrollBar);
  689. MARKUP_RELEASE(m_pHorizontalScrollBar);
  690. MARKUP_RELEASE(m_pScrollBarGripper);
  691. }
  692. int CXTPMarkupScrollViewer::GetVisualChildrenCount() const
  693. {
  694. return (GetContent() != NULL ? 1 : 0) + (m_pVerticalScrollBar ? 1 : 0) + (m_pHorizontalScrollBar ? 1 : 0) + (m_pScrollBarGripper ? 1 : 0);
  695. }
  696. CXTPMarkupVisual* CXTPMarkupScrollViewer::GetVisualChild(int nIndex) const
  697. {
  698. CXTPMarkupVisual* pContent = GetContent();
  699. if (pContent) if (nIndex == 0) return pContent; else nIndex--;
  700. if (m_pVerticalScrollBar) if (nIndex == 0) return m_pVerticalScrollBar; else nIndex--;
  701. if (m_pHorizontalScrollBar) if (nIndex == 0) return m_pHorizontalScrollBar; else nIndex--;
  702. return m_pScrollBarGripper;
  703. }
  704. CSize CXTPMarkupScrollViewer::ArrangeOverride(CSize szFinalSize)
  705. {
  706. CXTPMarkupUIElement* pContent = GetContent();
  707. if (!pContent)
  708. return szFinalSize;
  709. CSize szViewport(szFinalSize);
  710. if (m_pVerticalScrollBar) szViewport.cx -= m_pVerticalScrollBar->GetDesiredSize().cx;
  711. if (m_pHorizontalScrollBar) szViewport.cy -= m_pHorizontalScrollBar->GetDesiredSize().cy;;
  712. if (m_pVerticalScrollBar)
  713. {
  714. if (m_yOffset > 0 && pContent->GetDesiredSize().cy < m_yOffset + szViewport.cy)
  715. {
  716. m_yOffset = max(0, pContent->GetDesiredSize().cy - szViewport.cy);
  717. }
  718. SCROLLINFO si;
  719. ZeroMemory(&si, sizeof(SCROLLINFO));
  720. si.nMax = pContent->GetDesiredSize().cy - 1;
  721. si.nPage = szViewport.cy;
  722. si.nPos = m_yOffset;
  723. m_pVerticalScrollBar->SetScrollInfo(&si);
  724. m_pVerticalScrollBar->Arrange(CRect(szFinalSize.cx - m_pVerticalScrollBar->GetDesiredSize().cx, 0, szFinalSize.cx, szViewport.cy));
  725. }
  726. if (m_pHorizontalScrollBar)
  727. {
  728. if (m_xOffset > 0 && pContent->GetDesiredSize().cx < m_xOffset + szViewport.cx)
  729. {
  730. m_xOffset = max(0, pContent->GetDesiredSize().cx - szViewport.cx);
  731. }
  732. SCROLLINFO si;
  733. ZeroMemory(&si, sizeof(SCROLLINFO));
  734. si.nMax = pContent->GetDesiredSize().cx - 1;
  735. si.nPage = szViewport.cx;
  736. si.nPos = m_xOffset;
  737. m_pHorizontalScrollBar->SetScrollInfo(&si);
  738. m_pHorizontalScrollBar->Arrange(CRect(0, szFinalSize.cy - m_pHorizontalScrollBar->GetDesiredSize().cy, szViewport.cx, szFinalSize.cy));
  739. }
  740. if (m_pScrollBarGripper && m_pHorizontalScrollBar && m_pVerticalScrollBar)
  741. {
  742. m_pScrollBarGripper->Arrange(CRect(szFinalSize.cx - m_pVerticalScrollBar->GetDesiredSize().cx, szFinalSize.cy - m_pHorizontalScrollBar->GetDesiredSize().cy, szFinalSize.cx, szFinalSize.cy));
  743. }
  744. CRect rcContent(0, 0, max(szViewport.cx, pContent->GetDesiredSize().cx), max(szViewport.cy, pContent->GetDesiredSize().cy));
  745. rcContent.OffsetRect(-m_xOffset, -m_yOffset);
  746. pContent->Arrange(rcContent);
  747. return szFinalSize;
  748. }
  749. void CXTPMarkupScrollViewer::CreateScrollBar(int nBar)
  750. {
  751. if (nBar == SB_VERT && m_pVerticalScrollBar == NULL)
  752. {
  753. m_pVerticalScrollBar = (CXTPMarkupScrollBar*)m_pMarkupContext->CreateMarkupObject(MARKUP_TYPE(CXTPMarkupScrollBar));
  754. m_pVerticalScrollBar->SetOrientation(xtpMarkupOrientationVertical);
  755. m_pVerticalScrollBar->SetLogicalParent(this);
  756. }
  757. if (nBar == SB_HORZ && m_pHorizontalScrollBar == NULL)
  758. {
  759. m_pHorizontalScrollBar = (CXTPMarkupScrollBar*)m_pMarkupContext->CreateMarkupObject(MARKUP_TYPE(CXTPMarkupScrollBar));
  760. m_pHorizontalScrollBar->SetOrientation(xtpMarkupOrientationHorizontal);
  761. m_pHorizontalScrollBar->SetLogicalParent(this);
  762. }
  763. }
  764. CSize CXTPMarkupScrollViewer::MeasureOverride(CXTPMarkupDrawingContext* pDC, CSize szAvailableSize)
  765. {
  766. CXTPMarkupUIElement* pContent = GetContent();
  767. if (!pContent)
  768. return CSize(0, 0);
  769. CSize szScroll(0, 0);
  770. XTPMarkupScrollBarVisibility verticalBarVisibility = GetVerticalScrollBarVisibility();
  771. XTPMarkupScrollBarVisibility horizontalBarVisibility = GetHorizontalScrollBarVisibility();
  772. CSize szViewportSize(INT_MAX, INT_MAX);
  773. if (horizontalBarVisibility == xtpMarkupScrollBarDisabled) szViewportSize.cx = szAvailableSize.cx;
  774. if (verticalBarVisibility == xtpMarkupScrollBarDisabled) szViewportSize.cy = szAvailableSize.cy;
  775. if (verticalBarVisibility == xtpMarkupScrollBarAuto)
  776. {
  777. pContent->Measure(pDC, szViewportSize);
  778. verticalBarVisibility = (pContent->GetDesiredSize().cy > szAvailableSize.cy) ? xtpMarkupScrollBarVisible : xtpMarkupScrollBarDisabled;
  779. }
  780. if (verticalBarVisibility == xtpMarkupScrollBarVisible)
  781. {
  782. CreateScrollBar(SB_VERT);
  783. m_pVerticalScrollBar->Measure(pDC, szAvailableSize);
  784. szScroll.cx = m_pVerticalScrollBar->GetDesiredSize().cx;
  785. if (szViewportSize.cx != INT_MAX) szViewportSize.cx = max(0, szViewportSize.cx - szScroll.cx);
  786. }
  787. else
  788. {
  789. MARKUP_RELEASE(m_pVerticalScrollBar);
  790. m_yOffset = 0;
  791. }
  792. if (horizontalBarVisibility == xtpMarkupScrollBarAuto)
  793. {
  794. pContent->Measure(pDC, szViewportSize);
  795. horizontalBarVisibility = (pContent->GetDesiredSize().cx > szAvailableSize.cx - szScroll.cx) ? xtpMarkupScrollBarVisible : xtpMarkupScrollBarDisabled;
  796. }
  797. if (horizontalBarVisibility == xtpMarkupScrollBarVisible)
  798. {
  799. CreateScrollBar(SB_HORZ);
  800. m_pHorizontalScrollBar->Measure(pDC, szAvailableSize);
  801. szScroll.cy = m_pHorizontalScrollBar->GetDesiredSize().cy;
  802. if (szViewportSize.cy != INT_MAX)  szViewportSize.cy = max(0, szViewportSize.cy - szScroll.cy);
  803. }
  804. else
  805. {
  806. MARKUP_RELEASE(m_pHorizontalScrollBar);
  807. m_xOffset = 0;
  808. }
  809. if (m_pVerticalScrollBar && m_pHorizontalScrollBar)
  810. {
  811. if (m_pScrollBarGripper == NULL)
  812. {
  813. m_pScrollBarGripper = (CXTPMarkupScrollBarGripper*)m_pMarkupContext->CreateMarkupObject(MARKUP_TYPE(CXTPMarkupScrollBarGripper));
  814. m_pScrollBarGripper->SetLogicalParent(this);
  815. }
  816. }
  817. else
  818. {
  819. MARKUP_RELEASE(m_pScrollBarGripper);
  820. }
  821. pContent->Measure(pDC, szViewportSize);
  822. return CSize(min(szAvailableSize.cx, pContent->GetDesiredSize().cx + szScroll.cx), min(szAvailableSize.cy, pContent->GetDesiredSize().cy + szScroll.cy));
  823. }
  824. void CXTPMarkupScrollViewer::Scroll(int nBar, int nSBCode, int pos)
  825. {
  826. CXTPMarkupScrollBar* pScrollBar = nBar == SB_VERT ? m_pVerticalScrollBar : m_pHorizontalScrollBar;
  827. if (!pScrollBar)
  828. return;
  829. SCROLLINFO si;
  830. pScrollBar->GetScrollInfo(&si);
  831. int nCurPos = si.nPos;
  832. int nPage = (int)si.nPage;
  833. int nLimit = max(0, si.nMax - max(nPage - 1, 0));
  834. // decide what to do for each different scroll event
  835. switch (nSBCode)
  836. {
  837. case SB_TOP:
  838. nCurPos = 0;
  839. break;
  840. case SB_BOTTOM:
  841. nCurPos = nLimit;
  842. break;
  843. case SB_LINEUP:
  844. nCurPos = max(nCurPos - 16, 0);
  845. break;
  846. case SB_LINEDOWN:
  847. nCurPos = min(nCurPos + 16, nLimit);
  848. break;
  849. case SB_PAGEUP:
  850. nCurPos = max(nCurPos - nPage, 0);
  851. break;
  852. case SB_PAGEDOWN:
  853. nCurPos = min(nCurPos + nPage, nLimit);
  854. break;
  855. case SB_THUMBTRACK:
  856. case SB_THUMBPOSITION:
  857. nCurPos = pos;
  858. break;
  859. }
  860. SetScrollPos(nBar, nCurPos);
  861. }
  862. int CXTPMarkupScrollViewer::GetScrollPos(int nBar)
  863. {
  864. return (nBar == SB_VERT) ? m_yOffset : m_xOffset;
  865. }
  866. int CXTPMarkupScrollViewer::GetScrollLimit(int nBar)
  867. {
  868. CXTPMarkupScrollBar* pScrollBar = nBar == SB_VERT ? m_pVerticalScrollBar : m_pHorizontalScrollBar;
  869. if (!pScrollBar)
  870. return 0;
  871. SCROLLINFO si;
  872. pScrollBar->GetScrollInfo(&si);
  873. int nPage = (int)si.nPage;
  874. int nLimit = max(0, si.nMax - max(nPage - 1, 0));
  875. return nLimit;
  876. }
  877. void CXTPMarkupScrollViewer::SetScrollPos(int nBar, int pos)
  878. {
  879. int& nOffset = (nBar == SB_VERT) ? m_yOffset : m_xOffset;
  880. int nLimit = GetScrollLimit(nBar);
  881. if (pos > nLimit) pos = nLimit;
  882. if (pos < 0) pos = 0;
  883. if (nOffset != pos)
  884. {
  885. nOffset = pos;
  886. InvalidateArrange();
  887. }
  888. }
  889. void CXTPMarkupScrollViewer::OnMouseWheel(CXTPMarkupMouseWheelEventArgs* e)
  890. {
  891. SetScrollPos(SB_VERT, e->m_nDelta < 0 ? GetScrollPos(SB_VERT) + 48 : GetScrollPos(SB_VERT) - 48);
  892. e->SetHandled();
  893. }