ExtScrollWnd.cpp
上传用户:sesekoo
上传日期:2020-07-18
资源大小:21543k
文件大小:206k
源码类别:

界面编程

开发平台:

Visual C++

  1. ) const
  2. {
  3. ASSERT_VALID( this );
  4. ASSERT( nBar == SB_HORZ || nBar == SB_VERT );
  5. CScrollBar * pScrollBarWnd = GetScrollBarCtrl( nBar );
  6. if( pScrollBarWnd != NULL )
  7. {
  8. // if( bTrackPos
  9. // && pScrollBarWnd->IsKindOf( RUNTIME_CLASS(CExtScrollBar) )
  10. // && ((CExtScrollBar*)pScrollBarWnd)->m_nHelperTrackPos != -1
  11. // )
  12. // return ((CExtScrollBar*)pScrollBarWnd)->m_nHelperTrackPos;
  13. if( m_bUse32BitScrollInfo )
  14. {
  15. SCROLLINFO _scroll_info;
  16. ::memset( &_scroll_info, 0, sizeof(SCROLLINFO) );
  17. _scroll_info.cbSize = sizeof(SCROLLINFO);
  18. if( pScrollBarWnd->GetScrollInfo(
  19. &_scroll_info,
  20. bTrackPos ? SIF_TRACKPOS : SIF_POS
  21. )
  22. )
  23. {
  24. LONG nRetVal = (LONG)
  25. ( bTrackPos
  26. ? _scroll_info.nTrackPos
  27. : _scroll_info.nPos
  28. );
  29. return nRetVal;
  30. }
  31. //ASSERT( FALSE );
  32. } // if( m_bUse32BitScrollInfo )
  33. LONG nRetVal = (LONG)
  34. pScrollBarWnd->GetScrollPos();
  35. return nRetVal;
  36. } // if( pScrollBarWnd != NULL )
  37. DWORD dwWndStyle = CWnd::GetStyle();
  38. if( ( nBar == SB_HORZ && (dwWndStyle & WS_HSCROLL) == 0 )
  39. || ( nBar == SB_VERT && (dwWndStyle & WS_VSCROLL) == 0 )
  40. )
  41. return 0;
  42. if( m_bUse32BitScrollInfo )
  43. {
  44. SCROLLINFO _scroll_info;
  45. ::memset( &_scroll_info, 0, sizeof(SCROLLINFO) );
  46. _scroll_info.cbSize = sizeof(SCROLLINFO);
  47. if( ( const_cast < CExtScrollWnd * > ( this ) ) ->
  48. CWnd::GetScrollInfo(
  49. nBar,
  50. &_scroll_info,
  51. bTrackPos ? SIF_TRACKPOS : SIF_POS
  52. )
  53. )
  54. {
  55. LONG nRetVal = (LONG)
  56. ( bTrackPos
  57. ? _scroll_info.nTrackPos
  58. : _scroll_info.nPos
  59. );
  60. return nRetVal;
  61. }
  62. //ASSERT( FALSE );
  63. } // if( m_bUse32BitScrollInfo )
  64. LONG nRetVal = (LONG)
  65. ( ( const_cast < CExtScrollWnd * > ( this ) ) ->
  66. CWnd::GetScrollPos( nBar )
  67. );
  68. return nRetVal;
  69. }
  70. void CExtScrollWnd::ScrollPos32Set(
  71. int nBar,
  72. LONG nPos,
  73. bool bRedraw // = true
  74. )
  75. {
  76. ASSERT_VALID( this );
  77. ASSERT( nBar == SB_HORZ || nBar == SB_VERT );
  78. CScrollBar * pScrollBarWnd = GetScrollBarCtrl( nBar );
  79. if( pScrollBarWnd != NULL )
  80. {
  81. if( m_bUse32BitScrollInfo )
  82. {
  83. SCROLLINFO _scroll_info;
  84. ::memset( &_scroll_info, 0, sizeof(SCROLLINFO) );
  85. _scroll_info.cbSize = sizeof(SCROLLINFO);
  86. _scroll_info.fMask = SIF_POS;
  87. _scroll_info.nPos = (int)nPos;
  88. if( pScrollBarWnd->SetScrollInfo(
  89. &_scroll_info,
  90. bRedraw ? TRUE : FALSE
  91. )
  92. )
  93. return;
  94. //ASSERT( FALSE );
  95. } // if( m_bUse32BitScrollInfo )
  96. pScrollBarWnd->SetScrollPos(
  97. (int)nPos,
  98. bRedraw ? TRUE : FALSE
  99. );
  100. return;
  101. } // if( pScrollBarWnd != NULL )
  102. if( m_bUse32BitScrollInfo )
  103. {
  104. SCROLLINFO _scroll_info;
  105. ::memset( &_scroll_info, 0, sizeof(SCROLLINFO) );
  106. _scroll_info.cbSize = sizeof(SCROLLINFO);
  107. _scroll_info.fMask = SIF_POS;
  108. _scroll_info.nPos = (int)nPos;
  109. if( CWnd::SetScrollInfo(
  110. nBar,
  111. &_scroll_info,
  112. bRedraw ? TRUE : FALSE
  113. )
  114. )
  115. return;
  116. //ASSERT( FALSE );
  117. } // if( m_bUse32BitScrollInfo )
  118. CWnd::SetScrollPos(
  119. nBar,
  120. (int)nPos,
  121. bRedraw ? TRUE : FALSE
  122. );
  123. }
  124. CPoint CExtScrollWnd::OnSwGetScrollPos() const
  125. {
  126. ASSERT_VALID( this );
  127. CPoint pt(
  128. ScrollPos32Get( SB_HORZ ),
  129. ScrollPos32Get( SB_VERT )
  130. );
  131. ASSERT( pt.x >= 0 && pt.y >= 0 );
  132. //LONG xMaxValue = ScrollLimit32Get( SB_HORZ );
  133. //LONG yMaxValue = ScrollLimit32Get( SB_VERT );
  134. // pt.x = min( pt.x, xMaxValue );
  135. // pt.y = min( pt.y, yMaxValue );
  136. return pt;
  137. }
  138. CPoint CExtScrollWnd::OnSwGetScrollPaintPos() const
  139. {
  140. ASSERT_VALID( this );
  141. return OnSwGetScrollPos();
  142. }
  143. CRect CExtScrollWnd::OnSwRecalcLayout(
  144. bool bDoLayout,
  145. LPCRECT pRectClientSrc // = NULL
  146. )
  147. {
  148. ASSERT_VALID( this );
  149. if( GetSafeHwnd() == NULL )
  150. return CRect( *pRectClientSrc );
  151. if( bDoLayout )
  152. {
  153. CScrollBar * pScrollBarWndH = GetScrollBarCtrl( SB_HORZ );
  154. CScrollBar * pScrollBarWndV = GetScrollBarCtrl( SB_VERT );
  155. if( pScrollBarWndH != NULL && pScrollBarWndV != NULL )
  156. {
  157. CExtScrollBar * pExtScrollBarWndH = DYNAMIC_DOWNCAST( CExtScrollBar, pScrollBarWndH );
  158. CExtScrollBar * pExtScrollBarWndV = DYNAMIC_DOWNCAST( CExtScrollBar, pScrollBarWndV );
  159. if( pExtScrollBarWndH != NULL && pExtScrollBarWndV != NULL )
  160. {
  161. pExtScrollBarWndH->SyncReservedSpace( pExtScrollBarWndV );
  162. pExtScrollBarWndV->SyncReservedSpace( pExtScrollBarWndH );
  163. } // if( pExtScrollBarWndH != NULL && pExtScrollBarWndV != NULL )
  164. } // if( pScrollBarWndH != NULL && pScrollBarWndV != NULL )
  165. } // if( bDoLayout )
  166. CRect rcClient;
  167. if( pRectClientSrc != NULL )
  168. rcClient = *pRectClientSrc;
  169. else
  170. CWnd::GetClientRect( &rcClient );
  171. CWnd::RepositionBars(
  172. 0,
  173. 0x0FFFF,
  174. AFX_IDW_PANE_FIRST,
  175. bDoLayout ? CWnd::reposDefault : CWnd::reposQuery,
  176. &rcClient,
  177. &rcClient,
  178. TRUE
  179. );
  180. return rcClient;
  181. }
  182. CRect CExtScrollWnd::OnSwGetClientRect() const
  183. {
  184. ASSERT_VALID( this );
  185. CRect rcClient =
  186. ( const_cast < CExtScrollWnd * > ( this ) )
  187. -> OnSwRecalcLayout( false );
  188. return rcClient;
  189. }
  190. bool CExtScrollWnd::OnSwHasScrollBar( bool bHorz ) const
  191. {
  192. ASSERT_VALID( this );
  193. CScrollBar * pScrollBarWnd = GetScrollBarCtrl( bHorz ? SB_HORZ : SB_VERT );
  194. if( pScrollBarWnd != NULL )
  195. {
  196. if( pScrollBarWnd->IsWindowEnabled() )
  197. return true;
  198. return false;
  199. } // if( pScrollBarWnd != NULL )
  200. DWORD dwWndStyle = CWnd::GetStyle();
  201. DWORD dwTestStyle = bHorz ? WS_HSCROLL : WS_VSCROLL;
  202. if( ( dwWndStyle & dwTestStyle ) != 0 )
  203. return true;
  204. return false;
  205. }
  206. bool CExtScrollWnd::OnSwCanAutoHideScrollBar( bool bHorz ) const
  207. {
  208. ASSERT_VALID( this );
  209. bHorz;
  210. return true;
  211. }
  212. void CExtScrollWnd::OnSwEnableScrollBarCtrl( int nBar, bool bEnable )
  213. {
  214. ASSERT_VALID( this );
  215. ASSERT( nBar == SB_HORZ || nBar == SB_VERT || nBar == SB_BOTH );
  216. if( ! IsWindowEnabled() )
  217. bEnable = false;
  218. DWORD dwWndStyle = CWnd::GetStyle();
  219. CPoint ptMove = OnSwGetScrollPos();
  220. CScrollBar * pScrollBarWndH = GetScrollBarCtrl( SB_HORZ );
  221. CScrollBar * pScrollBarWndV = GetScrollBarCtrl( SB_VERT );
  222. if( nBar == SB_HORZ || nBar == SB_BOTH )
  223. {
  224. if( (!bEnable) && ptMove.x != 0 )
  225. {
  226. ptMove.x = 0;
  227. OnSwSetScrollPos( ptMove );
  228. } // if( (!bEnable) && ptMove.x != 0 )
  229. if( pScrollBarWndH != NULL )
  230. {
  231. if( (dwWndStyle & WS_HSCROLL) != 0 )
  232. CWnd::ShowScrollBar( SB_HORZ, FALSE );
  233. bool bAreadyEnabled = pScrollBarWndH->IsWindowEnabled() ? true : false;
  234. if( !( ( bAreadyEnabled && bEnable )
  235. || ( (!bAreadyEnabled) && (!bEnable) )
  236. )
  237. )
  238. {
  239. pScrollBarWndH->EnableWindow( bEnable ? TRUE : FALSE );
  240. if( OnSwCanAutoHideScrollBar(true) )
  241. pScrollBarWndH->ShowWindow( bEnable ? SW_SHOW : SW_HIDE );
  242. else if( bEnable && (pScrollBarWndH->GetStyle()&WS_VISIBLE) == 0 )
  243. pScrollBarWndH->ShowWindow( SW_SHOW );
  244. }
  245. } // if( pScrollBarWndH != NULL )
  246. else
  247. {
  248. if( OnSwCanAutoHideScrollBar(true) )
  249. CWnd::ShowScrollBar(
  250. SB_HORZ,
  251. bEnable ? TRUE : FALSE
  252. );
  253. else
  254. CWnd::EnableScrollBar(
  255. SB_HORZ,
  256. bEnable ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH
  257. );
  258. } // else from if( pScrollBarWndH != NULL )
  259. } // if( nBar == SB_HORZ || nBar == SB_BOTH )
  260. if( nBar == SB_VERT || nBar == SB_BOTH )
  261. {
  262. if( (!bEnable) && ptMove.y != 0 )
  263. {
  264. ptMove.y = 0;
  265. OnSwSetScrollPos( ptMove );
  266. } // if( (!bEnable) && ptMove.y != 0 )
  267. if( pScrollBarWndV != NULL )
  268. {
  269. if( (dwWndStyle & WS_VSCROLL) != 0 )
  270. CWnd::ShowScrollBar( SB_VERT, FALSE );
  271. bool bAreadyEnabled = pScrollBarWndV->IsWindowEnabled() ? true : false;
  272. if( !( ( bAreadyEnabled && bEnable )
  273. || ( (!bAreadyEnabled) && (!bEnable) )
  274. )
  275. )
  276. {
  277. pScrollBarWndV->EnableWindow( bEnable ? TRUE : FALSE );
  278. if( OnSwCanAutoHideScrollBar(false) )
  279. pScrollBarWndV->ShowWindow( bEnable ? SW_SHOW : SW_HIDE );
  280. else if( bEnable && (pScrollBarWndV->GetStyle()&WS_VISIBLE) == 0 )
  281. pScrollBarWndV->ShowWindow( SW_SHOW );
  282. }
  283. } // if( pScrollBarWndV != NULL )
  284. else
  285. {
  286. if( OnSwCanAutoHideScrollBar(false) )
  287. CWnd::ShowScrollBar(
  288. SB_VERT,
  289. bEnable ? TRUE : FALSE
  290. );
  291. else
  292. CWnd::EnableScrollBar(
  293. SB_VERT,
  294. bEnable ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH
  295. );
  296. } // else from if( pScrollBarWndV != NULL )
  297. } // if( nBar == SB_VERT || nBar == SB_BOTH )
  298. CExtScrollBar * pExtScrollBarWndH = DYNAMIC_DOWNCAST( CExtScrollBar, pScrollBarWndH );
  299. CExtScrollBar * pExtScrollBarWndV = DYNAMIC_DOWNCAST( CExtScrollBar, pScrollBarWndV );
  300. if( pExtScrollBarWndH != NULL && pExtScrollBarWndV != NULL )
  301. {
  302. pExtScrollBarWndH->SyncReservedSpace( pExtScrollBarWndV );
  303. pExtScrollBarWndV->SyncReservedSpace( pExtScrollBarWndH );
  304. } // if( pExtScrollBarWndH != NULL && pExtScrollBarWndV != NULL )
  305. }
  306. void CExtScrollWnd::OnSwSetScrollPos( POINT pt )
  307. {
  308. ASSERT_VALID( this );
  309. ASSERT( pt.x >= 0 && pt.y >= 0 );
  310. int xOrgValue = ScrollPos32Get( SB_HORZ );
  311. ScrollPos32Set( SB_HORZ, pt.x );
  312. int yOrgValue = ScrollPos32Get( SB_VERT );
  313. ScrollPos32Set( SB_VERT, pt.y );
  314. OnSwDoScrollWindow( xOrgValue - pt.x, yOrgValue - pt.y );
  315. }
  316. UINT CExtScrollWnd::OnSwCalcMouseScrollLines(
  317. UINT fFlags,
  318. short zDelta,
  319. CPoint point
  320. )
  321. {
  322. ASSERT_VALID( this );
  323. fFlags;
  324. zDelta;
  325. point;
  326. return g_PaintManager.GetMouseWheelScrollLines();
  327. }
  328. bool CExtScrollWnd::OnSwDoMouseWheel(
  329. UINT fFlags,
  330. short zDelta,
  331. CPoint point
  332. )
  333. {
  334. ASSERT_VALID( this );
  335. point;
  336. if( CExtPopupMenuWnd::IsMenuTracking() )
  337. {
  338. CExtPopupMenuWnd * pPopup = CExtPopupMenuSite::g_DefPopupMenuSite.GetInstance();
  339. if( pPopup == NULL )
  340. return false;
  341. bool bFound = false;
  342. CWnd * pWnd = GetParent();
  343. for( ; pWnd != NULL; pWnd = pWnd->GetParent() )
  344. {
  345. if( pWnd == pPopup )
  346. {
  347. bFound = true;
  348. break;
  349. }
  350. }
  351. if( ! bFound )
  352. return false;
  353. } // if( CExtPopupMenuWnd::IsMenuTracking() )
  354. else if( (fFlags&(MK_CONTROL)) != 0
  355. || CExtToolControlBar::g_bMenuTracking
  356. )
  357. return false;
  358. if( ! ( OnSwHasScrollBar(true) || OnSwHasScrollBar(false) ) )
  359. return false;
  360. bool bResult = false;
  361. UINT uWheelScrollLines =
  362. OnSwCalcMouseScrollLines(
  363. fFlags,
  364. zDelta,
  365. point
  366. );
  367. if( OnSwHasScrollBar(false)
  368. && ( (fFlags&(MK_SHIFT)) == 0 )
  369. )
  370. {
  371. int nDisplacement;
  372. int nToScroll =
  373. ::MulDiv( -zDelta, uWheelScrollLines, WHEEL_DELTA );
  374. if( nToScroll == -1
  375. || uWheelScrollLines == WHEEL_PAGESCROLL
  376. )
  377. {
  378. nDisplacement = OnSwGetPageSize( -1 ).cy;
  379. if( zDelta > 0 )
  380. nDisplacement = -nDisplacement;
  381. }
  382. else
  383. {
  384. nDisplacement =
  385. nToScroll * OnSwGetLineSize( 1 ).cy;
  386. nDisplacement =
  387. min(
  388. nDisplacement,
  389. OnSwGetPageSize( 1 ).cy
  390. );
  391. }
  392. bResult =
  393. OnSwDoScrollBy(
  394. CSize( 0, nDisplacement ),
  395. true
  396. );
  397. }
  398. else if(
  399. OnSwHasScrollBar( true )
  400. && ( (fFlags&(MK_SHIFT)) != 0 )
  401. )
  402. {
  403. int nDisplacement;
  404. int nToScroll =
  405. ::MulDiv( -zDelta, uWheelScrollLines, WHEEL_DELTA );
  406. if( nToScroll == -1
  407. || uWheelScrollLines == WHEEL_PAGESCROLL
  408. )
  409. {
  410. nDisplacement = OnSwGetPageSize( -1 ).cx;
  411. if( zDelta > 0 )
  412. nDisplacement = -nDisplacement;
  413. }
  414. else
  415. {
  416. nDisplacement =
  417. nToScroll * OnSwGetLineSize( 1 ).cx;
  418. nDisplacement =
  419. min(
  420. nDisplacement,
  421. OnSwGetPageSize( 1 ).cx
  422. );
  423. }
  424. bResult =
  425. OnSwDoScrollBy(
  426. CSize( nDisplacement, 0 ),
  427. true
  428. );
  429. }
  430. if( bResult )
  431. {
  432. OnSwInvalidate( m_bScrollErase );
  433. if( m_bScrollUpdateWindow )
  434. OnSwUpdateWindow();
  435. }
  436. return bResult;
  437. }
  438. bool CExtScrollWnd::OnSwDoScroll(
  439. UINT nScrollCode,
  440. UINT nPos,
  441. bool bDoScroll // = true
  442. )
  443. {
  444. ASSERT_VALID( this );
  445. LONG xPos, xOrgValue, yPos, yOrgValue;
  446. xOrgValue = xPos = ScrollPos32Get( SB_HORZ );
  447. switch( LOBYTE(nScrollCode) )
  448. {
  449. case SB_ENDSCROLL: break;
  450. case SB_TOP: xPos  = 0; break;
  451. case SB_BOTTOM: xPos  = __EXT_SCROLL_NUMERIC_MAX; break;
  452. case SB_LINEUP: xPos -= OnSwGetLineSize( -1 ).cx; break;
  453. case SB_LINEDOWN: xPos += OnSwGetLineSize(  1 ).cx; break;
  454. case SB_PAGEUP: xPos -= OnSwGetPageSize( -1 ).cx; break;
  455. case SB_PAGEDOWN: xPos += OnSwGetPageSize(  1 ).cx; break;
  456. case SB_THUMBTRACK:
  457. if( ! OnSwQueryThumbTrackEnabled(true) )
  458. break;
  459. case SB_THUMBPOSITION:
  460. if( m_bUse32BitScrollInfo )
  461. nPos = ScrollPos32Get( SB_HORZ, true );
  462. xPos  = nPos;
  463. break;
  464. }
  465. yOrgValue = yPos = ScrollPos32Get( SB_VERT );
  466. switch( HIBYTE(nScrollCode) )
  467. {
  468. case SB_ENDSCROLL: break;
  469. case SB_TOP: yPos  = 0; break;
  470. case SB_BOTTOM: yPos  = __EXT_SCROLL_NUMERIC_MAX; break;
  471. case SB_LINEUP: yPos -= OnSwGetLineSize( -1 ).cy; break;
  472. case SB_LINEDOWN: yPos += OnSwGetLineSize(  1 ).cy; break;
  473. case SB_PAGEUP: yPos -= OnSwGetPageSize( -1 ).cy; break;
  474. case SB_PAGEDOWN: yPos += OnSwGetPageSize(  1 ).cy; break;
  475. case SB_THUMBTRACK:
  476. if( ! OnSwQueryThumbTrackEnabled(false) )
  477. break;
  478. case SB_THUMBPOSITION:
  479. if( m_bUse32BitScrollInfo )
  480. nPos = ScrollPos32Get( SB_VERT, true );
  481. yPos  = nPos;
  482. break;
  483. }
  484. bool bResult =
  485. OnSwDoScrollBy(
  486. CSize( xPos - xOrgValue, yPos - yOrgValue ),
  487. bDoScroll
  488. );
  489. if( bResult && bDoScroll && m_bScrollUpdateWindow )
  490. OnSwUpdateWindow();
  491. return bResult;
  492. }
  493. bool CExtScrollWnd::OnSwDoScrollBy(
  494. CSize sizeScroll,
  495. bool bDoScroll // = true
  496. )
  497. {
  498. ASSERT_VALID( this );
  499. int xMaxValue, xOrgValue, xPos, yMaxValue, yOrgValue, yPos;
  500. if( ! OnSwHasScrollBar(false) )
  501. sizeScroll.cy = 0;
  502. if( ! OnSwHasScrollBar(true) )
  503. sizeScroll.cx = 0;
  504. // adjust current positions
  505. xOrgValue = xPos = ScrollPos32Get( SB_HORZ );
  506. xMaxValue = ScrollLimit32Get( SB_HORZ );
  507. xPos += sizeScroll.cx;
  508. if( xPos < 0 )
  509. xPos = 0;
  510. else if( xPos > xMaxValue )
  511. xPos = xMaxValue;
  512. yOrgValue = yPos = ScrollPos32Get( SB_VERT );
  513. yMaxValue = ScrollLimit32Get( SB_VERT );
  514. yPos += sizeScroll.cy;
  515. if( yPos < 0 )
  516. yPos = 0;
  517. else if( yPos > yMaxValue )
  518. yPos = yMaxValue;
  519. if( xPos == xOrgValue && yPos == yOrgValue )
  520. return false;
  521. if( bDoScroll )
  522. {
  523. OnSwDoScrollWindow( xOrgValue - xPos, yOrgValue - yPos );
  524. if( xPos != xOrgValue )
  525. ScrollPos32Set( SB_HORZ, xPos );
  526. if( yPos != yOrgValue )
  527. ScrollPos32Set( SB_VERT, yPos );
  528. }
  529. return true;
  530. }
  531. CSize CExtScrollWnd::OnSwGetScrollBarSizes() const
  532. {
  533. ASSERT_VALID( this );
  534. CSize sizeSb( 0, 0 );
  535. DWORD dwWndStyle = CWnd::GetStyle();
  536. if( GetScrollBarCtrl(SB_HORZ) == NULL )
  537. {
  538. sizeSb.cx = afxData.cxVScroll;
  539. if( dwWndStyle & WS_BORDER )
  540. sizeSb.cx -= __EXT_MFC_CX_BORDER;
  541. } // if( GetScrollBarCtrl(SB_HORZ) == NULL )
  542. if( GetScrollBarCtrl(SB_VERT) == NULL )
  543. {
  544. sizeSb.cy = afxData.cyHScroll;
  545. if( dwWndStyle & WS_BORDER )
  546. sizeSb.cy -= __EXT_MFC_CY_BORDER;
  547. } // if( GetScrollBarCtrl(SB_VERT) == NULL )
  548. return sizeSb;
  549. }
  550. bool CExtScrollWnd::OnSwCalcClientSizes(
  551. CSize & size,
  552. CSize & sizeSb
  553. )
  554. {
  555. // return true if enough room to add scrollbars if needed
  556. ASSERT_VALID( this );
  557. CRect rcClient = OnSwGetClientRect();
  558. size = rcClient.Size();
  559. sizeSb = OnSwGetScrollBarSizes();
  560. if( sizeSb.cx != 0
  561. && OnSwHasScrollBar( false )
  562. )
  563. size.cx += sizeSb.cx;
  564. if( sizeSb.cy != 0
  565. && OnSwHasScrollBar( true )
  566. )
  567. size.cy += sizeSb.cy;
  568. // return
  569. // ( size.cx > sizeSb.cx && size.cy > sizeSb.cy )
  570. // ? true : false;
  571. return true;
  572. }
  573. bool CExtScrollWnd::OnSwQueryThumbTrackEnabled( bool bHorz ) const
  574. {
  575. ASSERT_VALID( this );
  576. bHorz;
  577. return true;
  578. }
  579. void CExtScrollWnd::OnSwGetScrollBarState(
  580. CSize sizeClient,
  581. CSize & sizeNeedSB,
  582. CSize & sizeRange,
  583. CPoint & ptMove,
  584. bool bInsideClient
  585. ) const
  586. {
  587. ASSERT_VALID( this );
  588. CSize sizeSb = OnSwGetScrollBarSizes();
  589. sizeRange = OnSwGetTotalSize() - sizeClient;
  590. ptMove = OnSwGetScrollPos();
  591. bool bNeedH = sizeRange.cx > 0;
  592. if( !bNeedH )
  593. ptMove.x = 0;
  594. else if( bInsideClient )
  595. sizeRange.cy += sizeSb.cy;
  596. bool bNeedV = sizeRange.cy > 0;
  597. if( !bNeedV )
  598. ptMove.y = 0;
  599. else if ( bInsideClient )
  600. sizeRange.cx += sizeSb.cx;
  601. if( bNeedV && (!bNeedH) && sizeRange.cx > 0 )
  602. {
  603. ASSERT( bInsideClient );
  604. bNeedH = true;
  605. sizeRange.cy += sizeSb.cy;
  606. } // if( bNeedV && (!bNeedH) && sizeRange.cx > 0 )
  607. if( sizeRange.cx > 0 && ptMove.x >= sizeRange.cx )
  608. ptMove.x = sizeRange.cx;
  609. if( sizeRange.cy > 0 && ptMove.y >= sizeRange.cy )
  610. ptMove.y = sizeRange.cy;
  611. sizeNeedSB.cx = bNeedH;
  612. sizeNeedSB.cy = bNeedV;
  613. }
  614. void CExtScrollWnd::OnSwUpdateScrollBars()
  615. {
  616. ASSERT_VALID( this );
  617. if( m_nUpdateScrollBars > 1 )
  618. return;
  619. m_nUpdateScrollBars ++;
  620. ASSERT( OnSwGetTotalSize().cx >= 0 && OnSwGetTotalSize().cy >= 0 );
  621. CRect rcClient;
  622. bool bCalcClient = true;
  623. CWnd * pParentWnd = GetParent();
  624. if( pParentWnd != NULL
  625. && (BOOL)pParentWnd->SendMessage(
  626. WM_RECALCPARENT,
  627. 0,
  628. (LPARAM)(LPCRECT)&rcClient
  629. ) != 0
  630. )
  631. bCalcClient = false;
  632. CSize sizeClient;
  633. CSize sizeSb;
  634. if( bCalcClient )
  635. {
  636. if( ! OnSwCalcClientSizes( sizeClient, sizeSb ) )
  637. { // no room for scroll bars
  638. CRect rcClient2 = OnSwGetClientRect();
  639. if( rcClient2.Width() > 0 && rcClient2.Height() > 0 )
  640. {
  641. OnSwEnableScrollBarCtrl( SB_BOTH, false );
  642. OnSwRecalcLayout( true );
  643. }
  644. m_nUpdateScrollBars --;
  645. return;
  646. }
  647. }
  648. else
  649. { // let parent window determine the "client" rect
  650. sizeSb = OnSwGetScrollBarSizes();
  651. sizeClient.cx = rcClient.right - rcClient.left;
  652. sizeClient.cy = rcClient.bottom - rcClient.top;
  653. }
  654. // if enough room to add scrollbars
  655. CSize sizeRange;
  656. CPoint ptMove;
  657. CSize sizeNeedSB;
  658. OnSwGetScrollBarState(
  659. sizeClient,
  660. sizeNeedSB,
  661. sizeRange,
  662. ptMove,
  663. bCalcClient
  664. );
  665. if( sizeNeedSB.cx )
  666. sizeClient.cy -= sizeSb.cy;
  667. if( sizeNeedSB.cy )
  668. sizeClient.cx -= sizeSb.cx;
  669. // scroll window + update
  670. OnSwSetScrollPos( ptMove );
  671. // the scrollbar page range
  672. SCROLLINFO _scroll_info;
  673. ::memset( &_scroll_info, 0, sizeof(SCROLLINFO) );
  674. _scroll_info.cbSize = sizeof(SCROLLINFO);
  675. _scroll_info.fMask = SIF_PAGE|SIF_RANGE;
  676. _scroll_info.nMin = 0;
  677. // update bars
  678. OnSwEnableScrollBarCtrl( SB_HORZ, sizeNeedSB.cx ? true : false );
  679. if( sizeNeedSB.cx )
  680. {
  681. _scroll_info.nPage = sizeClient.cx;
  682. _scroll_info.nMax = OnSwGetTotalSize().cx - 1;
  683. if( ! OnSwScrollInfoAdjust(
  684. SB_HORZ,
  685. _scroll_info,
  686. true
  687. )
  688. )
  689. OnSwSetScrollRange(
  690. SB_HORZ,
  691. 0,
  692. sizeRange.cx,
  693. true
  694. );
  695. } // if( sizeNeedSB.cx )
  696. OnSwEnableScrollBarCtrl( SB_VERT, sizeNeedSB.cy ? true : false );
  697. if( sizeNeedSB.cy )
  698. {
  699. _scroll_info.nPage = sizeClient.cy;
  700. _scroll_info.nMax = OnSwGetTotalSize().cy - 1;
  701. if( ! OnSwScrollInfoAdjust(
  702. SB_VERT,
  703. _scroll_info,
  704. true
  705. )
  706. )
  707. OnSwSetScrollRange(
  708. SB_VERT,
  709. 0,
  710. sizeRange.cy,
  711. true
  712. );
  713. } // if( sizeNeedSB.cy )
  714. OnSwRecalcLayout( true );
  715. m_nUpdateScrollBars --;
  716. }
  717. void CExtScrollWnd::OnSwDoScrollWindow(
  718. int xAmount,
  719. int yAmount,
  720. LPCRECT lpRect, // = NULL
  721. LPCRECT lpClipRect // = NULL
  722. )
  723. {
  724. ASSERT_VALID( this );
  725. if( m_bScrollPhysical )
  726. CWnd::ScrollWindow(
  727. xAmount,
  728. yAmount,
  729. lpRect,
  730. lpClipRect
  731. );
  732. if( m_bScrollInvalidate )
  733. OnSwInvalidate( m_bScrollErase );
  734. if( m_bScrollUpdateWindow )
  735. OnSwUpdateWindow();
  736. }
  737. void CExtScrollWnd::OnSwInvalidate( bool bErase )
  738. {
  739. ASSERT_VALID( this );
  740. if( GetSafeHwnd() == NULL )
  741. return;
  742. if( ! IsWindowVisible() )
  743. return;
  744. CScrollBar * pScrollBarWndH = GetScrollBarCtrl( SB_HORZ );
  745. CScrollBar * pScrollBarWndV = GetScrollBarCtrl( SB_VERT );
  746. if( pScrollBarWndH != NULL
  747. && ( pScrollBarWndH->GetStyle() & WS_VISIBLE ) == 0
  748. )
  749. pScrollBarWndH = NULL;
  750. if( pScrollBarWndV != NULL
  751. && ( pScrollBarWndV->GetStyle() & WS_VISIBLE ) == 0
  752. )
  753. pScrollBarWndV = NULL;
  754. if( pScrollBarWndH == NULL && pScrollBarWndV == NULL )
  755. {
  756. CWnd::Invalidate( bErase ? TRUE : FALSE );
  757. return;
  758. } // if( pScrollBarWndH == NULL && pScrollBarWndV == NULL )
  759. CRect rcClientReal;
  760. CWnd::GetClientRect( &rcClientReal );
  761. CRgn rgnInvalidate;
  762. if( !rgnInvalidate.CreateRectRgnIndirect(&rcClientReal) )
  763. {
  764. CWnd::Invalidate( bErase ? TRUE : FALSE );
  765. return;
  766. }
  767. if( pScrollBarWndH != NULL )
  768. {
  769. CRect rcBar;
  770. pScrollBarWndH->GetWindowRect( &rcBar );
  771. ScreenToClient( &rcBar );
  772. CRgn rgnBar;
  773. if( (! rgnBar.CreateRectRgnIndirect(&rcBar) )
  774. || rgnInvalidate.CombineRgn(
  775. &rgnInvalidate,
  776. &rgnBar,
  777. RGN_DIFF
  778. ) == ERROR
  779. )
  780. {
  781. CWnd::Invalidate( bErase ? TRUE : FALSE );
  782. return;
  783. }
  784. } // if( pScrollBarWndH != NULL )
  785. if( pScrollBarWndV != NULL )
  786. {
  787. CRect rcBar;
  788. pScrollBarWndV->GetWindowRect( &rcBar );
  789. ScreenToClient( &rcBar );
  790. CRgn rgnBar;
  791. if( (! rgnBar.CreateRectRgnIndirect(&rcBar) )
  792. || rgnInvalidate.CombineRgn(
  793. &rgnInvalidate,
  794. &rgnBar,
  795. RGN_DIFF
  796. ) == ERROR
  797. )
  798. {
  799. CWnd::Invalidate( bErase ? TRUE : FALSE );
  800. return;
  801. }
  802. } // if( pScrollBarWndV != NULL )
  803. CWnd::InvalidateRgn( &rgnInvalidate, bErase ? TRUE : FALSE );
  804. }
  805. void CExtScrollWnd::OnSwUpdateWindow()
  806. {
  807. ASSERT_VALID( this );
  808. if( GetSafeHwnd() == NULL )
  809. return;
  810. UpdateWindow();
  811. }
  812. void CExtScrollWnd::OnSwDoRedraw()
  813. {
  814. ASSERT_VALID( this );
  815. if( GetSafeHwnd() == NULL )
  816. return;
  817. if( m_bRedrawInvalidate )
  818. OnSwInvalidate( m_bRedrawErase );
  819. if( m_bRedrawUpdateWindow )
  820. OnSwUpdateWindow();
  821. }
  822. void CExtScrollWnd::OnSwPaint( CDC & dc )
  823. {
  824. ASSERT_VALID( this );
  825. ASSERT( dc.GetSafeHdc() != NULL );
  826. dc;
  827. }
  828. /////////////////////////////////////////////////////////////////////////////
  829. // CExtScrollWnd message handlers
  830. void CExtScrollWnd::OnSize(UINT nType, int cx, int cy)
  831. {
  832. CWnd::OnSize(nType, cx, cy);
  833. if( nType != SIZE_MINIMIZED )
  834. {
  835. bool bH1 = OnSwHasScrollBar( true ), bV1 = OnSwHasScrollBar( false );
  836. OnSwRecalcLayout( true );
  837. OnSwUpdateScrollBars();
  838. bool bH2 = OnSwHasScrollBar( true ), bV2 = OnSwHasScrollBar( false );
  839. if( bH1 != bH2 || bV1 != bV2 )
  840. OnSwUpdateScrollBars();
  841. OnSwDoRedraw();
  842. }
  843. }
  844. void CExtScrollWnd::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  845. {
  846. if( pScrollBar != NULL
  847. && pScrollBar->SendChildNotifyLastMsg()
  848. )
  849. return;
  850. if( pScrollBar != GetScrollBarCtrl(SB_HORZ) )
  851. return;
  852. if( nSBCode == SB_ENDSCROLL )
  853. return;
  854. OnSwDoScroll( MAKEWORD( nSBCode, -1 ), nPos );
  855. if( nSBCode == SB_ENDSCROLL
  856. && ( ! OnSwQueryThumbTrackEnabled( true ) )
  857. )
  858. OnSwInvalidate( false );
  859. }
  860. void CExtScrollWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  861. {
  862. if( pScrollBar != NULL
  863. && pScrollBar->SendChildNotifyLastMsg()
  864. )
  865. return;
  866. if( pScrollBar != GetScrollBarCtrl(SB_VERT) )
  867. return;
  868. if( nSBCode == SB_ENDSCROLL )
  869. return;
  870. OnSwDoScroll( MAKEWORD( -1, nSBCode ), nPos );
  871. if( nSBCode == SB_ENDSCROLL
  872. && ( ! OnSwQueryThumbTrackEnabled( false ) )
  873. )
  874. OnSwInvalidate( false );
  875. }
  876. BOOL CExtScrollWnd::OnMouseWheel(UINT fFlags, short zDelta, CPoint point)
  877. {
  878. return
  879. OnSwDoMouseWheel( fFlags, zDelta, point )
  880. ? true : false;
  881. }
  882. BOOL CExtScrollWnd::OnEraseBkgnd(CDC* pDC) 
  883. {
  884. if( m_bEatErasing )
  885. return TRUE;
  886. return CWnd::OnEraseBkgnd(pDC);
  887. }
  888. void CExtScrollWnd::OnPaint() 
  889. {
  890. bool bSingleBufferPaint = false;
  891. CPaintDC dcPaint( this );
  892. CExtPaintManager::stat_ExcludeChildAreas(
  893. dcPaint.m_hDC,
  894. m_hWnd,
  895. CExtPaintManager::stat_DefExcludeChildAreaCallback
  896. );
  897. CRect rcAreaBetweenScrollBarWindows( 0, 0, 0, 0 );
  898. CScrollBar * pScrollBarH = GetScrollBarCtrl( SB_HORZ );
  899. CScrollBar * pScrollBarV = GetScrollBarCtrl( SB_VERT );
  900. if( pScrollBarH->GetSafeHwnd() != NULL
  901. && pScrollBarV->GetSafeHwnd() != NULL
  902. && ( pScrollBarH->GetStyle() & WS_VISIBLE ) != 0
  903. && ( pScrollBarV->GetStyle() & WS_VISIBLE ) != 0
  904. )
  905. {
  906. CRect rcH, rcV;
  907. pScrollBarH->GetWindowRect( &rcH );
  908. pScrollBarV->GetWindowRect( &rcV );
  909. ScreenToClient( &rcH );
  910. ScreenToClient( &rcV );
  911. rcAreaBetweenScrollBarWindows.SetRect( rcV.left, rcH.top, rcV.right, rcH.bottom );
  912. } // if( pScrollBarH->GetSafeHwnd() != NULL ...
  913. CPoint ptSp = OnSwGetScrollPaintPos();
  914. if( m_bBufferedPainting )
  915. {
  916. CRect rcClient;
  917. GetClientRect( &rcClient );
  918. CExtMemoryDC dc( &dcPaint, m_bClientCB ? (&rcClient) : NULL );
  919. ASSERT( dc.GetSafeHdc() != NULL );
  920. if( dc.GetSafeHdc() != NULL )
  921. {
  922. CPoint ptVpOld( dc.SetViewportOrg( -ptSp ) );
  923. OnSwPaint( dc );
  924. dc.SetViewportOrg( ptVpOld );
  925. if( (! rcAreaBetweenScrollBarWindows.IsRectEmpty() )
  926. && dc.RectVisible( &rcAreaBetweenScrollBarWindows )
  927. )
  928. OnSwPaintAreaBetweenScrollBarWindows(
  929. dc,
  930. rcAreaBetweenScrollBarWindows
  931. );
  932. } // if( dc.GetSafeHdc() != NULL )
  933. else
  934. bSingleBufferPaint = true;
  935. } // if( m_bBufferedPainting )
  936. else
  937. bSingleBufferPaint = true;
  938. if( bSingleBufferPaint )
  939. {
  940. CPoint ptVpOld( dcPaint.SetViewportOrg( -ptSp ) );
  941. OnSwPaint( dcPaint );
  942. dcPaint.SetViewportOrg( ptVpOld );
  943. if( (! rcAreaBetweenScrollBarWindows.IsRectEmpty() )
  944. && dcPaint.RectVisible( &rcAreaBetweenScrollBarWindows )
  945. )
  946. OnSwPaintAreaBetweenScrollBarWindows(
  947. dcPaint,
  948. rcAreaBetweenScrollBarWindows
  949. );
  950. } // if( bSingleBufferPaint )
  951. }
  952. LRESULT CExtScrollWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
  953. {
  954. if( message == WM_PRINT || message == WM_PRINTCLIENT )
  955. {
  956. CDC * pDC = CDC::FromHandle( (HDC)wParam );
  957. if( (lParam&(PRF_CLIENT|PRF_ERASEBKGND)) != 0 )
  958. {
  959. OnSwPaint( *pDC );
  960. CScrollBar * pScrollBarH = GetScrollBarCtrl( SB_HORZ );
  961. CScrollBar * pScrollBarV = GetScrollBarCtrl( SB_VERT );
  962. if( pScrollBarH->GetSafeHwnd() != NULL
  963. && pScrollBarV->GetSafeHwnd() != NULL
  964. && ( pScrollBarH->GetStyle() & WS_VISIBLE ) != 0
  965. && ( pScrollBarV->GetStyle() & WS_VISIBLE ) != 0
  966. )
  967. {
  968. CRect rcH, rcV;
  969. pScrollBarH->GetWindowRect( &rcH );
  970. pScrollBarV->GetWindowRect( &rcV );
  971. ScreenToClient( &rcH );
  972. ScreenToClient( &rcV );
  973. CRect rcAreaBetweenScrollBarWindows( rcV.left, rcH.top, rcV.right, rcH.bottom );
  974. if( (! rcAreaBetweenScrollBarWindows.IsRectEmpty() )
  975. && pDC->RectVisible( &rcAreaBetweenScrollBarWindows )
  976. )
  977. OnSwPaintAreaBetweenScrollBarWindows(
  978. *pDC,
  979. rcAreaBetweenScrollBarWindows
  980. );
  981. } // if( pScrollBarH->GetSafeHwnd() != NULL ...
  982. }
  983. if( (lParam&PRF_CHILDREN) != 0 )
  984. CExtPaintManager::stat_PrintChildren(
  985. m_hWnd,
  986. message,
  987. pDC->GetSafeHdc(),
  988. lParam,
  989. false
  990. );
  991. return (!0);
  992. }
  993. return CWnd::WindowProc(message, wParam, lParam);
  994. }
  995. void CExtScrollWnd::OnSwPaintAreaBetweenScrollBarWindows(
  996. CDC & dc,
  997. const RECT & rcAreaBetweenScrollBarWindows
  998. )
  999. {
  1000. ASSERT_VALID( this );
  1001. ASSERT( GetSafeHwnd() != NULL );
  1002. ASSERT( dc.GetSafeHdc() != NULL );
  1003. CRect rc = rcAreaBetweenScrollBarWindows;
  1004. CExtMemoryDC dcMem( &dc, &rc );
  1005. CExtPaintManager * pPM = PmBridge_GetPM();
  1006. ASSERT_VALID( pPM );
  1007. if( (! pPM->GetCb2DbTransparentMode(this ) )
  1008. || (! pPM->PaintDockerBkgnd( true, dcMem, this ) )
  1009. //|| (! pPM->PaintDocumentClientAreaBkgnd( dcMem, this ) )
  1010. )
  1011. dc.FillSolidRect(
  1012. &rc,
  1013. pPM->GetColor(
  1014. CExtPaintManager::CLR_3DFACE_OUT,
  1015. this
  1016. )
  1017. );
  1018. }
  1019. BOOL CExtScrollWnd::PreTranslateMessage(MSG* pMsg) 
  1020. {
  1021. if( pMsg->message == WM_MOUSEWHEEL
  1022. && GetSafeHwnd() != NULL
  1023. && CExtPopupMenuWnd::TestHoverEnabledFromActiveHWND(
  1024. GetSafeHwnd()
  1025. )
  1026. )
  1027. {
  1028. CPoint point = pMsg->lParam;
  1029. HWND hWnd = ::WindowFromPoint( point );
  1030. if( hWnd != NULL && hWnd == m_hWnd )
  1031. {
  1032. UINT fFlags = LOWORD(pMsg->wParam);
  1033. short zDelta = HIWORD(pMsg->wParam);
  1034. if( OnSwDoMouseWheel( fFlags, zDelta, point ) )
  1035. return TRUE;
  1036. }
  1037. }
  1038. return CWnd::PreTranslateMessage(pMsg);
  1039. }
  1040. void CExtScrollWnd::OnSwEnsurePointAvail( CPoint point )
  1041. {
  1042. ASSERT_VALID( this );
  1043. if( GetSafeHwnd() == NULL)
  1044. return;
  1045. if( ! ::IsWindow( GetSafeHwnd() ) )
  1046. return;
  1047. if( ! ( OnSwHasScrollBar(false) || OnSwHasScrollBar(true) ) )
  1048. return;
  1049. CRect rcClient;
  1050. CWnd::GetClientRect( &rcClient );
  1051. // if( rcClient.PtInRect(point) )
  1052. // return;
  1053. CPoint ptScrollOrg( OnSwGetScrollPos() );
  1054. CPoint ptScroll( ptScrollOrg );
  1055. CSize sizeTotal( OnSwGetTotalSize() );
  1056. if( OnSwHasScrollBar(true) )
  1057. {
  1058. if( point.x < 0 )
  1059. ptScroll.x += point.x;
  1060. else if( point.x > rcClient.Width() )
  1061. ptScroll.x += point.x - rcClient.Width();
  1062. if( ptScroll.x < 0 )
  1063. ptScroll.x = 0;
  1064. else if( ptScroll.x > sizeTotal.cx )
  1065. ptScroll.x = sizeTotal.cx;
  1066. } // if( OnSwHasScrollBar(true) )
  1067. if( OnSwHasScrollBar(false) )
  1068. {
  1069. if( point.y < 0 )
  1070. ptScroll.y += point.y;
  1071. else if( point.y > rcClient.Height() )
  1072. ptScroll.y += point.y - rcClient.Height();
  1073. if( ptScroll.y < 0 )
  1074. ptScroll.y = 0;
  1075. else if( ptScroll.y > sizeTotal.cy )
  1076. ptScroll.y = sizeTotal.cy;
  1077. } // if( OnSwHasScrollBar(false) )
  1078. if( ptScrollOrg != ptScroll )
  1079. OnSwSetScrollPos( ptScroll );
  1080. }
  1081. #if (!defined __EXT_MFC_NO_SCROLLITEMWND)
  1082. /////////////////////////////////////////////////////////////////////////////
  1083. // CExtScrollItemWnd window & CExtScrollItemCacheInfo helper
  1084. CExtScrollItemCacheInfo::CExtScrollItemCacheInfo(
  1085. LONG nPosH,   // = 0L
  1086. LONG nMaxH,   // = 0L
  1087. LONG nPageSizeH, // = 0L
  1088. LONG nPosV,   // = 0L
  1089. LONG nMaxV,   // = 0L
  1090. LONG nPageSizeV, // = 0L
  1091. bool bBeginH,    // = false
  1092. bool bEndH,      // = false
  1093. bool bBeginV,    // = false
  1094. bool bEndV       // = false
  1095. )
  1096. : m_nPosH( nPosH )
  1097. , m_nMaxH( nMaxH )
  1098. , m_nPageSizeH( nPageSizeH )
  1099. , m_nPosV( nPosV )
  1100. , m_nMaxV( nMaxV )
  1101. , m_nPageSizeV( nPageSizeV )
  1102. , m_bBeginH( bBeginH )
  1103. , m_bEndH( bEndH )
  1104. , m_bBeginV( bBeginV )
  1105. , m_bEndV( bEndV )
  1106. {
  1107. ASSERT( IsValid() );
  1108. }
  1109. CExtScrollItemCacheInfo::CExtScrollItemCacheInfo(
  1110. const CExtScrollItemCacheInfo & other
  1111. )
  1112. {
  1113. (*this) = other;
  1114. ASSERT( IsValid() );
  1115. }
  1116. void CExtScrollItemCacheInfo::Assign(
  1117. const CExtScrollItemCacheInfo & other,
  1118. bool bAssignH, // = true
  1119. bool bAssignV // = true
  1120. )
  1121. {
  1122. if( bAssignH )
  1123. {
  1124. m_nPosH = other.m_nPosH;
  1125. m_nMaxH = other.m_nMaxH;
  1126. m_nPageSizeH = other.m_nPageSizeH;
  1127. m_bBeginH = other.m_bBeginH;
  1128. m_bEndH = other.m_bEndH;
  1129. } // if( bAssignH )
  1130. if( bAssignV )
  1131. {
  1132. m_nPosV = other.m_nPosV;
  1133. m_nMaxV = other.m_nMaxV;
  1134. m_nPageSizeV = other.m_nPageSizeV;
  1135. m_bBeginV = other.m_bBeginV;
  1136. m_bEndV = other.m_bEndV;
  1137. } // if( bAssignV )
  1138. ASSERT( IsValid() );
  1139. }
  1140. void CExtScrollItemCacheInfo::AssignH(
  1141. const CExtScrollItemCacheInfo & other
  1142. )
  1143. {
  1144. Assign( other, true, false );
  1145. }
  1146. void CExtScrollItemCacheInfo::AssignV(
  1147. const CExtScrollItemCacheInfo & other
  1148. )
  1149. {
  1150. Assign( other, false, true );
  1151. }
  1152. CExtScrollItemCacheInfo & CExtScrollItemCacheInfo::operator = (
  1153. const CExtScrollItemCacheInfo & other
  1154. )
  1155. {
  1156. Assign( other );
  1157. return (*this);
  1158. }
  1159. bool CExtScrollItemCacheInfo::operator == (
  1160. const CExtScrollItemCacheInfo & other
  1161. ) const
  1162. {
  1163. return IsEqual( other );
  1164. }
  1165. bool CExtScrollItemCacheInfo::operator != (
  1166. const CExtScrollItemCacheInfo & other
  1167. ) const
  1168. {
  1169. return ( ! IsEqual( other ) );
  1170. }
  1171. void CExtScrollItemCacheInfo::Empty(
  1172. bool bEmptyH, // = true
  1173. bool bEmptyV // = true
  1174. )
  1175. {
  1176. ASSERT( IsValid() );
  1177. if( bEmptyH )
  1178. {
  1179. m_nPosH = 0L;
  1180. m_nMaxH = 0L;
  1181. m_nPageSizeH = 0L;
  1182. m_bBeginH = false;
  1183. m_bEndH = false;
  1184. } // if( bEmptyH )
  1185. if( bEmptyV )
  1186. {
  1187. m_nPosV = 0L;
  1188. m_nMaxV = 0L;
  1189. m_nPageSizeV = 0L;
  1190. m_bBeginV = false;
  1191. m_bEndV = false;
  1192. } // if( bEmptyV )
  1193. }
  1194. void CExtScrollItemCacheInfo::EmptyH()
  1195. {
  1196. ASSERT( IsValid() );
  1197. Empty( true, false );
  1198. }
  1199. void CExtScrollItemCacheInfo::EmptyV()
  1200. {
  1201. ASSERT( IsValid() );
  1202. Empty( false, true );
  1203. }
  1204. bool CExtScrollItemCacheInfo::IsEmpty(
  1205. bool bCheckEmptyH, // = true
  1206. bool bCheckEmptyV // = true
  1207. ) const
  1208. {
  1209. ASSERT( IsValid() );
  1210. if( ( bCheckEmptyH
  1211. && m_nMaxH != 0L
  1212. )
  1213. || ( bCheckEmptyV
  1214. && m_nMaxV != 0L
  1215. )
  1216. )
  1217. return false;
  1218. return true;
  1219. }
  1220. bool CExtScrollItemCacheInfo::IsEmptyH() const
  1221. {
  1222. ASSERT( IsValid() );
  1223. return IsEmpty( true, false );
  1224. }
  1225. bool CExtScrollItemCacheInfo::IsEmptyV() const
  1226. {
  1227. ASSERT( IsValid() );
  1228. return IsEmpty( false, true );
  1229. }
  1230. bool CExtScrollItemCacheInfo::IsValid() const
  1231. {
  1232. if( m_nPosH >= 0L
  1233. && m_nPosV >= 0L
  1234. && m_nMaxH >= 0L
  1235. && m_nMaxV >= 0L
  1236. && m_nPageSizeH >= 0L
  1237. && m_nPageSizeV >= 0L
  1238. && 0L <= m_nPosH && m_nPosH <= m_nMaxH
  1239. && 0L <= m_nPosV && m_nPosV <= m_nMaxV
  1240. )
  1241. return true;
  1242. return false;
  1243. }
  1244. bool CExtScrollItemCacheInfo::IsEqual( // static
  1245. const CExtScrollItemCacheInfo & left,
  1246. const CExtScrollItemCacheInfo & right,
  1247. bool bComparePosH,   // = true
  1248. bool bComparePosV,   // = true
  1249. bool bCompareMaxH,   // = true
  1250. bool bCompareMaxV,   // = true
  1251. bool bComparePageSizeH, // = true
  1252. bool bComparePageSizeV, // = true
  1253. bool bCompareBofH,      // = false
  1254. bool bCompareBofV,      // = false
  1255. bool bCompareEofH,      // = false
  1256. bool bCompareEofV       // = false
  1257. )
  1258. {
  1259. ASSERT( left.IsValid() );
  1260. ASSERT( left.IsValid() );
  1261. if( ( bComparePosH
  1262. && left.m_nPosH != right.m_nPosH
  1263. )
  1264. || ( bComparePosV
  1265. && left.m_nPosV != right.m_nPosV
  1266. )
  1267. || ( bCompareMaxH
  1268. && left.m_nMaxH != right.m_nMaxH
  1269. )
  1270. || ( bCompareMaxV
  1271. && left.m_nMaxV != right.m_nMaxV
  1272. )
  1273. || ( bComparePageSizeH
  1274. && left.m_nPageSizeH != right.m_nPageSizeH
  1275. )
  1276. || ( bComparePageSizeV
  1277. && left.m_nPageSizeV != right.m_nPageSizeV
  1278. )
  1279. || ( bCompareBofH
  1280. && left.m_bBeginH != right.m_bBeginH
  1281. )
  1282. || ( bCompareBofV
  1283. && left.m_bBeginV != right.m_bBeginV
  1284. )
  1285. || ( bCompareEofH
  1286. && left.m_bEndH != right.m_bEndH
  1287. )
  1288. || ( bCompareEofV
  1289. && left.m_bEndV != right.m_bEndV
  1290. )
  1291. )
  1292. return false;
  1293. return true;
  1294. }
  1295. bool CExtScrollItemCacheInfo::IsEqual(
  1296. const CExtScrollItemCacheInfo & other,
  1297. bool bComparePosH,   // = true
  1298. bool bComparePosV,   // = true
  1299. bool bCompareMaxH,   // = true
  1300. bool bCompareMaxV,   // = true
  1301. bool bComparePageSizeH, // = true
  1302. bool bComparePageSizeV, // = true
  1303. bool bCompareBofH,      // = false
  1304. bool bCompareBofV,      // = false
  1305. bool bCompareEofH,      // = false
  1306. bool bCompareEofV       // = false
  1307. ) const
  1308. {
  1309. return
  1310. IsEqual(
  1311. *this, other,
  1312. bComparePosH, bComparePosV,
  1313. bCompareMaxH, bCompareMaxV,
  1314. bComparePageSizeH, bComparePageSizeV,
  1315. bCompareBofH, bCompareBofV,
  1316. bCompareEofH, bCompareEofV
  1317. );
  1318. }
  1319. LONG CExtScrollItemCacheInfo::GetExtentH() const
  1320. {
  1321. ASSERT( IsValid() );
  1322. return (m_nMaxH + m_nPageSizeH);
  1323. }
  1324. LONG CExtScrollItemCacheInfo::GetExtentV() const
  1325. {
  1326. ASSERT( IsValid() );
  1327. return (m_nMaxV + m_nPageSizeV);
  1328. }
  1329. LONG CExtScrollItemCacheInfo::GetPosChangingH(
  1330. const CExtScrollItemCacheInfo & _sciOld
  1331. ) const
  1332. {
  1333. ASSERT( IsValid() );
  1334. return (m_nPosH - _sciOld.m_nPosH);
  1335. }
  1336. LONG CExtScrollItemCacheInfo::GetPosChangingV(
  1337. const CExtScrollItemCacheInfo & _sciOld
  1338. ) const
  1339. {
  1340. ASSERT( IsValid() );
  1341. return (m_nPosV - _sciOld.m_nPosV);
  1342. }
  1343. LONG CExtScrollItemCacheInfo::GetMaxChangingH(
  1344. const CExtScrollItemCacheInfo & _sciOld
  1345. ) const
  1346. {
  1347. ASSERT( IsValid() );
  1348. return (m_nMaxH - _sciOld.m_nMaxH);
  1349. }
  1350. LONG CExtScrollItemCacheInfo::GetMaxChangingV(
  1351. const CExtScrollItemCacheInfo & _sciOld
  1352. ) const
  1353. {
  1354. ASSERT( IsValid() );
  1355. return (m_nMaxV - _sciOld.m_nMaxV);
  1356. }
  1357. LONG CExtScrollItemCacheInfo::GetExtentChangingH(
  1358. const CExtScrollItemCacheInfo & _sciOld
  1359. ) const
  1360. {
  1361. ASSERT( IsValid() );
  1362. LONG nExtentThis = GetExtentH();
  1363. LONG nExtentOld = _sciOld.GetExtentH();
  1364. return (nExtentThis - nExtentOld);
  1365. }
  1366. LONG CExtScrollItemCacheInfo::GetExtentChangingV(
  1367. const CExtScrollItemCacheInfo & _sciOld
  1368. ) const
  1369. {
  1370. ASSERT( IsValid() );
  1371. LONG nExtentThis = GetExtentV();
  1372. LONG nExtentOld = _sciOld.GetExtentV();
  1373. return (nExtentThis - nExtentOld);
  1374. }
  1375. LONG CExtScrollItemCacheInfo::GetPageSizeChangingH(
  1376. const CExtScrollItemCacheInfo & _sciOld
  1377. ) const
  1378. {
  1379. ASSERT( IsValid() );
  1380. return (m_nPageSizeH - _sciOld.m_nPageSizeH);
  1381. }
  1382. LONG CExtScrollItemCacheInfo::GetPageSizeChangingV(
  1383. const CExtScrollItemCacheInfo & _sciOld
  1384. ) const
  1385. {
  1386. ASSERT( IsValid() );
  1387. return (m_nPageSizeV - _sciOld.m_nPageSizeV);
  1388. }
  1389. bool CExtScrollItemCacheInfo::IsShiftToBofH(
  1390. const CExtScrollItemCacheInfo & _sciOld
  1391. ) const
  1392. {
  1393. ASSERT( IsValid() );
  1394. return (m_bBeginH&&(!_sciOld.m_bBeginH)) ? true : false;
  1395. }
  1396. bool CExtScrollItemCacheInfo::IsShiftToBofV(
  1397. const CExtScrollItemCacheInfo & _sciOld
  1398. ) const
  1399. {
  1400. ASSERT( IsValid() );
  1401. return (m_bBeginV&&(!_sciOld.m_bBeginV)) ? true : false;
  1402. }
  1403. bool CExtScrollItemCacheInfo::IsShiftToEofH(
  1404. const CExtScrollItemCacheInfo & _sciOld
  1405. ) const
  1406. {
  1407. ASSERT( IsValid() );
  1408. return (m_bEndH&&(!_sciOld.m_bEndH)) ? true : false;
  1409. }
  1410. bool CExtScrollItemCacheInfo::IsShiftToEofV(
  1411. const CExtScrollItemCacheInfo & _sciOld
  1412. ) const
  1413. {
  1414. ASSERT( IsValid() );
  1415. return (m_bEndV&&(!_sciOld.m_bEndV)) ? true : false;
  1416. }
  1417. void CExtScrollItemCacheInfo::FlipHV()
  1418. {
  1419. ASSERT( IsValid() );
  1420. LONG nTemp;
  1421. bool bTemp;
  1422. nTemp = m_nPosH;
  1423. m_nPosH = m_nPosV;
  1424. m_nPosV = nTemp;
  1425. nTemp = m_nMaxH;
  1426. m_nMaxH = m_nMaxV;
  1427. m_nMaxV = nTemp;
  1428. nTemp = m_nPageSizeH;
  1429. m_nPageSizeH = m_nPageSizeV;
  1430. m_nPageSizeV = nTemp;
  1431. bTemp = m_bBeginH;
  1432. m_bBeginH = m_bBeginV;
  1433. m_bBeginV = bTemp;
  1434. bTemp = m_bEndH;
  1435. m_bEndH = m_bEndV;
  1436. m_bEndV = bTemp;
  1437. ASSERT( IsValid() );
  1438. }
  1439. IMPLEMENT_DYNCREATE( CExtScrollItemWnd, CExtScrollWnd );
  1440. CExtScrollItemWnd::CExtScrollItemWnd()
  1441. : m_bDirectCreateCall( false )
  1442. , m_dwScrollItemWndStyle( 0L )
  1443. , m_dwScrollItemWndStyleEx( 0L )
  1444. , m_bExtractResourceStyles( true )
  1445. {
  1446. VERIFY( RegisterScrollItemWndClass() );
  1447. }
  1448. CExtScrollItemWnd::~CExtScrollItemWnd()
  1449. {
  1450. }
  1451. BEGIN_MESSAGE_MAP(CExtScrollItemWnd,CExtScrollWnd)
  1452. //{{AFX_MSG_MAP(CExtScrollItemWnd)
  1453. //}}AFX_MSG_MAP
  1454. END_MESSAGE_MAP()
  1455. bool CExtScrollItemWnd::g_bScrollItemWndClassRegistered = false;
  1456. bool CExtScrollItemWnd::RegisterScrollItemWndClass()
  1457. {
  1458. if( g_bScrollItemWndClassRegistered )
  1459. return true;
  1460. WNDCLASS _wndClassInfo;
  1461. HINSTANCE hInst = ::AfxGetInstanceHandle();
  1462. if( ! ::GetClassInfo( hInst, __EXT_SCROLLITEMWND_CLASS_NAME, &_wndClassInfo ) )
  1463. {
  1464. _wndClassInfo.style = CS_GLOBALCLASS|CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
  1465. _wndClassInfo.lpfnWndProc = ::DefWindowProc;
  1466. _wndClassInfo.cbClsExtra = _wndClassInfo.cbWndExtra = 0;
  1467. _wndClassInfo.hInstance = hInst;
  1468. _wndClassInfo.hIcon = NULL;
  1469. _wndClassInfo.hCursor = ::LoadCursor( NULL, IDC_ARROW );
  1470. ASSERT( _wndClassInfo.hCursor != NULL );
  1471. _wndClassInfo.hbrBackground = NULL; 
  1472. _wndClassInfo.lpszMenuName = NULL;
  1473. _wndClassInfo.lpszClassName = __EXT_SCROLLITEMWND_CLASS_NAME;
  1474. if( ! ::AfxRegisterClass( &_wndClassInfo ) )
  1475. {
  1476. ASSERT( FALSE );
  1477. //AfxThrowResourceException();
  1478. return false;
  1479. }
  1480. }
  1481. g_bScrollItemWndClassRegistered = true;
  1482. return true;
  1483. }
  1484. BOOL CExtScrollItemWnd::Create(
  1485. CWnd * pParentWnd,
  1486. const RECT & rcWnd, // = CRect( 0, 0, 0, 0 )
  1487. UINT nDlgCtrlID, // = UINT( __EXT_MFC_IDC_STATIC )
  1488. DWORD dwScrollItemWndStyle, // = 0L
  1489. DWORD dwWindowStyle, // = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN
  1490. CCreateContext * pContext // = NULL
  1491. )
  1492. {
  1493. ASSERT_VALID( this );
  1494. pContext;
  1495. if( ! RegisterScrollItemWndClass() )
  1496. {
  1497. ASSERT( FALSE );
  1498. return FALSE;
  1499. }
  1500. m_bDirectCreateCall = true;
  1501. m_dwScrollItemWndStyle = dwScrollItemWndStyle;
  1502. if( ! CWnd::CreateEx( 0L, __EXT_SCROLLITEMWND_CLASS_NAME, _T(""), dwWindowStyle, rcWnd, pParentWnd, nDlgCtrlID ) )
  1503. {
  1504. ASSERT( FALSE );
  1505. return FALSE;
  1506. }
  1507. if( !_CreateHelper() )
  1508. {
  1509. ASSERT( FALSE );
  1510. AfxThrowMemoryException();
  1511. }
  1512. return TRUE;
  1513. }
  1514. BOOL CExtScrollItemWnd::PreCreateWindow(CREATESTRUCT& cs) 
  1515. {
  1516. ASSERT_VALID( this );
  1517. if( ( !RegisterScrollItemWndClass() )
  1518. || ( !CWnd::PreCreateWindow(cs) )
  1519. )
  1520. {
  1521. ASSERT( FALSE );
  1522. return FALSE;
  1523. }
  1524. cs.lpszClass = __EXT_SCROLLITEMWND_CLASS_NAME;
  1525. cs.style |= WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
  1526. return TRUE;
  1527. }
  1528. bool CExtScrollItemWnd::_CreateHelper()
  1529. {
  1530. ASSERT_VALID( this );
  1531. OnSwUpdateScrollBars();
  1532. OnSwDoRedraw();
  1533. return true;
  1534. }
  1535. void CExtScrollItemWnd::PreSubclassWindow() 
  1536. {
  1537. ASSERT_VALID( this );
  1538. CWnd::PreSubclassWindow();
  1539. if( m_bDirectCreateCall )
  1540. return;
  1541. if( m_bExtractResourceStyles )
  1542. {
  1543. __EXT_MFC_LONG_PTR dwStyle = ::__EXT_MFC_GetWindowLong( m_hWnd, GWL_STYLE );
  1544. m_dwScrollItemWndStyle = DWORD( dwStyle & __EXTMFC_ALL_FORM_MOVABLE_WND_STYLES );
  1545. ::__EXT_MFC_SetWindowLong( m_hWnd, GWL_STYLE, dwStyle & (~__EXTMFC_ALL_FORM_MOVABLE_WND_STYLES) );
  1546. } // if( m_bExtractResourceStyles )
  1547. if( !_CreateHelper() )
  1548. {
  1549. ASSERT( FALSE );
  1550. AfxThrowMemoryException();
  1551. } // if( !Create() )
  1552. }
  1553. DWORD CExtScrollItemWnd::SiwGetStyle() const
  1554. {
  1555. ASSERT( this != NULL );
  1556. return m_dwScrollItemWndStyle;
  1557. }
  1558. DWORD CExtScrollItemWnd::SiwModifyStyle(
  1559. DWORD dwStyleAdd,
  1560. DWORD dwStyleRemove, // = 0L
  1561. bool bUpdateWnd // = true
  1562. )
  1563. {
  1564. ASSERT( this != NULL );
  1565. DWORD dwScrollItemWndStyleOld = SiwGetStyle();
  1566. if( dwStyleAdd == 0 && dwStyleRemove == 0 )
  1567. return dwScrollItemWndStyleOld;
  1568. m_dwScrollItemWndStyle &= ~dwStyleRemove;
  1569. m_dwScrollItemWndStyle |= dwStyleAdd;
  1570. if( bUpdateWnd
  1571. && GetSafeHwnd() != NULL
  1572. && ::IsWindow( GetSafeHwnd() )
  1573. )
  1574. {
  1575. OnSwUpdateScrollBars();
  1576. OnSwDoRedraw();
  1577. }
  1578. return dwScrollItemWndStyleOld;
  1579. }
  1580. DWORD CExtScrollItemWnd::SiwGetStyleEx() const
  1581. {
  1582. ASSERT( this != NULL );
  1583. return m_dwScrollItemWndStyleEx;
  1584. }
  1585. DWORD CExtScrollItemWnd::SiwModifyStyleEx(
  1586. DWORD dwStyleExAdd,
  1587. DWORD dwStyleExRemove, // = 0L
  1588. bool bUpdateWnd // = true
  1589. )
  1590. {
  1591. ASSERT( this != NULL );
  1592. DWORD dwScrollItemWndStyleExOld = SiwGetStyle();
  1593. if( dwStyleExAdd == 0 && dwStyleExRemove == 0 )
  1594. return dwScrollItemWndStyleExOld;
  1595. m_dwScrollItemWndStyleEx &= ~dwStyleExRemove;
  1596. m_dwScrollItemWndStyleEx |= dwStyleExAdd;
  1597. if( bUpdateWnd
  1598. && GetSafeHwnd() != NULL
  1599. && ::IsWindow( GetSafeHwnd() )
  1600. )
  1601. {
  1602. OnSwUpdateScrollBars();
  1603. OnSwDoRedraw();
  1604. }
  1605. return dwScrollItemWndStyleExOld;
  1606. }
  1607. DWORD CExtScrollItemWnd::SiwScrollTypeHGet() const
  1608. {
  1609. ASSERT( this != NULL );
  1610. DWORD dwScrollItemWndStyle = SiwGetStyle();
  1611. return (dwScrollItemWndStyle&__ESIS_STH_MASK);
  1612. }
  1613. DWORD CExtScrollItemWnd::SiwScrollTypeVGet() const
  1614. {
  1615. ASSERT( this != NULL );
  1616. DWORD dwScrollItemWndStyle = SiwGetStyle();
  1617. return ((dwScrollItemWndStyle&__ESIS_STV_MASK) >> __ESIW_ST_BIT_COUNT);
  1618. }
  1619. DWORD CExtScrollItemWnd::SiwScrollTypeHSet(
  1620. DWORD dwScrollTypeNew,
  1621. bool bUpdateWnd // = true
  1622. )
  1623. {
  1624. ASSERT( this != NULL );
  1625. dwScrollTypeNew &= __ESIW_ST_MASK;
  1626. DWORD dwScrollTypeOld = SiwScrollTypeHGet();
  1627. if( dwScrollTypeNew == dwScrollTypeOld )
  1628. return dwScrollTypeOld;
  1629. SiwModifyStyle(
  1630. dwScrollTypeNew,
  1631. __ESIS_STH_MASK,
  1632. bUpdateWnd
  1633. );
  1634. return dwScrollTypeOld;
  1635. }
  1636. DWORD CExtScrollItemWnd::SiwScrollTypeVSet(
  1637. DWORD dwScrollTypeNew,
  1638. bool bUpdateWnd // = true
  1639. )
  1640. {
  1641. ASSERT( this != NULL );
  1642. dwScrollTypeNew &= __ESIW_ST_MASK;
  1643. DWORD dwScrollTypeOld = SiwScrollTypeVGet();
  1644. if( dwScrollTypeNew == dwScrollTypeOld )
  1645. return dwScrollTypeOld;
  1646. SiwModifyStyle(
  1647. dwScrollTypeNew << __ESIW_ST_BIT_COUNT,
  1648. __ESIS_STV_MASK,
  1649. bUpdateWnd
  1650. );
  1651. return dwScrollTypeOld;
  1652. }
  1653. bool CExtScrollItemWnd::SiwPreferHorizontalWalkGet() const
  1654. {
  1655. ASSERT_VALID( this );
  1656. bool bPreferHorizontalWalk =
  1657. ( (SiwGetStyle() & __ESIS_PREFER_HORZ_WALK) != 0 )
  1658. ? true : false;
  1659. return bPreferHorizontalWalk;
  1660. }
  1661. bool CExtScrollItemWnd::SiwPreferHorizontalWalkSet(
  1662. bool bPreferHorizontalWalk
  1663. )
  1664. {
  1665. bool bPreferHorizontalWalkOld = SiwPreferHorizontalWalkGet();
  1666. if( (bPreferHorizontalWalk && bPreferHorizontalWalkOld)
  1667. || ((!bPreferHorizontalWalk) && (!bPreferHorizontalWalkOld))
  1668. )
  1669. return bPreferHorizontalWalkOld;
  1670. SiwModifyStyle(
  1671. ( (bPreferHorizontalWalk) ? __ESIS_PREFER_HORZ_WALK : 0 ),
  1672. __ESIS_PREFER_HORZ_WALK,
  1673. false
  1674. );
  1675. return bPreferHorizontalWalkOld;
  1676. }
  1677. CSize CExtScrollItemWnd::OnSwGetLineSize( int nDirection ) const
  1678. {
  1679. ASSERT_VALID( this );
  1680. nDirection;
  1681. static const CSize g_sizePixelScrollStep( 3, 3 );
  1682. CSize _sizeLine( 0, 0 );
  1683. DWORD dwScrollType = SiwScrollTypeHGet();
  1684. if( dwScrollType == __ESIW_ST_PIXEL )
  1685. _sizeLine.cx = g_sizePixelScrollStep.cx;
  1686. else if( dwScrollType == __ESIW_ST_ITEM
  1687. || dwScrollType == __ESIW_ST_VIRTUAL
  1688. )
  1689. _sizeLine.cx = 1;
  1690. dwScrollType = SiwScrollTypeVGet();
  1691. if( dwScrollType == __ESIW_ST_PIXEL )
  1692. _sizeLine.cy = g_sizePixelScrollStep.cy;
  1693. else if( dwScrollType == __ESIW_ST_ITEM
  1694. || dwScrollType == __ESIW_ST_VIRTUAL
  1695. )
  1696. _sizeLine.cy = 1;
  1697. return _sizeLine;
  1698. }
  1699. void CExtScrollItemWnd::OnSwUpdateScrollBars()
  1700. {
  1701. ASSERT_VALID( this );
  1702. if( GetSafeHwnd() == NULL )
  1703. return;
  1704. if( m_nUpdateScrollBars > 1 )
  1705. return;
  1706. m_nUpdateScrollBars ++;
  1707. ASSERT( OnSwGetTotalSize().cx >= 0 && OnSwGetTotalSize().cy >= 0 );
  1708. CRect rcClient;
  1709. bool bCalcClient = true;
  1710. CWnd * pParentWnd = GetParent();
  1711. if( pParentWnd != NULL
  1712. && (BOOL)pParentWnd->SendMessage(
  1713. WM_RECALCPARENT,
  1714. 0,
  1715. (LPARAM)(LPCRECT)&rcClient
  1716. ) != 0
  1717. )
  1718. bCalcClient = false;
  1719. CSize sizeClient;
  1720. CSize sizeSb;
  1721. if( bCalcClient )
  1722. {
  1723. if( !OnSwCalcClientSizes( sizeClient, sizeSb ) )
  1724. { // no room for scroll bars
  1725. CRect rcClient2 = OnSwGetClientRect();
  1726. if( rcClient2.Width() > 0 && rcClient2.Height()> 0 )
  1727. {
  1728. OnSwEnableScrollBarCtrl( SB_BOTH, false );
  1729. OnSwRecalcLayout( true );
  1730. }
  1731. m_nUpdateScrollBars --;
  1732. return;
  1733. }
  1734. }
  1735. else
  1736. { // let parent window determine the "client" rect
  1737. sizeSb = OnSwGetScrollBarSizes();
  1738. sizeClient.cx = rcClient.right - rcClient.left;
  1739. sizeClient.cy = rcClient.bottom - rcClient.top;
  1740. }
  1741. DWORD dwScrollTypeH = SiwScrollTypeHGet();
  1742. DWORD dwScrollTypeV = SiwScrollTypeVGet();
  1743. if( dwScrollTypeH == __ESIW_ST_ITEM || dwScrollTypeV == __ESIW_ST_ITEM )
  1744. {
  1745. CSize _sizeVR = OnSiwGetVisibleRange().Size();
  1746. if( dwScrollTypeH == __ESIW_ST_ITEM )
  1747. sizeClient.cx = _sizeVR.cx;
  1748. if( dwScrollTypeV == __ESIW_ST_ITEM )
  1749. sizeClient.cy = _sizeVR.cy;
  1750. } // if( dwScrollTypeH == __ESIW_ST_ITEM || dwScrollTypeV == __ESIW_ST_ITEM )
  1751. bool bHasSbH0 = OnSwHasScrollBar( true );
  1752. bool bHasSbV0 = OnSwHasScrollBar( false );
  1753. // if enough room to add scrollbars
  1754. CSize sizeRange;
  1755. CPoint ptMove;
  1756. CSize sizeNeedSB;
  1757. OnSwGetScrollBarState(
  1758. sizeClient,
  1759. sizeNeedSB,
  1760. sizeRange,
  1761. ptMove,
  1762. bCalcClient
  1763. );
  1764. // if( bCalcClient )
  1765. // {
  1766. // if( sizeNeedSB.cx != 0
  1767. // && dwScrollTypeV == __ESIW_ST_PIXEL
  1768. // //&& bHasSbH0
  1769. // )
  1770. // sizeClient.cy -= sizeSb.cy;
  1771. // if( sizeNeedSB.cy != 0
  1772. // && dwScrollTypeH == __ESIW_ST_PIXEL
  1773. // //&& bHasSbV0
  1774. // )
  1775. // sizeClient.cx -= sizeSb.cx;
  1776. // } // if( bCalcClient )
  1777. // scroll window + update
  1778. CPoint ptCurrScrollPos = OnSwGetScrollPos();
  1779. if( ptMove != ptCurrScrollPos )
  1780. OnSwSetScrollPos( ptMove );
  1781. // the scrollbar page range
  1782. SCROLLINFO _scroll_info;
  1783. ::memset( &_scroll_info, 0, sizeof(SCROLLINFO) );
  1784. _scroll_info.cbSize = sizeof(SCROLLINFO);
  1785. _scroll_info.fMask = SIF_PAGE|SIF_RANGE;
  1786. _scroll_info.nMin = 0;
  1787. //DWORD dwScrollTypeH = SiwScrollTypeHGet();
  1788. //DWORD dwScrollTypeV = SiwScrollTypeVGet();
  1789. CSize _sizeTotalISR = OnSwGetTotalSize();
  1790. if( _sizeTotalISR.cx < 0 )
  1791. _sizeTotalISR.cx = __EXT_SCROLL_NUMERIC_MAX;
  1792. if( _sizeTotalISR.cy < 0 )
  1793. _sizeTotalISR.cy = __EXT_SCROLL_NUMERIC_MAX;
  1794. CSize _sizePageISR = OnSwGetPageSize( 0 );
  1795. // update bars
  1796. if( dwScrollTypeH == __ESIW_ST_NONE )
  1797. OnSwEnableScrollBarCtrl( SB_HORZ, false );
  1798. else if( dwScrollTypeH == __ESIW_ST_PIXEL )
  1799. {
  1800. OnSwEnableScrollBarCtrl( SB_HORZ, sizeNeedSB.cx ? true : false );
  1801. if( sizeNeedSB.cx )
  1802. {
  1803. _scroll_info.nPage = sizeClient.cx;
  1804. _scroll_info.nMax = OnSwGetTotalSize().cx - 1;
  1805. if( bHasSbH0 && bHasSbV0 )
  1806. _scroll_info.nMax += OnSwGetScrollBarSizes().cx;
  1807. if( ! OnSwScrollInfoAdjust(
  1808. SB_HORZ,
  1809. _scroll_info,
  1810. true
  1811. )
  1812. )
  1813. OnSwSetScrollRange(
  1814. SB_HORZ,
  1815. 0,
  1816. sizeRange.cx,
  1817. true
  1818. );
  1819. } // if( sizeNeedSB.cx )
  1820. } // else if( dwScrollTypeH == __ESIW_ST_PIXEL )
  1821. else if( dwScrollTypeH == __ESIW_ST_ITEM )
  1822. {
  1823. if( _sizeTotalISR.cx > _sizePageISR.cx )
  1824. {
  1825. ASSERT( _sizePageISR.cx >= 0 );
  1826. OnSwEnableScrollBarCtrl( SB_HORZ, true );
  1827. _scroll_info.nPage = _sizePageISR.cx;
  1828. _scroll_info.nMax = _sizeTotalISR.cx - 1;
  1829. if( ! OnSwScrollInfoAdjust(
  1830. SB_HORZ,
  1831. _scroll_info,
  1832. true
  1833. )
  1834. )
  1835. OnSwSetScrollRange(
  1836. SB_HORZ,
  1837. 0,
  1838. _sizeTotalISR.cx,
  1839. true
  1840. );
  1841. }
  1842. else
  1843. OnSwEnableScrollBarCtrl( SB_HORZ, false );
  1844. } // else if( dwScrollTypeH == __ESIW_ST_ITEM )
  1845. else
  1846. { // if __ESIW_ST_VIRTUAL
  1847. ASSERT( dwScrollTypeH == __ESIW_ST_VIRTUAL );
  1848. bool bBOF = OnSiwQueryVirtualBOF( true );
  1849. bool bEOF = OnSiwQueryVirtualEOF( true );
  1850. bool bEnableSB = true;
  1851. if( bBOF )
  1852. {
  1853. if( bEOF )
  1854. bEnableSB = false;
  1855. else
  1856. _scroll_info.nPos = 0;
  1857. } // if( bBOF )
  1858. else
  1859. {
  1860. if( bEOF )
  1861. _scroll_info.nPos = __EXT_SCROLL_NUMERIC_MAX - 1;
  1862. else
  1863. _scroll_info.nPos = __EXT_SCROLL_NUMERIC_MAX / 2;
  1864. } // else from if( bBOF )
  1865. if( bEnableSB )
  1866. {
  1867. OnSwEnableScrollBarCtrl( SB_HORZ, true );
  1868. _scroll_info.fMask = SIF_PAGE|SIF_RANGE|SIF_POS;
  1869. _scroll_info.nPage = _sizePageISR.cx;
  1870. _scroll_info.nMax = __EXT_SCROLL_NUMERIC_MAX;
  1871. if( ! OnSwScrollInfoAdjust(
  1872. SB_HORZ,
  1873. _scroll_info,
  1874. true
  1875. )
  1876. )
  1877. OnSwSetScrollRange(
  1878. SB_HORZ,
  1879. 0,
  1880. _sizeTotalISR.cx,
  1881. true
  1882. );
  1883. } // if( bEnableSB )
  1884. else
  1885. OnSwEnableScrollBarCtrl( SB_HORZ, false );
  1886. } // if __ESIW_ST_VIRTUAL
  1887. // recalc for vertical parms
  1888. _sizeTotalISR = OnSwGetTotalSize();
  1889. if( _sizeTotalISR.cx < 0 )
  1890. _sizeTotalISR.cx = __EXT_SCROLL_NUMERIC_MAX;
  1891. if( _sizeTotalISR.cy < 0 )
  1892. _sizeTotalISR.cy = __EXT_SCROLL_NUMERIC_MAX;
  1893. _sizePageISR = OnSwGetPageSize( 0 );
  1894. if( dwScrollTypeV == __ESIW_ST_NONE )
  1895. OnSwEnableScrollBarCtrl( SB_VERT, false );
  1896. else if( dwScrollTypeV == __ESIW_ST_PIXEL )
  1897. {
  1898. OnSwEnableScrollBarCtrl( SB_VERT, sizeNeedSB.cy ? true : false );
  1899. if( sizeNeedSB.cy )
  1900. {
  1901. _scroll_info.nPage = sizeClient.cy;
  1902. _scroll_info.nMax = OnSwGetTotalSize().cy - 1;
  1903. if( bHasSbH0 && bHasSbV0 )
  1904. _scroll_info.nMax += OnSwGetScrollBarSizes().cy;
  1905. if( ! OnSwScrollInfoAdjust(
  1906. SB_VERT,
  1907. _scroll_info,
  1908. true
  1909. )
  1910. )
  1911. OnSwSetScrollRange(
  1912. SB_VERT,
  1913. 0,
  1914. sizeRange.cy,
  1915. true
  1916. );
  1917. } // if( sizeNeedSB.cy )
  1918. } // else if( dwScrollTypeV == __ESIW_ST_PIXEL )
  1919. else if( dwScrollTypeV == __ESIW_ST_ITEM )
  1920. {
  1921. if( _sizeTotalISR.cy > _sizePageISR.cy )
  1922. {
  1923. ASSERT( _sizePageISR.cy >= 0 );
  1924. OnSwEnableScrollBarCtrl( SB_VERT, true );
  1925. _scroll_info.nPage = _sizePageISR.cy;
  1926. _scroll_info.nMax = _sizeTotalISR.cy - 1;
  1927. if( ! OnSwScrollInfoAdjust(
  1928. SB_VERT,
  1929. _scroll_info,
  1930. true
  1931. )
  1932. )
  1933. OnSwSetScrollRange(
  1934. SB_VERT,
  1935. 0,
  1936. _sizeTotalISR.cy,
  1937. true
  1938. );
  1939. }
  1940. else
  1941. OnSwEnableScrollBarCtrl( SB_VERT, false );
  1942. } // else if( dwScrollTypeV == __ESIW_ST_ITEM )
  1943. else
  1944. { // if __ESIW_ST_VIRTUAL
  1945. ASSERT( dwScrollTypeV == __ESIW_ST_VIRTUAL );
  1946. bool bBOF = OnSiwQueryVirtualBOF( false );
  1947. bool bEOF = OnSiwQueryVirtualEOF( false );
  1948. bool bEnableSB = true;
  1949. if( bBOF )
  1950. {
  1951. if( bEOF )
  1952. bEnableSB = false;
  1953. else
  1954. _scroll_info.nPos = 0;
  1955. } // if( bBOF )
  1956. else
  1957. {
  1958. if( bEOF )
  1959. _scroll_info.nPos = __EXT_SCROLL_NUMERIC_MAX - 1;
  1960. else
  1961. _scroll_info.nPos = __EXT_SCROLL_NUMERIC_MAX / 2;
  1962. } // else from if( bBOF )
  1963. if( bEnableSB )
  1964. {
  1965. OnSwEnableScrollBarCtrl( SB_VERT, true );
  1966. _scroll_info.fMask = SIF_PAGE|SIF_RANGE|SIF_POS;
  1967. _scroll_info.nPage = _sizePageISR.cy;
  1968. _scroll_info.nMax = __EXT_SCROLL_NUMERIC_MAX;
  1969. if( ! OnSwScrollInfoAdjust(
  1970. SB_VERT,
  1971. _scroll_info,
  1972. true
  1973. )
  1974. )
  1975. OnSwSetScrollRange(
  1976. SB_VERT,
  1977. 0,
  1978. _sizeTotalISR.cy,
  1979. true
  1980. );
  1981. } // if( bEnableSB )
  1982. else
  1983. OnSwEnableScrollBarCtrl( SB_VERT, false );
  1984. } // if __ESIW_ST_VIRTUAL
  1985. // adjust virtual position and cache state
  1986. // if( dwScrollTypeH == __ESIW_ST_VIRTUAL
  1987. // || dwScrollTypeV == __ESIW_ST_VIRTUAL
  1988. // )
  1989. OnSwDoScrollBy( CSize(0,0), false );
  1990. OnSwRecalcLayout( true );
  1991. bool bHasSbH1 = OnSwHasScrollBar( true );
  1992. bool bHasSbV1 = OnSwHasScrollBar( false );
  1993. if( bHasSbH0 != bHasSbH1
  1994. || bHasSbV0 != bHasSbV1
  1995. // || dwScrollTypeH == __ESIW_ST_VIRTUAL
  1996. // || dwScrollTypeV == __ESIW_ST_VIRTUAL
  1997. )
  1998. OnSwUpdateScrollBars();
  1999. else
  2000. {
  2001. if( ( bHasSbH1 && GetScrollBarCtrl( SB_HORZ )->GetSafeHwnd() == NULL )
  2002. || ( bHasSbV1 && GetScrollBarCtrl( SB_VERT )->GetSafeHwnd() == NULL )
  2003. )
  2004. SendMessage( WM_NCPAINT );
  2005. }
  2006. m_nUpdateScrollBars --;
  2007. }
  2008. bool CExtScrollItemWnd::SiwAutohideScrollBarGet( bool bHorz ) const
  2009. {
  2010. ASSERT_VALID( this );
  2011. if( bHorz )
  2012. {
  2013. if( ( SiwGetStyle() & __ESIS_DISABLE_AUTOHIDE_SB_H ) != 0 )
  2014. return false;
  2015. } // if( bHorz )
  2016. else
  2017. {
  2018. if( ( SiwGetStyle() & __ESIS_DISABLE_AUTOHIDE_SB_V ) != 0 )
  2019. return false;
  2020. } // else from if( bHorz )
  2021. return true;
  2022. }
  2023. bool CExtScrollItemWnd::SiwAutohideScrollBarSet(
  2024. bool bHorz,
  2025. bool bAutoHide // = true
  2026. )
  2027. {
  2028. ASSERT_VALID( this );
  2029. bool bAutohideScrollBarOld = SiwThumbTrackEnabledGet( bHorz );
  2030. if( (bAutohideScrollBarOld && bAutoHide)
  2031. || ((!bAutohideScrollBarOld) && (!bAutoHide))
  2032. )
  2033. return bAutohideScrollBarOld;
  2034. DWORD dwRemove = bHorz ? __ESIS_DISABLE_AUTOHIDE_SB_H : __ESIS_DISABLE_AUTOHIDE_SB_V;
  2035. DWORD dwAdd = bAutoHide ? 0L : dwRemove;
  2036. SiwModifyStyle( dwAdd, dwRemove, false );
  2037. return bAutohideScrollBarOld;
  2038. }
  2039. bool CExtScrollItemWnd::SiwThumbTrackEnabledGet( bool bHorz ) const
  2040. {
  2041. ASSERT_VALID( this );
  2042. if( bHorz )
  2043. {
  2044. if( ( SiwGetStyle() & __ESIS_DISABLE_THUMBTRACK_H ) != 0 )
  2045. return false;
  2046. } // if( bHorz )
  2047. else
  2048. {
  2049. if( ( SiwGetStyle() & __ESIS_DISABLE_THUMBTRACK_V ) != 0 )
  2050. return false;
  2051. } // else from if( bHorz )
  2052. return true;
  2053. }
  2054. bool CExtScrollItemWnd::SiwThumbTrackEnabledSet(
  2055. bool bHorz,
  2056. bool bEnabled // = true
  2057. )
  2058. {
  2059. ASSERT_VALID( this );
  2060. bool bThumbTrackEnabledOld = SiwThumbTrackEnabledGet( bHorz );
  2061. if( (bThumbTrackEnabledOld && bEnabled)
  2062. || ((!bThumbTrackEnabledOld) && (!bEnabled))
  2063. )
  2064. return bThumbTrackEnabledOld;
  2065. DWORD dwRemove = bHorz ? __ESIS_DISABLE_THUMBTRACK_H : __ESIS_DISABLE_THUMBTRACK_V;
  2066. DWORD dwAdd = bEnabled ? 0L : dwRemove;
  2067. SiwModifyStyle( dwAdd, dwRemove, false );
  2068. return bThumbTrackEnabledOld;
  2069. }
  2070. bool CExtScrollItemWnd::OnSwQueryThumbTrackEnabled( bool bHorz ) const
  2071. {
  2072. ASSERT_VALID( this );
  2073. if( ! SiwThumbTrackEnabledGet( bHorz ) )
  2074. return false;
  2075. DWORD dwScrollType = bHorz
  2076. ? SiwScrollTypeHGet()
  2077. : SiwScrollTypeVGet()
  2078. ;
  2079. if( dwScrollType == __ESIW_ST_VIRTUAL )
  2080. {
  2081. CScrollBar * pScrollBar =
  2082. GetScrollBarCtrl(
  2083. bHorz
  2084. ? SB_HORZ
  2085. : SB_VERT
  2086. );
  2087. if( pScrollBar->GetSafeHwnd() != NULL )
  2088. {
  2089. CExtScrollBar * pExtScrollBar =
  2090. DYNAMIC_DOWNCAST(
  2091. CExtScrollBar,
  2092. pScrollBar
  2093. );
  2094. if( pExtScrollBar != NULL
  2095. && pExtScrollBar->m_bCompleteRepaint
  2096. )
  2097. return true;
  2098. } // if( pScrollBar->GetSafeHwnd() != NULL )
  2099. return false;
  2100. } // if( dwScrollType == __ESIW_ST_VIRTUAL )
  2101. return true;
  2102. }
  2103. CSize CExtScrollItemWnd::OnSwGetTotalSize() const
  2104. {
  2105. ASSERT_VALID( this );
  2106. CSize _sizeTotalISR( 0, 0 );
  2107. DWORD dwScrollTypeH = SiwScrollTypeHGet();
  2108. DWORD dwScrollTypeV = SiwScrollTypeVGet();
  2109. if( dwScrollTypeH == __ESIW_ST_VIRTUAL )
  2110. _sizeTotalISR.cx = __EXT_SCROLL_NUMERIC_MAX;
  2111. if( dwScrollTypeV == __ESIW_ST_VIRTUAL )
  2112. _sizeTotalISR.cy = __EXT_SCROLL_NUMERIC_MAX;
  2113. return _sizeTotalISR;
  2114. }
  2115. CSize CExtScrollItemWnd::OnSwGetPageSize( int nDirection ) const
  2116. {
  2117. ASSERT_VALID( this );
  2118. CRect rcClient = OnSwGetClientRect();
  2119. if( rcClient.right < rcClient.left )
  2120. rcClient.right = rcClient.left;
  2121. if( rcClient.bottom < rcClient.top )
  2122. rcClient.bottom = rcClient.top;
  2123. CSize _sizeClient = rcClient.Size();
  2124. CSize _sizePage = OnSiwCalcPageMetrics( nDirection );
  2125. DWORD dwScrollTypeH = SiwScrollTypeHGet();
  2126. DWORD dwScrollTypeV = SiwScrollTypeVGet();
  2127. if( dwScrollTypeH == __ESIW_ST_NONE )
  2128. _sizePage.cx = 0;
  2129. else if( dwScrollTypeH == __ESIW_ST_PIXEL )
  2130. _sizePage.cx = _sizeClient.cx;
  2131. else if( dwScrollTypeH == __ESIW_ST_ITEM )
  2132. {
  2133. } // else if( dwScrollTypeH == __ESIW_ST_ITEM )
  2134. else
  2135. { // if __ESIW_ST_VIRTUAL
  2136. ASSERT( dwScrollTypeH == __ESIW_ST_VIRTUAL );
  2137. } // if __ESIW_ST_VIRTUAL
  2138. if( dwScrollTypeV == __ESIW_ST_NONE )
  2139. _sizePage.cy = 0;
  2140. else if( dwScrollTypeV == __ESIW_ST_PIXEL )
  2141. _sizePage.cy = _sizeClient.cy;
  2142. else if( dwScrollTypeV == __ESIW_ST_ITEM )
  2143. {
  2144. } // else if( dwScrollTypeV == __ESIW_ST_ITEM )
  2145. else
  2146. { // if __ESIW_ST_VIRTUAL
  2147. ASSERT( dwScrollTypeV == __ESIW_ST_VIRTUAL );
  2148. } // if __ESIW_ST_VIRTUAL
  2149. return _sizePage;
  2150. }
  2151. CSize CExtScrollItemWnd::OnSiwCalcItemSize() const
  2152. {
  2153. ASSERT_VALID( this );
  2154. return CSize( 0, 0 );
  2155. }
  2156. CSize CExtScrollItemWnd::OnSiwCalcPageMetrics( int nDirection ) const
  2157. {
  2158. ASSERT_VALID( this );
  2159. nDirection;
  2160. CSize _sizeItem = OnSiwCalcItemSize();
  2161. ASSERT( _sizeItem.cx >= 0 && _sizeItem.cy >= 0 );
  2162. CRect rcClient = OnSwGetClientRect();
  2163. CSize _sizeClient = rcClient.Size();
  2164. if( _sizeClient.cx < 0 )
  2165. _sizeClient.cx = 0;
  2166. if( _sizeClient.cy < 0 )
  2167. _sizeClient.cy = 0;
  2168. CSize _sizePageMetrics(
  2169. ( _sizeItem.cx == 0 ) ? 0 : ( _sizeClient.cx / _sizeItem.cx ),
  2170. ( _sizeItem.cy == 0 ) ? 0 : ( _sizeClient.cy / _sizeItem.cy )
  2171. );
  2172. if( _sizeItem.cx != 0 )
  2173. {
  2174. if( _sizePageMetrics.cx == 0 )
  2175. _sizePageMetrics.cx = 1;
  2176. }
  2177. else
  2178. _sizePageMetrics.cx = 0;
  2179. if( _sizeItem.cy != 0 )
  2180. {
  2181. if( _sizePageMetrics.cy == 0 )
  2182. _sizePageMetrics.cy = 1;
  2183. }
  2184. else
  2185. _sizePageMetrics.cy = 0;
  2186. return _sizePageMetrics;
  2187. }
  2188. bool CExtScrollItemWnd::OnSiwQueryVirtualBOF( bool bHorz ) const
  2189. {
  2190. ASSERT_VALID( this );
  2191. if( bHorz )
  2192. {
  2193. DWORD dwScrollTypeH = SiwScrollTypeHGet();
  2194. if( dwScrollTypeH != __ESIW_ST_VIRTUAL )
  2195. return true;
  2196. } // if( bHorz )
  2197. else
  2198. {
  2199. DWORD dwScrollTypeV = SiwScrollTypeVGet();
  2200. if( dwScrollTypeV != __ESIW_ST_VIRTUAL )
  2201. return true;
  2202. } // else from if( bHorz )
  2203. return false;
  2204. }
  2205. bool CExtScrollItemWnd::OnSiwQueryVirtualEOF( bool bHorz ) const
  2206. {
  2207. ASSERT_VALID( this );
  2208. if( bHorz )
  2209. {
  2210. DWORD dwScrollTypeH = SiwScrollTypeHGet();
  2211. if( dwScrollTypeH != __ESIW_ST_VIRTUAL )
  2212. return true;
  2213. } // if( bHorz )
  2214. else
  2215. {
  2216. DWORD dwScrollTypeV = SiwScrollTypeVGet();
  2217. if( dwScrollTypeV != __ESIW_ST_VIRTUAL )
  2218. return true;
  2219. } // else from if( bHorz )
  2220. return false;
  2221. }
  2222. INT CExtScrollItemWnd::OnSiwQueryItemExtentH(
  2223. LONG nColNo,
  2224. INT * p_nExtraSpaceBefore, // = NULL
  2225. INT * p_nExtraSpaceAfter // = NULL
  2226. ) const
  2227. {
  2228. ASSERT_VALID( this );
  2229. ASSERT( nColNo >= 0 );
  2230. nColNo;
  2231. if( p_nExtraSpaceBefore != NULL )
  2232. (*p_nExtraSpaceBefore) = 0;
  2233. if( p_nExtraSpaceAfter != NULL )
  2234. (*p_nExtraSpaceAfter) = 0;
  2235. return 0;
  2236. }
  2237. INT CExtScrollItemWnd::OnSiwQueryItemExtentV(
  2238. LONG nRowNo,
  2239. INT * p_nExtraSpaceBefore, // = NULL
  2240. INT * p_nExtraSpaceAfter // = NULL
  2241. ) const
  2242. {
  2243. ASSERT_VALID( this );
  2244. ASSERT( nRowNo >= 0 );
  2245. nRowNo;
  2246. if( p_nExtraSpaceBefore != NULL )
  2247. (*p_nExtraSpaceBefore) = 0;
  2248. if( p_nExtraSpaceAfter != NULL )
  2249. (*p_nExtraSpaceAfter) = 0;
  2250. return 0;
  2251. }
  2252. bool CExtScrollItemWnd::OnSiwVirtualEndTestH( LONG nColNo, LPARAM lParam ) const
  2253. {
  2254. ASSERT_VALID( this );
  2255. ASSERT( nColNo >= 0 );
  2256. nColNo;
  2257. lParam;
  2258. return false;
  2259. }
  2260. bool CExtScrollItemWnd::OnSiwVirtualEndTestV( LONG nRowNo, LPARAM lParam ) const
  2261. {
  2262. ASSERT_VALID( this );
  2263. ASSERT( nRowNo >= 0 );
  2264. nRowNo;
  2265. lParam;
  2266. return false;
  2267. }
  2268. bool CExtScrollItemWnd::OnSiwWalkCell(
  2269. CDC & dc,
  2270. LPVOID pQueryData,
  2271. LONG nVisibleColNo,
  2272. LONG nVisibleRowNo,
  2273. LONG nColNo,
  2274. LONG nRowNo,
  2275. const RECT & rcCellExtra,
  2276. const RECT & rcCell,
  2277. const RECT & rcVisibleRange,
  2278. bool & bVirtualRightReached,
  2279. bool & bVirtualBottomReached,
  2280. DWORD dwAreaFlags,
  2281. bool bFocusedControl
  2282. ) const
  2283. {
  2284. ASSERT_VALID( this );
  2285. ASSERT( dc.GetSafeHdc() != NULL || pQueryData != NULL );
  2286. //ASSERT( nVisibleColNo >= 0 );
  2287. //ASSERT( nVisibleRowNo >= 0 );
  2288. ASSERT( nColNo >= 0 );
  2289. ASSERT( nRowNo >= 0 );
  2290. // ASSERT( rcCell.right >= rcCell.left );
  2291. // ASSERT( rcCell.bottom >= rcCell.top );
  2292. ASSERT( rcCellExtra.right >= rcCellExtra.left );
  2293. ASSERT( rcCellExtra.bottom >= rcCellExtra.top );
  2294. ASSERT( rcCellExtra.left <= rcCell.left );
  2295. ASSERT( rcCellExtra.top <= rcCell.top );
  2296. ASSERT( rcCellExtra.right >= rcCell.right );
  2297. ASSERT( rcCellExtra.bottom >= rcCell.bottom );
  2298. dc;
  2299. pQueryData;
  2300. nVisibleColNo;
  2301. nVisibleRowNo;
  2302. nColNo;
  2303. nRowNo;
  2304. rcCellExtra;
  2305. rcCell;
  2306. rcVisibleRange;
  2307. bVirtualRightReached;
  2308. bVirtualBottomReached;
  2309. dwAreaFlags;
  2310. bFocusedControl;
  2311. // if( pQueryData != NULL )
  2312. // return false; // no default hit-testing implementation
  2313. // bVirtualRightReached = OnSiwVirtualEndTestH( nColNo, LPARAM(dwAreaFlags) );
  2314. // if( bVirtualRightReached )
  2315. // return false;
  2316. // bVirtualBottomReached = OnSiwVirtualEndTestV( nRowNo, LPARAM(dwAreaFlags) );
  2317. // if( bVirtualBottomReached )
  2318. // return false;
  2319. // if( rcCell.right == rcCell.left
  2320. // || rcCell.bottom == rcCell.top
  2321. // )
  2322. // return false;
  2323. // if( ! dc.RectVisible( &rcCell ) )
  2324. // return false;
  2325. //COLORREF clrLT = OnSiwGetSysColor( COLOR_3DHIGHLIGHT );
  2326. //COLORREF clrRB = OnSiwGetSysColor( COLOR_3DSHADOW );
  2327. //COLORREF clrFace = OnSiwGetSysColor( COLOR_3DFACE );
  2328. // dc.FillSolidRect( &rcCell, clrFace );
  2329. //CString sCellText;
  2330. // sCellText.Format( _T("%08d-%08d"), nColNo, nRowNo );
  2331. // dc.DrawText(
  2332. // sCellText,
  2333. // (LPRECT)&rcCell,
  2334. // DT_SINGLELINE|DT_CENTER|DT_VCENTER
  2335. // );
  2336. // dc.Draw3dRect( &rcCell, clrLT, clrRB );
  2337. return false;
  2338. }
  2339. bool CExtScrollItemWnd::OnSiwWalkItemsH(
  2340. CDC & dc,
  2341. LPVOID pQueryData,
  2342. const RECT & rcRowExtra,
  2343. const RECT & rcRow,
  2344. LONG nVisibleRowNo,
  2345. LONG nRowNo,
  2346. const RECT & rcVisibleRange,
  2347. bool & bVirtualBottomReached,
  2348. DWORD dwAreaFlags,
  2349. bool bFocusedControl
  2350. ) const
  2351. {
  2352. ASSERT_VALID( this );
  2353. ASSERT( dc.GetSafeHdc() != NULL || pQueryData != NULL );
  2354. //ASSERT( nVisibleRowNo >= 0 );
  2355. ASSERT( nRowNo >= 0 );
  2356. ASSERT( rcRow.right >= rcRow.left );
  2357. ASSERT( rcRow.bottom >= rcRow.top );
  2358. ASSERT( rcRowExtra.right >= rcRowExtra.left );
  2359. ASSERT( rcRowExtra.bottom >= rcRowExtra.top );
  2360. ASSERT( rcRowExtra.left <= rcRow.left );
  2361. ASSERT( rcRowExtra.top <= rcRow.top );
  2362. ASSERT( rcRowExtra.right >= rcRow.right );
  2363. ASSERT( rcRowExtra.bottom >= rcRow.bottom );
  2364. bVirtualBottomReached = OnSiwVirtualEndTestV( nRowNo, LPARAM(dwAreaFlags) );
  2365. if( bVirtualBottomReached )
  2366. return false;
  2367. if( rcRowExtra.right == rcRowExtra.left
  2368. || rcRowExtra.bottom == rcRowExtra.top
  2369. )
  2370. return false;
  2371. if( dc.GetSafeHdc() == NULL )
  2372. return false; // no hit-test like query support
  2373. if( ! dc.RectVisible( &rcRow ) )
  2374. return false;
  2375. CRect rcClient = OnSwGetClientRect();
  2376. LONG nVisibleColNo = 0;
  2377. LONG nColNo = rcVisibleRange.left;
  2378. bool bVirtualRightReached = false;
  2379. CRect rcCellExtra(
  2380. rcClient.left,
  2381. rcRowExtra.top,
  2382. rcClient.left,
  2383. rcRowExtra.bottom
  2384. );
  2385. for( ; nColNo <= rcVisibleRange.right; nColNo++, nVisibleColNo++ )
  2386. {
  2387. INT nExtraSpaceBefore = 0, nExtraSpaceAfter = 0;
  2388. INT nColWidth =
  2389. OnSiwQueryItemExtentH(
  2390. nColNo,
  2391. &nExtraSpaceBefore,
  2392. &nExtraSpaceAfter
  2393. );
  2394. ASSERT( nColWidth >= 0 );
  2395. ASSERT( nExtraSpaceBefore >= 0 );
  2396. ASSERT( nExtraSpaceAfter >= 0 );
  2397. rcCellExtra.right += nColWidth;
  2398. if( rcCellExtra.right < rcClient.left
  2399. || rcCellExtra.left > rcClient.right
  2400. )
  2401. continue;
  2402. CRect rcCell(
  2403. rcCellExtra.left + nExtraSpaceBefore,
  2404. rcRow.top,
  2405. rcCellExtra.right - nExtraSpaceAfter,
  2406. rcRow.bottom
  2407. );
  2408. OnSiwWalkCell(
  2409. dc,
  2410. pQueryData,
  2411. nVisibleColNo,
  2412. nVisibleRowNo,
  2413. nColNo,
  2414. nRowNo,
  2415. rcCellExtra,
  2416. rcCell,
  2417. rcVisibleRange,
  2418. bVirtualRightReached,
  2419. bVirtualBottomReached,
  2420. dwAreaFlags,
  2421. bFocusedControl
  2422. );
  2423. if( bVirtualRightReached || bVirtualBottomReached )
  2424. break;
  2425. rcCellExtra.left = rcCellExtra.right;
  2426. } // for( ; nColNo <= rcVisibleRange.right; nColNo++, nVisibleColNo++ )
  2427. return false;
  2428. }
  2429. bool CExtScrollItemWnd::OnSiwWalkItemsV(
  2430. CDC & dc,
  2431. LPVOID pQueryData,
  2432. const RECT & rcColExtra,
  2433. const RECT & rcCol,
  2434. LONG nVisibleColNo,
  2435. LONG nColNo,
  2436. const RECT & rcVisibleRange,
  2437. bool & bVirtualRightReached,
  2438. DWORD dwAreaFlags,
  2439. bool bFocusedControl
  2440. ) const
  2441. {
  2442. ASSERT_VALID( this );
  2443. ASSERT( dc.GetSafeHdc() != NULL || pQueryData != NULL );
  2444. //ASSERT( nVisibleColNo >= 0 );
  2445. ASSERT( nColNo >= 0 );
  2446. ASSERT( rcCol.right >= rcCol.left );
  2447. ASSERT( rcCol.bottom >= rcCol.top );
  2448. ASSERT( rcColExtra.right >= rcColExtra.left );
  2449. ASSERT( rcColExtra.bottom >= rcColExtra.top );
  2450. ASSERT( rcColExtra.left <= rcCol.left );
  2451. ASSERT( rcColExtra.top <= rcCol.top );
  2452. ASSERT( rcColExtra.right >= rcCol.right );
  2453. ASSERT( rcColExtra.bottom >= rcCol.bottom );
  2454. bVirtualRightReached = OnSiwVirtualEndTestH( nColNo, LPARAM(dwAreaFlags) );
  2455. if( bVirtualRightReached )
  2456. return false;
  2457. if( rcColExtra.right == rcColExtra.left
  2458. || rcColExtra.bottom == rcColExtra.top
  2459. )
  2460. return false;
  2461. if( dc.GetSafeHdc() == NULL )
  2462. return false; // no hit-test like query support
  2463. if( ! dc.RectVisible( &rcCol ) )
  2464. return false;
  2465. CRect rcClient = OnSwGetClientRect();
  2466. LONG nVisibleRowNo = 0;
  2467. LONG nRowNo = rcVisibleRange.top;
  2468. bool bVirtualBottomReached = false;
  2469. CRect rcCellExtra(
  2470. rcColExtra.left,
  2471. rcClient.top,
  2472. rcColExtra.right,
  2473. rcClient.top
  2474. );
  2475. for( ; nRowNo <= rcVisibleRange.bottom; nRowNo++, nVisibleRowNo++ )
  2476. {
  2477. INT nExtraSpaceBefore = 0, nExtraSpaceAfter = 0;
  2478. INT nRowHeight =
  2479. OnSiwQueryItemExtentV(
  2480. nRowNo,
  2481. &nExtraSpaceBefore,
  2482. &nExtraSpaceAfter
  2483. );
  2484. ASSERT( nRowHeight >= 0 );
  2485. ASSERT( nExtraSpaceBefore >= 0 );
  2486. ASSERT( nExtraSpaceAfter >= 0 );
  2487. rcCellExtra.bottom += nRowHeight;
  2488. if( rcCellExtra.right < rcClient.left
  2489. || rcCellExtra.left > rcClient.right
  2490. )
  2491. continue;
  2492. CRect rcCell(
  2493. rcCol.left,
  2494. rcCellExtra.top + nExtraSpaceBefore,
  2495. rcCol.right,
  2496. rcCellExtra.bottom - nExtraSpaceAfter
  2497. );
  2498. OnSiwWalkCell(
  2499. dc,
  2500. pQueryData,
  2501. nVisibleColNo,
  2502. nVisibleRowNo,
  2503. nColNo,
  2504. nRowNo,
  2505. rcCellExtra,
  2506. rcCell,
  2507. rcVisibleRange,
  2508. bVirtualRightReached,
  2509. bVirtualBottomReached,
  2510. dwAreaFlags,
  2511. bFocusedControl
  2512. );
  2513. if( bVirtualRightReached || bVirtualBottomReached )
  2514. break;
  2515. rcCellExtra.top = rcCellExtra.bottom;
  2516. } // for( ; nRowNo <= rcVisibleRange.bottom; nRowNo++, nVisibleRowNo++ )
  2517. return false;
  2518. }
  2519. bool CExtScrollItemWnd::OnSiwQueryFocusedControlState() const
  2520. {
  2521. ASSERT_VALID( this );
  2522. if( m_hWnd == NULL || (! ::IsWindow(m_hWnd) ) )
  2523. return false;
  2524. HWND hWndFocus = ::GetFocus();
  2525. if( m_hWnd == hWndFocus
  2526. || ::IsChild( m_hWnd, hWndFocus )
  2527. )
  2528. return true;
  2529. return false;
  2530. }
  2531. void CExtScrollItemWnd::OnSiwDrawFocusRect(
  2532. CDC &dc,
  2533. LPCRECT pRect,
  2534. CObject * pObjSrc, // = NULL
  2535. LPARAM lParam // = 0L
  2536. ) const
  2537. {
  2538. ASSERT_VALID( this );
  2539. ASSERT_VALID( (&dc) );
  2540. ASSERT( dc.GetSafeHdc() != NULL );
  2541. #ifdef _DEBUG
  2542. if( pObjSrc != NULL )
  2543. {
  2544. ASSERT_VALID( pObjSrc );
  2545. }
  2546. #endif // _DEBUG
  2547. pObjSrc;
  2548. lParam;
  2549. COLORREF clrTextOld = 
  2550. dc.SetTextColor( RGB(255,255,255) );
  2551. COLORREF clrBkOld =
  2552. dc.SetBkColor( RGB(0,0,0) );
  2553. dc.DrawFocusRect( pRect );
  2554. dc.SetBkColor( clrBkOld );
  2555. dc.SetTextColor( clrTextOld );
  2556. }
  2557. COLORREF CExtScrollItemWnd::OnSiwGetReadOnlyTextColor() const
  2558. {
  2559. ASSERT_VALID( this );
  2560. // return OnSiwGetSysColor( COLOR_BTNTEXT );
  2561. // return OnSiwGetSysColor( COLOR_3DSHADOW );
  2562. return OnSiwGetSysColor( COLOR_3DSHADOW );
  2563. }
  2564. COLORREF CExtScrollItemWnd::OnSiwGetReadOnlyBackgroundColor() const
  2565. {
  2566. ASSERT_VALID( this );
  2567. // return OnSiwGetSysColor( COLOR_WINDOW );
  2568. // return OnSiwGetSysColor( COLOR_3DFACE );
  2569. return OnSiwGetSysColor( COLOR_WINDOW );
  2570. }
  2571. COLORREF CExtScrollItemWnd::OnSiwGetSysColor( int nIndex ) const
  2572. {
  2573. ASSERT_VALID( this );
  2574. DWORD dwSiwGetStyleEx = SiwGetStyleEx();
  2575. bool bUsedPmColors =
  2576. ( (dwSiwGetStyleEx&__EGWS_EX_PM_COLORS) != 0 )
  2577. ? true : false;
  2578. COLORREF clr = bUsedPmColors
  2579. ? PmBridge_GetPM()->GetColor( nIndex, (CObject*)this )
  2580. : ( ::GetSysColor( nIndex ) )
  2581. ;
  2582. return clr;
  2583. }
  2584. // nLighterOrDarker is related to COLOR_3DFACE brush:
  2585. // -3 - darkest, -2 - darker, -1 - dark,
  2586. // 1 - light, 2 - lighter, 3 - lightest
  2587. CBrush & CExtScrollItemWnd::OnSiwGetLighterOrDarkerBrush( int nLighterOrDarker ) const
  2588. {
  2589. ASSERT_VALID( this );
  2590. DWORD dwSiwGetStyleEx = SiwGetStyleEx();
  2591. bool bUsedPmColors =
  2592. ( (dwSiwGetStyleEx&__EGWS_EX_PM_COLORS) != 0 )
  2593. ? true : false;
  2594. switch( nLighterOrDarker )
  2595. {
  2596. case -3:
  2597. return bUsedPmColors ? PmBridge_GetPM()->m_brushDarkestDefault : PmBridge_GetPM()->m_brushDarkestSystem;
  2598. case -2:
  2599. return bUsedPmColors ? PmBridge_GetPM()->m_brushDarkerDefault : PmBridge_GetPM()->m_brushDarkerSystem;
  2600. case -1:
  2601. return bUsedPmColors ? PmBridge_GetPM()->m_brushDarkDefault : PmBridge_GetPM()->m_brushDarkSystem;
  2602. case 1:
  2603. return bUsedPmColors ? PmBridge_GetPM()->m_brushLightDefault: PmBridge_GetPM()->m_brushLightSystem;
  2604. case 2:
  2605. return bUsedPmColors ? PmBridge_GetPM()->m_brushLighterDefault : PmBridge_GetPM()->m_brushLighterSystem;
  2606. default:
  2607. ASSERT( nLighterOrDarker == 3 );
  2608. return bUsedPmColors ? PmBridge_GetPM()->m_brushLightestDefault : PmBridge_GetPM()->m_brushLightestSystem;
  2609. } // switch( nLighterOrDarker )
  2610. }
  2611. CFont & CExtScrollItemWnd::OnSiwGetDefaultFont() const
  2612. {
  2613. ASSERT_VALID( this );
  2614. CFont * pFont = NULL;
  2615. if( GetSafeHwnd() != NULL )
  2616. pFont = GetFont();
  2617. return ( pFont->GetSafeHandle() != NULL ) ? (*pFont) : PmBridge_GetPM()->m_FontNormal;
  2618. }
  2619. void CExtScrollItemWnd::OnSwPaint( CDC & dc )
  2620. {
  2621. ASSERT_VALID( this );
  2622. ASSERT( dc.GetSafeHdc() != NULL );
  2623. bool bFocusedControl = OnSiwQueryFocusedControlState();
  2624. OnSiwPaintBackground( dc, bFocusedControl );
  2625. OnSiwPaintForeground( dc, bFocusedControl );
  2626. }
  2627. void CExtScrollItemWnd::OnSiwPaintBackground(
  2628. CDC & dc,
  2629. bool bFocusedControl
  2630. ) const
  2631. {
  2632. ASSERT_VALID( this );
  2633. ASSERT( dc.GetSafeHdc() != NULL );
  2634. bFocusedControl;
  2635. CRect rcRealClient;
  2636. CWnd::GetClientRect( &rcRealClient );
  2637. if( ! dc.RectVisible(&rcRealClient) )
  2638. return;
  2639. CRect rcClient = OnSwGetClientRect();
  2640. if( rcClient != rcRealClient )
  2641. {
  2642. COLORREF clrEntire = OnSiwGetSysColor( COLOR_3DFACE );
  2643. dc.FillSolidRect( &rcRealClient, clrEntire );
  2644. } // if( rcClient != rcRealClient )
  2645. if( dc.RectVisible(&rcClient) )
  2646. {
  2647. COLORREF clrWindow = 
  2648. OnSiwGetSysColor( IsWindowEnabled() ? COLOR_WINDOW : COLOR_3DFACE );
  2649. dc.FillSolidRect( &rcClient, clrWindow );
  2650. } // if( dc.RectVisible(&rcClient) )
  2651. }
  2652. void CExtScrollItemWnd::OnSiwPaintForeground(
  2653. CDC & dc,
  2654. bool bFocusedControl
  2655. ) const
  2656. {
  2657. ASSERT_VALID( this );
  2658. ASSERT( dc.GetSafeHdc() != NULL );
  2659. CRect rcClient = OnSwGetClientRect();
  2660. if( ! dc.RectVisible(&rcClient) )
  2661. return;
  2662. CRect rcVisibleRange = OnSiwGetVisibleRange();
  2663. ASSERT( rcVisibleRange.left <= rcVisibleRange.right );
  2664. ASSERT( rcVisibleRange.top <= rcVisibleRange.bottom );
  2665. CSize _sizeItem = OnSiwCalcItemSize();
  2666. ASSERT( _sizeItem.cx >= 0 && _sizeItem.cy >= 0 );
  2667. if( !( rcVisibleRange.left <= rcVisibleRange.right
  2668. && rcVisibleRange.top <= rcVisibleRange.bottom
  2669. && _sizeItem.cx > 0
  2670. && _sizeItem.cy > 0
  2671. )
  2672. )
  2673. return;
  2674. DWORD dwScrollTypeH = SiwScrollTypeHGet();
  2675. DWORD dwScrollTypeV = SiwScrollTypeVGet();
  2676. if( ( dwScrollTypeH == __ESIW_ST_NONE
  2677. || dwScrollTypeH == __ESIW_ST_PIXEL
  2678. )
  2679. && ( dwScrollTypeV == __ESIW_ST_NONE
  2680. || dwScrollTypeV == __ESIW_ST_PIXEL
  2681. )
  2682. )
  2683. return;
  2684. bool bPreferHorizontalWalk = SiwPreferHorizontalWalkGet();
  2685. if( bPreferHorizontalWalk )
  2686. {
  2687. if( dwScrollTypeH == __ESIW_ST_NONE
  2688. || dwScrollTypeH == __ESIW_ST_PIXEL
  2689. )
  2690. bPreferHorizontalWalk = false;
  2691. } // if( bPreferHorizontalWalk )
  2692. else
  2693. {
  2694. if( dwScrollTypeV == __ESIW_ST_NONE
  2695. || dwScrollTypeV == __ESIW_ST_PIXEL
  2696. )
  2697. bPreferHorizontalWalk = true;
  2698. } // else from if( bPreferHorizontalWalk )
  2699. CRgn rgnClientClip;
  2700. if( rgnClientClip.CreateRectRgnIndirect(&rcClient) )
  2701. dc.SelectClipRgn( &rgnClientClip );
  2702. COLORREF clrText = OnSiwGetSysColor( COLOR_BTNTEXT );
  2703. int nOldBkMode = dc.SetBkMode( TRANSPARENT );
  2704. COLORREF clrTextOld = dc.SetTextColor( clrText );
  2705. CFont * pOldFont = dc.SelectObject( &( OnSiwGetDefaultFont() ) );
  2706. if( bPreferHorizontalWalk )
  2707. {
  2708. LONG nColNo = rcVisibleRange.left;
  2709. LONG nVisibleColNo = 0;
  2710. bool bVirtualRightReached = false;
  2711. CRect rcColExtra(
  2712. rcClient.left,
  2713. rcClient.top,
  2714. rcClient.left,
  2715. rcClient.bottom
  2716. );
  2717. for( ; nColNo <= rcVisibleRange.right; nColNo ++, nVisibleColNo++ )
  2718. {
  2719. INT nExtraSpaceBefore = 0, nExtraSpaceAfter = 0;
  2720. INT nColWidth =
  2721. OnSiwQueryItemExtentH(
  2722. nColNo,
  2723. &nExtraSpaceBefore,
  2724. &nExtraSpaceAfter
  2725. );
  2726. ASSERT( nColWidth >= 0 );
  2727. ASSERT( nExtraSpaceBefore >= 0 );
  2728. ASSERT( nExtraSpaceAfter >= 0 );
  2729. if( nColWidth == 0 )
  2730. continue;
  2731. rcColExtra.right += nColWidth;
  2732. CRect rcCol( rcColExtra );
  2733. rcCol.DeflateRect(
  2734. nExtraSpaceBefore,
  2735. 0,
  2736. nExtraSpaceAfter,
  2737. 0
  2738. );
  2739. ASSERT( rcCol.left <= rcCol.right );
  2740. OnSiwWalkItemsV(
  2741. dc,
  2742. NULL,
  2743. rcColExtra,
  2744. rcCol,
  2745. nVisibleColNo,
  2746. nColNo,
  2747. rcVisibleRange,
  2748. bVirtualRightReached,
  2749. 0L,
  2750. bFocusedControl
  2751. );
  2752. if( bVirtualRightReached )
  2753. break;
  2754. rcColExtra.left = rcColExtra.right;
  2755. }
  2756. } // if( bPreferHorizontalWalk )
  2757. else
  2758. {
  2759. LONG nRowNo = rcVisibleRange.top;
  2760. LONG nVisibleRowNo = 0;
  2761. bool bVirtualBottomReached = false;
  2762. CRect rcRowExtra(
  2763. rcClient.left,
  2764. rcClient.top,
  2765. rcClient.right,
  2766. rcClient.top
  2767. );
  2768. for( ; nRowNo <= rcVisibleRange.bottom; nRowNo ++, nVisibleRowNo++ )
  2769. {
  2770. INT nExtraSpaceBefore = 0, nExtraSpaceAfter = 0;
  2771. INT nRowHeight =
  2772. OnSiwQueryItemExtentV(
  2773. nRowNo,
  2774. &nExtraSpaceBefore,
  2775. &nExtraSpaceAfter
  2776. );
  2777. ASSERT( nRowHeight >= 0 );
  2778. ASSERT( nExtraSpaceBefore >= 0 );
  2779. ASSERT( nExtraSpaceAfter >= 0 );
  2780. if( nRowHeight == 0 )
  2781. continue;
  2782. rcRowExtra.bottom += nRowHeight;
  2783. CRect rcRow( rcRowExtra );
  2784. rcRow.DeflateRect(
  2785. 0,
  2786. nExtraSpaceBefore,
  2787. 0,
  2788. nExtraSpaceAfter
  2789. );
  2790. ASSERT( rcRow.top <= rcRow.bottom );
  2791. OnSiwWalkItemsH(
  2792. dc,
  2793. NULL,
  2794. rcRowExtra,
  2795. rcRow,
  2796. nVisibleRowNo,
  2797. nRowNo,
  2798. rcVisibleRange,
  2799. bVirtualBottomReached,
  2800. 0L,
  2801. bFocusedControl
  2802. );
  2803. if( bVirtualBottomReached )
  2804. break;
  2805. rcRowExtra.top = rcRowExtra.bottom;
  2806. }
  2807. } // else from if( bPreferHorizontalWalk )
  2808. dc.SelectObject( pOldFont );
  2809. dc.SetTextColor( clrTextOld );
  2810. dc.SetBkMode( nOldBkMode );
  2811. dc.SelectClipRgn( NULL );
  2812. }
  2813. bool CExtScrollItemWnd::OnSwDoScroll(
  2814. UINT nScrollCode,
  2815. UINT nPos,
  2816. bool bDoScroll // = true
  2817. )
  2818. {
  2819. ASSERT_VALID( this );
  2820. DWORD dwScrollTypeH = SiwScrollTypeHGet();
  2821. DWORD dwScrollTypeV = SiwScrollTypeVGet();
  2822. LONG xPos, xOrgValue, yPos, yOrgValue;
  2823. xOrgValue = xPos = ScrollPos32Get( SB_HORZ );
  2824. switch( LOBYTE(nScrollCode) )
  2825. {
  2826. case SB_ENDSCROLL: break;
  2827. case SB_TOP: xPos  = 0; break;
  2828. case SB_BOTTOM: xPos  = __EXT_SCROLL_NUMERIC_MAX; break;
  2829. case SB_LINEUP: xPos -= OnSwGetLineSize( -1 ).cx; break;
  2830. case SB_LINEDOWN: xPos += OnSwGetLineSize(  1 ).cx; break;
  2831. case SB_PAGEUP: xPos -= OnSwGetPageSize( -1 ).cx; break;
  2832. case SB_PAGEDOWN:
  2833. {
  2834. LONG nPageSize = OnSwGetPageSize( 1 ).cx;
  2835. if( dwScrollTypeH != __ESIW_ST_VIRTUAL )
  2836. {
  2837. CExtScrollBar * pExtSB = DYNAMIC_DOWNCAST( CExtScrollBar, GetScrollBarCtrl(SB_HORZ) );
  2838. if( pExtSB->GetSafeHwnd() != NULL
  2839. && ::GetCapture() == pExtSB->m_hWnd
  2840. )
  2841. xPos = ScrollPos32Get( SB_HORZ, true );
  2842. xPos += nPageSize;
  2843. }
  2844. else
  2845. {
  2846. if( (__EXT_SCROLL_NUMERIC_MAX - nPageSize) < xPos )
  2847. xPos = __EXT_SCROLL_NUMERIC_MAX;
  2848. else
  2849. xPos += nPageSize;
  2850. } // else from if( dwScrollTypeH != __ESIW_ST_VIRTUAL )
  2851. }
  2852. break;
  2853. case SB_THUMBTRACK:
  2854. if( ! OnSwQueryThumbTrackEnabled(true) )
  2855. return false;
  2856. case SB_THUMBPOSITION:
  2857. if( dwScrollTypeH != __ESIW_ST_VIRTUAL )
  2858. {
  2859. if( m_bUse32BitScrollInfo )
  2860. nPos = ScrollPos32Get( SB_HORZ, true );
  2861. xPos = nPos;
  2862. } // if( dwScrollTypeH != __ESIW_ST_VIRTUAL )
  2863. else
  2864. {
  2865. if( nPos <= 0 )
  2866. xPos = 0;
  2867. else
  2868. xPos = __EXT_SCROLL_NUMERIC_MAX;
  2869. } // else from if( dwScrollTypeH != __ESIW_ST_VIRTUAL )
  2870. break;
  2871. }
  2872. yOrgValue = yPos = ScrollPos32Get( SB_VERT );
  2873. switch( HIBYTE(nScrollCode) )
  2874. {
  2875. case SB_ENDSCROLL: break;
  2876. case SB_TOP: yPos  = 0; break;
  2877. case SB_BOTTOM: yPos  = __EXT_SCROLL_NUMERIC_MAX; break;
  2878. case SB_LINEUP: yPos -= OnSwGetLineSize( -1 ).cy; break;
  2879. case SB_LINEDOWN: yPos += OnSwGetLineSize(  1 ).cy; break;
  2880. case SB_PAGEUP: yPos -= OnSwGetPageSize( -1 ).cy; break;
  2881. case SB_PAGEDOWN:
  2882. {
  2883. LONG nPageSize = OnSwGetPageSize( 1 ).cy;
  2884. if( dwScrollTypeV != __ESIW_ST_VIRTUAL )
  2885. {
  2886. CExtScrollBar * pExtSB = DYNAMIC_DOWNCAST( CExtScrollBar, GetScrollBarCtrl(SB_VERT) );
  2887. if( pExtSB->GetSafeHwnd() != NULL
  2888. && ::GetCapture() == pExtSB->m_hWnd
  2889. )
  2890. yPos = ScrollPos32Get( SB_VERT, true );
  2891. yPos += nPageSize;
  2892. }
  2893. else
  2894. {
  2895. if( (__EXT_SCROLL_NUMERIC_MAX - nPageSize) < yPos )
  2896. yPos = __EXT_SCROLL_NUMERIC_MAX;
  2897. else
  2898. yPos += nPageSize;
  2899. } // else from if( dwScrollTypeV != __ESIW_ST_VIRTUAL )
  2900. }
  2901. break;
  2902. case SB_THUMBTRACK:
  2903. if( ! OnSwQueryThumbTrackEnabled(false) )
  2904. return false;
  2905. case SB_THUMBPOSITION:
  2906. if( dwScrollTypeV != __ESIW_ST_VIRTUAL )
  2907. {
  2908. if( m_bUse32BitScrollInfo )
  2909. nPos = ScrollPos32Get( SB_VERT, true );
  2910. yPos = (int)nPos;
  2911. } // if( dwScrollTypeV != __ESIW_ST_VIRTUAL )
  2912. else
  2913. {
  2914. if( nPos <= 0 )
  2915. yPos = 0;
  2916. else
  2917. yPos = __EXT_SCROLL_NUMERIC_MAX;
  2918. } // else from if( dwScrollTypeV != __ESIW_ST_VIRTUAL )
  2919. break;
  2920. }
  2921. bool bResult = OnSwDoScrollBy( CSize( xPos - xOrgValue, yPos - yOrgValue ), bDoScroll );
  2922. if( bResult && bDoScroll && m_bScrollUpdateWindow )
  2923. OnSwUpdateWindow();
  2924. return bResult;
  2925. }
  2926. bool CExtScrollItemWnd::SiwFireCacheChanging(
  2927. LONG nScrollPosNewX, // = -1L // if <0L - use current
  2928. LONG nScrollPosNewY, // = -1L // if <0L - use current
  2929. bool bUpdate // = true
  2930. )
  2931. {
  2932. ASSERT_VALID( this );
  2933. LONG xMaxValue = 0L, xPos = 0L, xPosOld = 0L,
  2934. yMaxValue = 0L, yPos = 0L, yPosOld = 0L;
  2935. if( bUpdate || OnSwHasScrollBar(true) )
  2936. {
  2937. xPos = ScrollPos32Get( SB_HORZ );
  2938. xMaxValue = ScrollLimit32Get( SB_HORZ );
  2939. if( nScrollPosNewX >= 0L )
  2940. {
  2941. xPosOld = xPos;
  2942. xPos = nScrollPosNewX;
  2943. } // if( nScrollPosNewX >= 0L )
  2944. if( xPos < 0 )
  2945. xPos = 0;
  2946. else if( xPos > xMaxValue )
  2947. xPos = xMaxValue;
  2948. if( bUpdate && xPos != xPosOld  )
  2949. ScrollPos32Set( SB_HORZ, xPos, false );
  2950. } // if( bUpdate || OnSwHasScrollBar(true) )
  2951. if( bUpdate || OnSwHasScrollBar(false) )
  2952. {
  2953. yPos = ScrollPos32Get( SB_VERT );
  2954. yMaxValue = ScrollLimit32Get( SB_VERT );
  2955. if( nScrollPosNewY >= 0L )
  2956. {
  2957. yPosOld = yPos;
  2958. yPos = nScrollPosNewY;
  2959. } // if( nScrollPosNewY >= 0L )
  2960. if( yPos < 0 )
  2961. yPos = 0;
  2962. else if( yPos > yMaxValue )
  2963. yPos = yMaxValue;
  2964. if( bUpdate && yPos != yPosOld  )
  2965. ScrollPos32Set( SB_VERT, yPos, false );
  2966. } // if( bUpdate || OnSwHasScrollBar(false) )
  2967. bool bBeginX = ( (xPos == 0) ? true : false ),
  2968. bBeginY = ( (yPos == 0) ? true : false ),
  2969. bEndX = ( (xPos == xMaxValue && xMaxValue > 0) ? true : false ),
  2970. bEndY = ( (yPos == yMaxValue && yMaxValue > 0) ? true : false );
  2971. CSize _sizePage = OnSwGetPageSize( 0 );
  2972. if( _sizePage.cx < 0 )
  2973. _sizePage.cx = 0;
  2974. if( _sizePage.cy < 0 )
  2975. _sizePage.cy = 0;
  2976. m_sciLast.Empty();
  2977. bool bRetVal =
  2978. _NotifyCacheChanged(
  2979. xPos, xPosOld, xMaxValue, _sizePage.cx,
  2980. yPos, yPosOld, yMaxValue, _sizePage.cy,
  2981. bBeginX, bEndX,
  2982. bBeginY, bEndY
  2983. );
  2984. if( bUpdate )
  2985. {
  2986. OnSwUpdateScrollBars();
  2987. OnSwDoRedraw();
  2988. } // if( bUpdate )
  2989. return bRetVal;
  2990. }
  2991. bool CExtScrollItemWnd::OnSwDoScrollBy(
  2992. CSize sizeScroll,
  2993. bool bDoScroll // = true
  2994. )
  2995. {
  2996. ASSERT_VALID( this );
  2997. LONG xMaxValue, xOrgValue, xPos, yMaxValue, yOrgValue, yPos;
  2998. if( ! OnSwHasScrollBar(false) )
  2999. sizeScroll.cy = 0;
  3000. if( ! OnSwHasScrollBar(true) )
  3001. sizeScroll.cx = 0;
  3002. xOrgValue = xPos = ScrollPos32Get( SB_HORZ );
  3003. xMaxValue = ScrollLimit32Get( SB_HORZ );
  3004. xPos += sizeScroll.cx;
  3005. if( xPos < 0 )
  3006. xPos = 0;
  3007. else if( xPos > xMaxValue )
  3008. xPos = xMaxValue;
  3009. yOrgValue = yPos = ScrollPos32Get( SB_VERT );
  3010. yMaxValue = ScrollLimit32Get( SB_VERT );
  3011. yPos += sizeScroll.cy;
  3012. if( yPos < 0 )
  3013. yPos = 0;
  3014. else if( yPos > yMaxValue )
  3015. yPos = yMaxValue;
  3016. bool bBeginX = ( (xPos == 0) ? true : false ),
  3017. bBeginY = ( (yPos == 0) ? true : false ),
  3018. bEndX = ( (xPos == xMaxValue && xMaxValue > 0) ? true : false ),
  3019. bEndY = ( (yPos == yMaxValue && yMaxValue > 0) ? true : false );
  3020. CSize _sizePage = OnSwGetPageSize( 0 );
  3021. bool bRetVal =
  3022. _NotifyCacheChanged(
  3023. xPos, xOrgValue, xMaxValue, _sizePage.cx,
  3024. yPos, yOrgValue, yMaxValue, _sizePage.cy,
  3025. bBeginX, bEndX,
  3026. bBeginY, bEndY
  3027. );
  3028. if( !bRetVal )
  3029. return false;
  3030. if( xPos == xOrgValue
  3031. && yPos == yOrgValue
  3032. )
  3033. return true; //false;
  3034. if( bDoScroll )
  3035. {
  3036. CSize sizeItem = OnSiwCalcItemSize();
  3037. int xAmount = xOrgValue - xPos;
  3038. int yAmount = yOrgValue - yPos;
  3039. xAmount *= sizeItem.cx;
  3040. yAmount *= sizeItem.cy;
  3041. OnSwDoScrollWindow( xAmount, yAmount );
  3042. if( xPos != xOrgValue )
  3043. ScrollPos32Set( SB_HORZ, xPos );
  3044. if( yPos != yOrgValue )
  3045. ScrollPos32Set( SB_VERT, yPos );
  3046. } // if( bDoScroll )
  3047. return true;
  3048. }
  3049. CPoint CExtScrollItemWnd::OnSwGetScrollPaintPos() const
  3050. {
  3051. ASSERT_VALID( this );
  3052. return CPoint( 0, 0 );
  3053. }
  3054. CRect CExtScrollItemWnd::OnSiwGetFrozenRange() const
  3055. {
  3056. ASSERT_VALID( this );
  3057. return CRect( 0, 0, 0, 0 );
  3058. }
  3059. CRect CExtScrollItemWnd::OnSiwGetVisibleRange() const
  3060. {
  3061. ASSERT_VALID( this );
  3062. CRect rcFrozenRange = OnSiwGetFrozenRange();
  3063. ASSERT(
  3064. rcFrozenRange.top    >= 0
  3065. && rcFrozenRange.bottom >= 0
  3066. && rcFrozenRange.left   >= 0
  3067. && rcFrozenRange.right  >= 0
  3068. );
  3069. DWORD dwScrollTypeH = SiwScrollTypeHGet();
  3070. DWORD dwScrollTypeV = SiwScrollTypeVGet();
  3071. CSize _sizeTotal = OnSwGetTotalSize();
  3072. CSize _sizePage = OnSiwCalcPageMetrics( 0 );
  3073. CSize _sizeRange(
  3074. (dwScrollTypeH == __ESIW_ST_NONE) ? _sizeTotal.cx : ( min( _sizeTotal.cx, _sizePage.cx ) ),
  3075. (dwScrollTypeV == __ESIW_ST_NONE) ? _sizeTotal.cy : ( min( _sizeTotal.cy, _sizePage.cy ) )
  3076. );
  3077. CPoint ptMove = OnSwGetScrollPos();
  3078. CRect rcVisibleRange( ptMove, _sizeRange );
  3079. if( ((ULONG)rcVisibleRange.right) >= ((ULONG)_sizeTotal.cx)
  3080. && dwScrollTypeH != __ESIW_ST_NONE
  3081. && dwScrollTypeH != __ESIW_ST_VIRTUAL
  3082. )
  3083. rcVisibleRange.right = _sizeTotal.cx-1;
  3084. if( ((ULONG)rcVisibleRange.right) < ((ULONG)rcVisibleRange.left) )
  3085. rcVisibleRange.right = rcVisibleRange.left;
  3086. if( ((ULONG)rcVisibleRange.bottom) >= ((ULONG)_sizeTotal.cy)
  3087. && dwScrollTypeV != __ESIW_ST_NONE
  3088. && dwScrollTypeV != __ESIW_ST_VIRTUAL
  3089. )
  3090. rcVisibleRange.bottom = _sizeTotal.cy-1;
  3091. if( ((ULONG)rcVisibleRange.bottom) < ((ULONG)rcVisibleRange.top) )
  3092. rcVisibleRange.bottom = rcVisibleRange.top;
  3093. if( dwScrollTypeH == __ESIW_ST_VIRTUAL )
  3094. rcVisibleRange.OffsetRect( -rcVisibleRange.left, 0 );
  3095. if( dwScrollTypeV == __ESIW_ST_VIRTUAL )
  3096. rcVisibleRange.OffsetRect( 0, -rcVisibleRange.top );
  3097. rcVisibleRange.OffsetRect( rcFrozenRange.left, rcFrozenRange.top );
  3098. return rcVisibleRange;
  3099. }
  3100. void CExtScrollItemWnd::OnSwGetScrollBarState(
  3101. CSize sizeClient,
  3102. CSize & sizeNeedSB,
  3103. CSize & sizeRange,
  3104. CPoint & ptMove,
  3105. bool bInsideClient
  3106. ) const
  3107. {
  3108. ASSERT_VALID( this );
  3109. DWORD dwScrollTypeH = SiwScrollTypeHGet();
  3110. DWORD dwScrollTypeV = SiwScrollTypeVGet();
  3111. bool bHasSbH0 = OnSwHasScrollBar( true );
  3112. bool bHasSbV0 = OnSwHasScrollBar( false );
  3113. CSize sizeSb = OnSwGetScrollBarSizes();
  3114. CSize sizeTotal = OnSwGetTotalSize();
  3115. sizeRange = sizeTotal - sizeClient;
  3116. ptMove = OnSwGetScrollPos();
  3117. bool bNeedH = sizeRange.cx > 0;
  3118. if( !bNeedH )
  3119. ptMove.x = 0;
  3120. else if(
  3121. bInsideClient
  3122. && dwScrollTypeV == __ESIW_ST_PIXEL
  3123. && ( bHasSbH0 )
  3124. )
  3125. sizeRange.cy += sizeSb.cy;
  3126. bool bNeedV = sizeRange.cy > 0;
  3127. if( ! bNeedV )
  3128. ptMove.y = 0;
  3129. else if (
  3130. bInsideClient
  3131. && dwScrollTypeH == __ESIW_ST_PIXEL
  3132. && ( bHasSbV0 )
  3133. )
  3134. sizeRange.cx += sizeSb.cx;
  3135. if( bNeedV
  3136. && (!bNeedH)
  3137. && sizeRange.cx > 0
  3138. )
  3139. {
  3140. ASSERT( bInsideClient );
  3141. bNeedH = true;
  3142. if( dwScrollTypeV == __ESIW_ST_PIXEL )
  3143. {
  3144. sizeRange.cy += sizeSb.cy;
  3145. }
  3146. } // if( bNeedV ...
  3147. if( sizeRange.cx > 0 && ptMove.x >= sizeRange.cx )
  3148. ptMove.x = sizeRange.cx;
  3149. if( sizeRange.cy > 0 && ptMove.y >= sizeRange.cy )
  3150. ptMove.y = sizeRange.cy;
  3151. if( bNeedH || bNeedV )
  3152. {
  3153. CSize sizePage = OnSwGetPageSize( 0 );
  3154. CSize sizePxClient( 0, 0 );
  3155. if( dwScrollTypeH == __ESIW_ST_PIXEL || dwScrollTypeV == __ESIW_ST_PIXEL )
  3156. {
  3157. sizePxClient = OnSwGetClientRect().Size();
  3158. }
  3159. if( bNeedH )
  3160. {
  3161. if( dwScrollTypeH == __ESIW_ST_PIXEL )
  3162. {
  3163. if( OnSwHasScrollBar( true ) )
  3164. sizePxClient.cx += sizeSb.cx;
  3165. sizePage.cx = max( sizePage.cx, sizePxClient.cx );
  3166. }
  3167. if( sizeTotal.cx < sizePage.cx )
  3168. {
  3169. bNeedH = false;
  3170. ptMove.x = 0;
  3171. }
  3172. }
  3173. if( bNeedV )
  3174. {
  3175. if( dwScrollTypeV == __ESIW_ST_PIXEL )
  3176. {
  3177. if( OnSwHasScrollBar( false ) )
  3178. sizePxClient.cy += sizeSb.cy;
  3179. sizePage.cy = max( sizePage.cy, sizePxClient.cy );
  3180. }
  3181. if( sizeTotal.cy < sizePage.cy )
  3182. {
  3183. bNeedV = false;
  3184. ptMove.y = 0;
  3185. }
  3186. }
  3187. }
  3188. sizeNeedSB.cx = bNeedH;
  3189. sizeNeedSB.cy = bNeedV;
  3190. CPoint ptMove_ISR = OnSwGetScrollPos();
  3191. if( dwScrollTypeH == __ESIW_ST_ITEM
  3192. || dwScrollTypeH == __ESIW_ST_VIRTUAL
  3193. )
  3194. ptMove.x = ptMove_ISR.x;
  3195. else if( dwScrollTypeH == __ESIW_ST_NONE )
  3196. sizeNeedSB.cx = 0;
  3197. if( dwScrollTypeV == __ESIW_ST_ITEM
  3198. || dwScrollTypeV == __ESIW_ST_VIRTUAL
  3199. )
  3200. ptMove.y = ptMove_ISR.y;
  3201. else if( dwScrollTypeV == __ESIW_ST_NONE )
  3202. sizeNeedSB.cy = 0;
  3203. }
  3204. bool CExtScrollItemWnd::OnSwCanAutoHideScrollBar( bool bHorz ) const
  3205. {
  3206. ASSERT_VALID( this );
  3207. return SiwAutohideScrollBarGet( bHorz );
  3208. }
  3209. bool CExtScrollItemWnd::_NotifyCacheChanged(
  3210. LONG nPosH,
  3211. LONG nPosOldH,
  3212. LONG nMaxH,
  3213. LONG nPageSizeH,
  3214. LONG nPosV,
  3215. LONG nPosOldV,
  3216. LONG nMaxV,
  3217. LONG nPageSizeV,
  3218. bool bBeginH,
  3219. bool bEndH,
  3220. bool bBeginV,
  3221. bool bEndV
  3222. )
  3223. {
  3224. ASSERT_VALID( this );
  3225. nPosOldH;
  3226. nPosOldV;
  3227. ASSERT(
  3228. nPosH >= 0L
  3229. && nPosOldH >= 0L
  3230. && nPosV >= 0L
  3231. && nPosOldV >= 0L
  3232. && nMaxH >= 0L
  3233. && nMaxV >= 0L
  3234. && nPageSizeH >= 0L
  3235. && nPageSizeV >= 0L
  3236. );
  3237. ASSERT( 0L <= nPosH && nPosH <= nMaxH );
  3238. ASSERT( 0L <= nPosOldH && nPosOldH <= nMaxH );
  3239. ASSERT( 0L <= nPosV && nPosV <= nMaxV );
  3240. ASSERT( 0L <= nPosOldV && nPosOldV <= nMaxV );
  3241. //DWORD dwScrollTypeH = SiwScrollTypeHGet();
  3242. DWORD dwScrollTypeV = SiwScrollTypeVGet();
  3243. if( dwScrollTypeV != __ESIW_ST_NONE
  3244. && dwScrollTypeV != __ESIW_ST_PIXEL
  3245. && OnSwHasScrollBar( false )
  3246. )
  3247. {
  3248. if( nPosV < nMaxV )
  3249. {
  3250. nPageSizeV++;
  3251. }
  3252. }
  3253. CExtScrollItemCacheInfo _sciNew(
  3254. nPosH,
  3255. nMaxH,
  3256. nPageSizeH,
  3257. nPosV,
  3258. nMaxV,
  3259. nPageSizeV,
  3260. bBeginH,
  3261. bEndH,
  3262. bBeginV,
  3263. bEndV
  3264. );
  3265. ASSERT( _sciNew.IsValid() );
  3266. if( m_sciLast == _sciNew )
  3267. return true;
  3268. if( ! OnSiwCacheChanged( _sciNew, m_sciLast ) )
  3269. return false;
  3270. m_sciLast = _sciNew;
  3271. return true;
  3272. }
  3273. bool CExtScrollItemWnd::OnSiwCacheChanged(
  3274. const CExtScrollItemCacheInfo & _sciNew,
  3275. const CExtScrollItemCacheInfo & _sciOld
  3276. )
  3277. {
  3278. ASSERT_VALID( this );
  3279. ASSERT( _sciNew.IsValid() );
  3280. ASSERT( _sciOld.IsValid() );
  3281. _sciNew;
  3282. _sciOld;
  3283. ///////////////////////////////////////////////////////////////////////
  3284. /// DEBUG BLOCK (BEGIN): verify cache notification is valid
  3285. ///////////////////////////////////////////////////////////////////////
  3286. #ifdef _DEBUG
  3287. LONG nPosChangingH = _sciNew.m_nPosH - _sciOld.m_nPosH;
  3288. LONG nPosChangingV = _sciNew.m_nPosV - _sciOld.m_nPosV;
  3289. ASSERT( nPosChangingH == _sciNew.GetPosChangingH(_sciOld) );
  3290. ASSERT( nPosChangingV == _sciNew.GetPosChangingV(_sciOld) );
  3291. LONG nPageSizeChangingH = _sciNew.m_nPageSizeH - _sciOld.m_nPageSizeH;
  3292. LONG nPageSizeChangingV = _sciNew.m_nPageSizeV - _sciOld.m_nPageSizeV;
  3293. ASSERT( nPageSizeChangingH == _sciNew.GetPageSizeChangingH(_sciOld) );
  3294. ASSERT( nPageSizeChangingV == _sciNew.GetPageSizeChangingV(_sciOld) );
  3295. LONG nMaxChangingH = _sciNew.m_nMaxH - _sciOld.m_nMaxH;
  3296. LONG nMaxChangingV = _sciNew.m_nMaxV - _sciOld.m_nMaxV;
  3297. ASSERT( nMaxChangingH == _sciNew.GetMaxChangingH(_sciOld) );
  3298. ASSERT( nMaxChangingV == _sciNew.GetMaxChangingV(_sciOld) );
  3299. LONG nExtentH_New = _sciNew.m_nMaxH + _sciNew.m_nPageSizeH;
  3300. LONG nExtentH_Old = _sciOld.m_nMaxH + _sciOld.m_nPageSizeH;
  3301. LONG nExtentV_New = _sciNew.m_nMaxV + _sciNew.m_nPageSizeV;
  3302. LONG nExtentV_Old = _sciOld.m_nMaxV + _sciOld.m_nPageSizeV;
  3303. LONG nExtentChangingH = nExtentH_New - nExtentH_Old;
  3304. LONG nExtentChangingV = nExtentV_New - nExtentV_Old;
  3305. ASSERT( nExtentChangingH == _sciNew.GetExtentChangingH(_sciOld) );
  3306. ASSERT( nExtentChangingV == _sciNew.GetExtentChangingV(_sciOld) );
  3307. if( nPosChangingH == 0L
  3308. && nPosChangingV == 0L
  3309. && nPageSizeChangingH == 0L
  3310. && nPageSizeChangingV == 0L
  3311. && nMaxChangingH == 0L
  3312. && nMaxChangingV == 0L
  3313. && nExtentChangingH == 0L
  3314. && nExtentChangingV == 0L
  3315. )
  3316. {
  3317. ASSERT( FALSE );
  3318. }
  3319. //CString strTrace;
  3320. // strTrace.Format(
  3321. // _T("   --> CExtScrollItemWnd::OnSiwCacheChanged()n")
  3322. // _T("   -->    nPosNewH=%08ld nMaxH=%08ld PG=%08ld BEGIN=%s END=%sn")
  3323. // _T("   -->    nPosNewV=%08ld nMaxV=%08ld PG=%08ld BEGIN=%s END=%sn")
  3324. // ,
  3325. // _sciNew.m_nPosH, _sciNew.m_nMaxH, _sciNew.m_nPageSizeH,
  3326. // _sciNew.m_bBeginH ? _T("yes") : _T("not"),
  3327. // _sciNew.m_bEndH ? _T("yes") : _T("not"),
  3328. // _sciNew.m_nPosV, _sciNew.m_nMaxV, _sciNew.m_nPageSizeV,
  3329. // _sciNew.m_bBeginV ? _T("yes") : _T("not"),
  3330. // _sciNew.m_bEndV ? _T("yes") : _T("not")
  3331. // );
  3332. // TRACE0( LPCTSTR(strTrace) );
  3333. #endif // _DEBUG
  3334. ///////////////////////////////////////////////////////////////////////
  3335. /// DEBUG BLOCK (END): verify cache notification is valid
  3336. ///////////////////////////////////////////////////////////////////////
  3337. return true;
  3338. }
  3339. #endif // (!defined __EXT_MFC_NO_SCROLLITEMWND)
  3340. #if (!defined __EXT_MFC_NO_SCROLLCONAINERWND)
  3341. /////////////////////////////////////////////////////////////////////////////
  3342. // CExtScrollContainerWnd
  3343. IMPLEMENT_DYNCREATE( CExtScrollContainerWnd, CExtScrollWnd );
  3344. CExtScrollContainerWnd::CExtScrollContainerWnd()
  3345. : m_sizeToScroll( 0, 0 )
  3346. , m_clrBkColor( COLORREF(-1L) )
  3347. , m_bAutoDelete( false )
  3348. , m_bRedirectPreTranslateMessage( false )
  3349. , m_bRedirectOnCmdMsg( false )
  3350. , m_bRedirectFocus( true )
  3351. , m_bSynchronizeEnabledState( false )
  3352. , m_nScrollRedrawFlags( RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE|RDW_ERASENOW|RDW_ALLCHILDREN )
  3353. {
  3354. }
  3355. CExtScrollContainerWnd::~CExtScrollContainerWnd()
  3356. {
  3357. }
  3358. BEGIN_MESSAGE_MAP( CExtScrollContainerWnd, CExtScrollWnd )
  3359. //{{AFX_MSG_MAP(CExtScrollContainerWnd)
  3360. ON_WM_CREATE()
  3361. ON_WM_SETFOCUS()
  3362. ON_WM_ENABLE()
  3363. //}}AFX_MSG_MAP
  3364. END_MESSAGE_MAP()
  3365. BOOL CExtScrollContainerWnd::PreCreateWindow(CREATESTRUCT& cs) 
  3366. {
  3367. if( ! CExtScrollWnd::PreCreateWindow( cs ) )
  3368. return FALSE;
  3369. cs.dwExStyle &= ~(WS_EX_CLIENTEDGE|WS_EX_STATICEDGE);
  3370. cs.dwExStyle |= WS_EX_CONTROLPARENT;
  3371. cs.style &= ~(WS_BORDER);
  3372. cs.style |= WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
  3373. cs.lpszClass = ::AfxRegisterWndClass( CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, ::LoadCursor( NULL, IDC_ARROW ), NULL, NULL );
  3374. return TRUE;
  3375. }
  3376. CPoint CExtScrollContainerWnd::OnSwGetScrollPaintPos() const
  3377. {
  3378. ASSERT_VALID( this );
  3379. return CPoint( 0, 0 );
  3380. }
  3381. void CExtScrollContainerWnd::OnSwPaint( CDC & dc )
  3382. {
  3383. ASSERT_VALID( this );
  3384. if( m_clrBkColor != COLORREF(-1L) )
  3385. {
  3386. CRect rcClient;
  3387. GetClientRect( &rcClient );
  3388. dc.FillSolidRect(
  3389. &rcClient,
  3390. m_clrBkColor
  3391. );
  3392. return;
  3393. }
  3394. if( ! g_PaintManager->PaintDockerBkgnd(
  3395. true,
  3396. dc,
  3397. this
  3398. )
  3399. )
  3400. {
  3401. CRect rcClient;
  3402. GetClientRect( &rcClient );
  3403. dc.FillSolidRect(
  3404. &rcClient,
  3405. g_PaintManager->GetColor( COLOR_BTNFACE, this )
  3406. );
  3407. }
  3408. }
  3409. void CExtScrollContainerWnd::OnSwPaintAreaBetweenScrollBarWindows(
  3410. CDC & dc,
  3411. const RECT & rcAreaBetweenScrollBarWindows
  3412. )
  3413. {
  3414. ASSERT_VALID( this );
  3415. dc.FillSolidRect(
  3416. &rcAreaBetweenScrollBarWindows,
  3417. g_PaintManager->GetColor( COLOR_BTNFACE, this )
  3418. );
  3419. }
  3420. CSize CExtScrollContainerWnd::OnSwGetTotalSize() const
  3421. {
  3422. ASSERT_VALID( this );
  3423. return m_sizeToScroll;
  3424. }
  3425. CSize CExtScrollContainerWnd::OnSwGetPageSize( int nDirection ) const
  3426. {
  3427. ASSERT_VALID( this );
  3428. nDirection;
  3429. return CSize( 100, 100 );
  3430. }
  3431. CSize CExtScrollContainerWnd::OnSwGetLineSize( int nDirection ) const
  3432. {
  3433. ASSERT_VALID( this );
  3434. nDirection;
  3435. return CSize( 1, 1 );
  3436. }
  3437. CScrollBar * CExtScrollContainerWnd::GetScrollBarCtrl(int nBar) const
  3438. {
  3439. ASSERT_VALID( this );
  3440. if( m_hWnd == NULL || (! ::IsWindow(m_hWnd) ) )
  3441. return NULL;
  3442. ASSERT( nBar == SB_HORZ || nBar == SB_VERT );
  3443. if( nBar == SB_HORZ )
  3444. {
  3445. if( m_wndScrollBarH.GetSafeHwnd() != NULL )
  3446. return ( const_cast < CExtScrollBar * > ( &m_wndScrollBarH ) );
  3447. } // if( nBar == SB_HORZ )
  3448. else
  3449. {
  3450. if( m_wndScrollBarV.GetSafeHwnd() != NULL )
  3451. return ( const_cast < CExtScrollBar * > ( &m_wndScrollBarV ) );
  3452. } // else from if( nBar == SB_HORZ )
  3453. return NULL;
  3454. }
  3455. void CExtScrollContainerWnd::PreSubclassWindow() 
  3456. {
  3457. CExtScrollWnd::PreSubclassWindow();
  3458. }
  3459. void CExtScrollContainerWnd::PostNcDestroy()
  3460. {
  3461. CExtScrollWnd::PostNcDestroy();
  3462. if( m_bAutoDelete )
  3463. delete this;
  3464. }
  3465. void CExtScrollContainerWnd::OnSetFocus( CWnd * pOldWnd )
  3466. {
  3467. CExtScrollWnd::OnSetFocus( pOldWnd );
  3468. if( ! m_bRedirectFocus )
  3469. return;
  3470. CWnd * pWndToScroll = OnGetWndToScroll();
  3471. if( pWndToScroll == NULL )
  3472. return;
  3473. pWndToScroll->SetFocus();
  3474. }
  3475. void CExtScrollContainerWnd::OnEnable( BOOL bEnable )
  3476. {
  3477. CExtScrollWnd::OnEnable( bEnable );
  3478. if( ! m_bSynchronizeEnabledState )
  3479. return;
  3480. CWnd * pWndToScroll = OnGetWndToScroll();
  3481. if( pWndToScroll == NULL )
  3482. return;
  3483. pWndToScroll->EnableWindow( bEnable );
  3484. }
  3485. BOOL CExtScrollContainerWnd::PreTranslateMessage( MSG * pMsg )
  3486. {
  3487. if( m_bRedirectPreTranslateMessage )
  3488. {
  3489. CWnd * pWndToScroll = OnGetWndToScroll();
  3490. if( pWndToScroll != NULL
  3491. && pWndToScroll->PreTranslateMessage( pMsg )
  3492. )
  3493. return TRUE;
  3494. }
  3495. return CExtScrollWnd::PreTranslateMessage( pMsg );
  3496. }
  3497. BOOL CExtScrollContainerWnd::OnCmdMsg( UINT nID, int nCode, void * pExtra, AFX_CMDHANDLERINFO * pHandlerInfo )
  3498. {
  3499. if( m_bRedirectOnCmdMsg )
  3500. {
  3501. CWnd * pWndToScroll = OnGetWndToScroll();
  3502. if( pWndToScroll != NULL
  3503. && pWndToScroll->OnCmdMsg( nID, nCode, pExtra, pHandlerInfo )
  3504. )
  3505. return TRUE;
  3506. }
  3507. return CExtScrollWnd::OnCmdMsg( nID, nCode, pExtra, pHandlerInfo );
  3508. }
  3509. int CExtScrollContainerWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) 
  3510. {
  3511. if( CExtScrollWnd::OnCreate( lpCreateStruct ) == -1 )
  3512. return -1;
  3513. m_wndScrollBarH.m_eSO = CExtScrollBar::__ESO_BOTTOM;
  3514. m_wndScrollBarV.m_eSO = CExtScrollBar::__ESO_RIGHT;
  3515. if( ! m_wndScrollBarV.Create(
  3516. WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|SBS_VERT|SBS_RIGHTALIGN,
  3517. CRect(0,0,0,0),
  3518. this,
  3519. 1
  3520. )
  3521. )
  3522. {
  3523. ASSERT( FALSE );
  3524. return -1;
  3525. }
  3526. if( ! m_wndScrollBarH.Create(
  3527. WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|SBS_HORZ|SBS_BOTTOMALIGN,
  3528. CRect(0,0,0,0),
  3529. this,
  3530. 2
  3531. )
  3532. )
  3533. {
  3534. ASSERT( FALSE );
  3535. return -1;
  3536. }
  3537. m_wndScrollBarH.SyncReservedSpace( &m_wndScrollBarV );
  3538. m_wndScrollBarV.SyncReservedSpace( &m_wndScrollBarH );
  3539. if( ! m_wndCorner.Create(
  3540. _T(""),
  3541. WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS,
  3542. CRect(0,0,0,0),
  3543. this,
  3544. 3
  3545. )
  3546. )
  3547. {
  3548. ASSERT( FALSE );
  3549. return -1;
  3550. }
  3551. OnSwRecalcLayout( true );
  3552. return 0;
  3553. }
  3554. CRect CExtScrollContainerWnd::OnSwRecalcLayout(
  3555. bool bDoLayout,
  3556. LPCRECT pRectClientSrc // = NULL
  3557. )
  3558. {
  3559. ASSERT_VALID( this );
  3560. CWnd * pWndToScroll = OnGetWndToScroll();
  3561. if( m_sizeToScroll.cx == 0 && m_sizeToScroll.cy == 0 )
  3562. {
  3563. if( pWndToScroll != NULL )
  3564. {
  3565. ASSERT_VALID( pWndToScroll );
  3566. CRect rcWnd;
  3567. pWndToScroll->GetWindowRect( &rcWnd );
  3568. m_sizeToScroll = rcWnd.Size();
  3569. } // if( pWndToScroll != NULL )
  3570. } // if( m_sizeToScroll.cx == 0 && m_sizeToScroll.cy == 0 )
  3571. else
  3572. {
  3573. if( pWndToScroll == NULL )
  3574. m_sizeToScroll.cx = m_sizeToScroll.cy = 0;
  3575. } // else from if( m_sizeToScroll.cx == 0 && m_sizeToScroll.cy == 0 )
  3576. CRect rc = CExtScrollWnd::OnSwRecalcLayout( bDoLayout, pRectClientSrc ); 
  3577. if( ( ! bDoLayout)
  3578. || m_sizeToScroll.cx == 0
  3579. || m_sizeToScroll.cy == 0
  3580. )
  3581. return rc;
  3582. ASSERT_VALID( pWndToScroll );
  3583. CSize _sizeFree = rc.Size();
  3584. CSize _sizeEffective(
  3585. max( _sizeFree.cx, m_sizeToScroll.cx ),
  3586. max( _sizeFree.cy, m_sizeToScroll.cy )
  3587. );
  3588. LONG lPosHorz = ScrollPos32Get( SB_HORZ );
  3589. LONG lPosVert = ScrollPos32Get( SB_VERT );
  3590. CSize sizeSB( 0, 0 );
  3591. if( m_wndCorner.GetSafeHwnd() != NULL
  3592. && m_wndScrollBarH.GetSafeHwnd() != NULL
  3593. && m_wndScrollBarV.GetSafeHwnd() != NULL
  3594. )
  3595. {
  3596. CRect rcCorner( 0, 0, 0, 0 ), rcSBH( 0, 0, 0, 0 ), rcSBV( 0, 0, 0, 0 );
  3597. bool bVisibleH = ( ( m_wndScrollBarH.GetStyle() & WS_VISIBLE ) != 0 ) ? true : false;
  3598. bool bVisibleV = ( ( m_wndScrollBarV.GetStyle() & WS_VISIBLE ) != 0 ) ? true : false;
  3599. if( bVisibleH )
  3600. {
  3601. m_wndScrollBarH.GetWindowRect( &rcSBH );
  3602. sizeSB.cy = rcSBH.Height();
  3603. }
  3604. if( bVisibleV )
  3605. {
  3606. m_wndScrollBarV.GetWindowRect( &rcSBV );
  3607. sizeSB.cx = rcSBV.Width();
  3608. }
  3609. if( bVisibleH && bVisibleV )
  3610. {
  3611. rcCorner.SetRect( rcSBV.left, rcSBH.top, rcSBV.right, rcSBH.bottom );
  3612. ScreenToClient( &rcCorner );
  3613. }
  3614. if( ! rcCorner.IsRectEmpty() )
  3615. m_wndCorner.SetWindowPos(
  3616. &wndTop,
  3617. rcCorner.left, rcCorner.top, rcCorner.Width(), rcCorner.Height(),
  3618. SWP_NOACTIVATE|SWP_SHOWWINDOW
  3619. );
  3620. else if( ( m_wndCorner.GetStyle() & WS_VISIBLE ) != 0 )
  3621. m_wndCorner.ShowWindow( SW_HIDE );
  3622. }
  3623. if( m_bSynchronizeEnabledState )
  3624. {
  3625. BOOL bEnabledContainer = IsWindowEnabled();
  3626. BOOL bEnabledWndToScroll = pWndToScroll->IsWindowEnabled();
  3627. if( ( bEnabledContainer && (!bEnabledWndToScroll) )
  3628. || ( (!bEnabledContainer) && bEnabledWndToScroll )
  3629. )
  3630. pWndToScroll->EnableWindow( bEnabledContainer );
  3631. }
  3632. COLORREF clrCornerBk = m_wndCorner.GetBkColor();
  3633. if( m_clrBkColor != clrCornerBk )
  3634. m_wndCorner.SetBkColor( m_clrBkColor );
  3635. if( bDoLayout )
  3636. {
  3637. if( _sizeFree.cx >= m_sizeToScroll.cx )
  3638. {
  3639. _sizeFree.cx -= sizeSB.cx;
  3640. _sizeEffective.cx = max( _sizeFree.cx, m_sizeToScroll.cx );
  3641. }
  3642. if( _sizeFree.cy >= m_sizeToScroll.cy )
  3643. {
  3644. _sizeFree.cy -= sizeSB.cy;
  3645. _sizeEffective.cy = max( _sizeFree.cy, m_sizeToScroll.cy );
  3646. }
  3647. //pWndToScroll->MoveWindow( -lPosHorz, -lPosVert, _sizeEffective.cx, _sizeEffective.cy );
  3648. pWndToScroll->SetWindowPos( &CWnd::wndBottom, -lPosHorz, -lPosVert, _sizeEffective.cx, _sizeEffective.cy, SWP_SHOWWINDOW );
  3649. OnSwUpdateScrollBars();
  3650. }
  3651. return rc;
  3652. }
  3653. bool CExtScrollContainerWnd::OnSwDoScrollBy(
  3654. CSize sizeScroll,
  3655. bool bDoScroll // = true
  3656. )
  3657. {
  3658. ASSERT_VALID( this );
  3659. CExtScrollWnd::OnSwDoScrollBy(sizeScroll,bDoScroll);
  3660. if( m_sizeToScroll.cx == 0
  3661. || m_sizeToScroll.cy == 0
  3662. )
  3663. return true;
  3664. CWnd * pWndToScroll = OnGetWndToScroll();
  3665. ASSERT_VALID( pWndToScroll );
  3666. CRect rc = OnSwGetClientRect();
  3667. CSize _sizeFree = rc.Size();
  3668. CSize _sizeEffective(
  3669. max( _sizeFree.cx, m_sizeToScroll.cx ),
  3670. max( _sizeFree.cy, m_sizeToScroll.cy )
  3671. );
  3672. LONG lPosHorz = ScrollPos32Get( SB_HORZ );
  3673. LONG lPosVert = ScrollPos32Get( SB_VERT );
  3674. //pWndToScroll->MoveWindow( -lPosHorz, -lPosVert, _sizeEffective.cx, _sizeEffective.cy );
  3675. pWndToScroll->SetWindowPos( &CWnd::wndBottom, -lPosHorz, -lPosVert, _sizeEffective.cx, _sizeEffective.cy, SWP_SHOWWINDOW );
  3676. if( m_nScrollRedrawFlags != 0 )
  3677. RedrawWindow( NULL, NULL, m_nScrollRedrawFlags );
  3678. return true;
  3679. }
  3680. bool CExtScrollContainerWnd::Create(
  3681. CWnd * pWndParent,
  3682. const RECT & rc,
  3683. UINT nDlgCtrlID // = AFX_IDW_PANE_FIRST
  3684. )
  3685. {
  3686. ASSERT_VALID( this );
  3687. if( GetSafeHwnd() != NULL )
  3688. {
  3689. ASSERT( FALSE );
  3690. return false;
  3691. }
  3692. if( ! CWnd::Create(
  3693. NULL, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
  3694. rc, pWndParent, nDlgCtrlID )
  3695. )
  3696. {
  3697. ASSERT( FALSE );
  3698. return false;
  3699. }
  3700. return true;
  3701. }
  3702. CWnd * CExtScrollContainerWnd::OnGetWndToScroll()
  3703. {
  3704. ASSERT_VALID( this );
  3705. CWnd * pWndToScroll = GetWindow( GW_CHILD );
  3706. for( ; pWndToScroll != NULL; pWndToScroll = pWndToScroll->GetWindow( GW_HWNDNEXT ) )
  3707. {
  3708. if( pWndToScroll->IsKindOf( RUNTIME_CLASS( CExtScrollBar ) )
  3709. || LPVOID(pWndToScroll) == LPVOID(&m_wndCorner)
  3710. )
  3711. continue;
  3712. return pWndToScroll;
  3713. }
  3714. return NULL;
  3715. }
  3716. #endif // (!defined __EXT_MFC_NO_SCROLLCONAINERWND)
  3717. #endif // (!defined __EXT_MFC_NO_SCROLLWND)