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

界面编程

开发平台:

Visual C++

  1. // This is part of the Professional User Interface Suite library.
  2. // Copyright (C) 2001-2009 FOSS Software, Inc.
  3. // All rights reserved.
  4. //
  5. // http://www.prof-uis.com
  6. // mailto:support@prof-uis.com
  7. //
  8. // This source code can be used, modified and redistributed
  9. // under the terms of the license agreement that is included
  10. // in the Professional User Interface Suite package.
  11. //
  12. // Warranties and Disclaimers:
  13. // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND
  14. // INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  16. // IN NO EVENT WILL FOSS SOFTWARE INC. BE LIABLE FOR ANY DIRECT,
  17. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES,
  18. // INCLUDING DAMAGES FOR LOSS OF PROFITS, LOSS OR INACCURACY OF DATA,
  19. // INCURRED BY ANY PERSON FROM SUCH PERSON'S USAGE OF THIS SOFTWARE
  20. // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  21. #include "StdAfx.h"
  22. #if (!defined __EXT_MFC_NO_SPLITTER_WND)
  23. #if (!defined __EXT_SPLITTER_WND_H)
  24. #include <ExtSplitterWnd.h>
  25. #endif
  26. #if (!defined __EXT_SCROLLWND_H)
  27. #include <ExtScrollWnd.h>
  28. #endif 
  29. #if (!defined __EXT_PAINT_MANAGER_H)
  30. #include <ExtPaintManager.h>
  31. #endif
  32. #if (!defined __EXT_RESIZABLE_DIALOG_H)
  33. #include <ExtResizableDialog.h>
  34. #endif
  35. #if _MFC_VER < 0x700
  36. #include <../src/AfxImpl.h>
  37. #else
  38. #include <../src/mfc/AfxImpl.h>
  39. #endif
  40. #if (!defined __AFXPRIV_H__)
  41. #include <AfxPriv.h>
  42. #endif
  43. #ifdef _DEBUG
  44. #define new DEBUG_NEW
  45. #undef THIS_FILE
  46. static char THIS_FILE[] = __FILE__;
  47. #endif
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CExtSplitterBaseWnd
  50. IMPLEMENT_DYNCREATE( CExtSplitterBaseWnd, CSplitterWnd );
  51. IMPLEMENT_CExtPmBridge_MEMBERS( CExtSplitterBaseWnd );
  52. HCURSOR CExtSplitterBaseWnd::g_split_hcurLast = NULL;
  53. HCURSOR CExtSplitterBaseWnd::g_split_hcurDestroy = NULL;
  54. UINT CExtSplitterBaseWnd::g_split_idcPrimaryLast = 0;
  55. CExtSplitterBaseWnd::CExtSplitterBaseWnd()
  56. : m_clrBackground( COLORREF(-1L) )
  57. {
  58. //AFX_ZERO_INIT_OBJECT( CWnd );
  59. #if _MFC_VER < 0x700
  60. if( ! afxData.bWin4 )
  61. {
  62. m_cxSplitter = m_cySplitter = 4;
  63. m_cxBorderShare = m_cyBorderShare = 1;
  64. m_cxSplitterGap = m_cySplitterGap = 4 + 1 + 1;
  65. ASSERT( m_cxBorder == 0 && m_cyBorder == 0 );
  66. }
  67. else
  68. #endif //_MFC_VER < 0x700
  69. {
  70. m_cxSplitter = m_cySplitter = 3 + 2 + 2;
  71. m_cxBorderShare = m_cyBorderShare = 0;
  72. m_cxSplitterGap = m_cySplitterGap = 3 + 2 + 2;
  73. m_cxBorder = m_cyBorder = 2;
  74. }
  75. #ifdef _DEBUG
  76. if( GetSystemMetrics(SM_CXBORDER) != 1
  77. || GetSystemMetrics(SM_CYBORDER) != 1
  78. )
  79. {
  80. TRACE0( "Warning: CExtSplitterBaseWnd assumes 1 pixel border.n" );
  81. }
  82. #endif
  83. PmBridge_Install();
  84. }
  85. CExtSplitterBaseWnd::~CExtSplitterBaseWnd()
  86. {
  87. // delete[] m_pRowInfo;
  88. // delete[] m_pColInfo;
  89. PmBridge_Uninstall();
  90. }
  91. COLORREF CExtSplitterBaseWnd::OnQueryBackgroundColor() const
  92. {
  93. ASSERT_VALID( this );
  94. return m_clrBackground;
  95. }
  96. int CExtSplitterBaseWnd::stat_CanSplitRowCol( CExtSplitterBaseWnd::CRowColInfo * pInfoBefore, int nBeforeSize, int nSizeSplitter )
  97. {
  98. ASSERT( pInfoBefore->nCurSize > 0 );
  99. ASSERT( pInfoBefore->nMinSize > 0 );
  100. ASSERT( nBeforeSize <= pInfoBefore->nCurSize );
  101. if( nBeforeSize < pInfoBefore->nMinSize )
  102. {
  103. TRACE0("Warning: split too small to fit in a new pane.n");
  104. return -1;
  105. }
  106. int nNewSize = pInfoBefore->nCurSize - nBeforeSize - nSizeSplitter;
  107. if( nBeforeSize < pInfoBefore->nMinSize )
  108. {
  109. TRACE0("Warning: split too small to shrink old pane.n");
  110. return -1;
  111. }
  112. if( nNewSize < (pInfoBefore+1)->nMinSize )
  113. {
  114. TRACE0("Warning: split too small to create new pane.n");
  115. return -1;
  116. }
  117. return nNewSize;
  118. }
  119. void CExtSplitterBaseWnd::stat_LayoutRowCol( CExtSplitterBaseWnd::CRowColInfo * pInfoArray, int nMax, int nSize, int nSizeSplitter )
  120. {
  121. ASSERT( pInfoArray != NULL );
  122. ASSERT( nMax > 0);
  123. ASSERT( nSizeSplitter > 0 );
  124. CExtSplitterBaseWnd::CRowColInfo * pInfo;
  125. int i;
  126. if( nSize < 0 )
  127. nSize = 0;
  128. for( i = 0, pInfo = pInfoArray; i < nMax-1; i++, pInfo++ )
  129. {
  130. if( pInfo->nIdealSize < pInfo->nMinSize )
  131. pInfo->nIdealSize = 0;
  132. pInfo->nCurSize = pInfo->nIdealSize;
  133. }
  134. pInfo->nCurSize = INT_MAX;
  135. for( i = 0, pInfo = pInfoArray; i < nMax; i++, pInfo++ )
  136. {
  137. ASSERT(nSize >= 0);
  138. if( nSize == 0)
  139. {
  140. // no more room (set pane to be invisible)
  141. pInfo->nCurSize = 0;
  142. continue;       // don't worry about splitters
  143. }
  144. else if( nSize < pInfo->nMinSize && i != 0 )
  145. {
  146. pInfo->nCurSize = 0;
  147. ASSERT( afxData.cxBorder2 == afxData.cyBorder2 );
  148. (pInfo-1)->nCurSize += nSize + afxData.cxBorder2;
  149. nSize = 0;
  150. }
  151. else
  152. {
  153. ASSERT(nSize > 0 );
  154. if( pInfo->nCurSize == 0)
  155. {
  156. if( i != 0 )
  157. pInfo->nCurSize = 0;
  158. }
  159. else if( nSize < pInfo->nCurSize )
  160. {
  161. pInfo->nCurSize = nSize;
  162. nSize = 0;
  163. }
  164. else
  165. nSize -= pInfo->nCurSize;
  166. }
  167. ASSERT( nSize >= 0 );
  168. if( i != nMax - 1 )
  169. {
  170. if( nSize > nSizeSplitter )
  171. {
  172. nSize -= nSizeSplitter;
  173. ASSERT( nSize > 0 );
  174. }
  175. else
  176. {
  177. ASSERT( afxData.cxBorder2 == afxData.cyBorder2 );
  178. pInfo->nCurSize += nSize;
  179. if( pInfo->nCurSize > (nSizeSplitter - afxData.cxBorder2))
  180. pInfo->nCurSize -= (nSizeSplitter - afxData.cyBorder2);
  181. nSize = 0;
  182. }
  183. }
  184. }
  185. ASSERT(nSize == 0);
  186. }
  187. void CExtSplitterBaseWnd::stat_DeferClientPos( AFX_SIZEPARENTPARAMS* lpLayout, CWnd * pWnd, int x, int y, int cx, int cy, BOOL bScrollBar )
  188. {
  189. ASSERT( pWnd != NULL );
  190. ASSERT( pWnd->m_hWnd != NULL );
  191. if( bScrollBar )
  192. {
  193. BOOL bNeedBorder = ( cx <= __EXT_MFC_CX_BORDER || cy <= __EXT_MFC_CY_BORDER );
  194. pWnd->ModifyStyle( bNeedBorder ? 0 : WS_BORDER, bNeedBorder ? WS_BORDER : 0 );
  195. }
  196. CRect rect( x, y, x+cx, y+cy );
  197. #if _MFC_VER < 0x700
  198. if( ! afxData.bWin4 )
  199. {
  200. if( bScrollBar )
  201. rect.InflateRect( __EXT_MFC_CX_BORDER, __EXT_MFC_CY_BORDER );
  202. else
  203. pWnd->CalcWindowRect( &rect );
  204. }
  205. #endif //_MFC_VER < 0x700
  206. if( ( pWnd->GetExStyle() & WS_EX_CLIENTEDGE ) || pWnd->IsKindOf( RUNTIME_CLASS( CExtSplitterBaseWnd ) ) )
  207. rect.InflateRect( afxData.cxBorder2, afxData.cyBorder2 );
  208. CRect rectOld;
  209. pWnd->GetWindowRect( rectOld );
  210. pWnd->GetParent()->ScreenToClient( &rectOld );
  211. if( rect != rectOld )
  212. AfxRepositionWindow( lpLayout, pWnd->m_hWnd, rect );
  213. }
  214. BEGIN_MESSAGE_MAP( CExtSplitterBaseWnd, CSplitterWnd )
  215. //{{AFX_MSG_MAP(CExtSplitterBaseWnd)
  216. ON_WM_SETCURSOR()
  217. ON_WM_MOUSEMOVE()
  218. ON_WM_PAINT()
  219. ON_WM_LBUTTONDOWN()
  220. ON_WM_LBUTTONDBLCLK()
  221. ON_WM_LBUTTONUP()
  222. ON_WM_KEYDOWN()
  223. ON_WM_SIZE()
  224. ON_WM_HSCROLL()
  225. ON_WM_VSCROLL()
  226. ON_WM_NCCREATE()
  227. ON_WM_SYSCOMMAND()
  228. ON_WM_CANCELMODE()
  229. ON_WM_MOUSEWHEEL()
  230. //}}AFX_MSG_MAP
  231. ON_MESSAGE_VOID( WM_DISPLAYCHANGE, OnDisplayChange )
  232. ON_MESSAGE_VOID( WM_WININICHANGE, OnDisplayChange )
  233. ON_MESSAGE_VOID( WM_SETTINGCHANGE, OnDisplayChange )
  234. ON_MESSAGE( WM_NEXTDLGCTL, OnNextDlgCtrl )
  235. END_MESSAGE_MAP()
  236. #ifdef _DEBUG
  237. void CExtSplitterBaseWnd::AssertValid() const
  238. {
  239. CWnd::AssertValid();
  240. ASSERT( m_nMaxRows >= 0 );
  241. ASSERT( m_nMaxCols >= 0 );
  242. ASSERT( m_nMaxCols >= 0 && m_nMaxRows >= 0 );
  243. ASSERT( m_nRows >= 0 );
  244. ASSERT( m_nCols >= 0 );
  245. ASSERT( m_nRows <= m_nMaxRows );
  246. ASSERT( m_nCols <= m_nMaxCols );
  247. }
  248. void CExtSplitterBaseWnd::Dump( CDumpContext & dc ) const
  249. {
  250. CSplitterWnd::Dump( dc );
  251. if( m_pDynamicViewClass != NULL )
  252. dc << "m_pDynamicViewClass = " << m_pDynamicViewClass->m_lpszClassName;
  253. dc << "nm_nMaxRows = " << m_nMaxRows;
  254. dc << "nm_nMaxCols = " << m_nMaxCols;
  255. dc << "nm_nRows = " << m_nRows;
  256. dc << "nm_nCols = " << m_nCols;
  257. dc << "nm_bHasHScroll = " << m_bHasHScroll;
  258. dc << "nm_bHasVScroll = " << m_bHasVScroll;
  259. dc << "nm_cxSplitter = " << m_cxSplitter;
  260. dc << "nm_cySplitter = " << m_cySplitter;
  261. if( m_bTracking )
  262. {
  263. dc << "nTRACKING: m_htTrack = " << m_htTrack;
  264. dc << "nm_rectLimit = " << m_rectLimit;
  265. dc << "nm_ptTrackOffset = " << m_ptTrackOffset;
  266. dc << "nm_rectTracker = " << m_rectTracker;
  267. if( m_bTracking2)
  268. dc << "nm_rectTracker2 = " << m_rectTracker2;
  269. }
  270. dc << "n";
  271. }
  272. #endif
  273. BOOL CExtSplitterBaseWnd::Create(
  274. CWnd * pParentWnd,
  275. int nMaxRows,
  276. int nMaxCols,
  277. SIZE sizeMin,
  278. CCreateContext * pContext,
  279. DWORD dwStyle,
  280. UINT nID
  281. )
  282. {
  283. ASSERT( pParentWnd != NULL );
  284. ASSERT( sizeMin.cx > 0 && sizeMin.cy > 0 );
  285. ASSERT( pContext != NULL );
  286. ASSERT( pContext->m_pNewViewClass != NULL );
  287. ASSERT( dwStyle & WS_CHILD );
  288. ASSERT( dwStyle & SPLS_DYNAMIC_SPLIT );
  289. ASSERT( nMaxRows >= 1 && nMaxRows <= 2 );
  290. ASSERT( nMaxCols >= 1 && nMaxCols <= 2 );
  291. ASSERT( nMaxCols > 1 || nMaxRows > 1 );
  292. m_nMaxRows = nMaxRows;
  293. m_nMaxCols = nMaxCols;
  294. ASSERT( m_nRows == 0 && m_nCols == 0 );
  295. m_nRows = m_nCols = 1;
  296. if( ! CreateCommon( pParentWnd, sizeMin, dwStyle, nID ) )
  297. return FALSE;
  298. ASSERT( m_nRows == 1 && m_nCols == 1 );
  299. ASSERT( pContext->m_pNewViewClass->IsDerivedFrom( RUNTIME_CLASS( CWnd ) ) );
  300. m_pDynamicViewClass = pContext->m_pNewViewClass;
  301. if( ! CreateView( 0, 0, m_pDynamicViewClass, sizeMin, pContext ) )
  302. {
  303. DestroyWindow();
  304. return FALSE;
  305. }
  306. m_pColInfo[0].nIdealSize = sizeMin.cx;
  307. m_pRowInfo[0].nIdealSize = sizeMin.cy;
  308. return TRUE;
  309. }
  310. BOOL CExtSplitterBaseWnd::CreateStatic(
  311. CWnd * pParentWnd,
  312. int nRows,
  313. int nCols,
  314. DWORD dwStyle,
  315. UINT nID
  316. )
  317. {
  318. ASSERT( pParentWnd != NULL );
  319. ASSERT( nRows >= 1 && nRows <= 16 );
  320. ASSERT( nCols >= 1 && nCols <= 16 );
  321. ASSERT( nCols > 1 || nRows > 1 );
  322. ASSERT( dwStyle & WS_CHILD );
  323. ASSERT( !(dwStyle & SPLS_DYNAMIC_SPLIT ) );
  324. ASSERT( m_nRows == 0 && m_nCols == 0 );
  325. m_nRows = m_nMaxRows = nRows;
  326. m_nCols = m_nMaxCols = nCols;
  327. if( ! CreateCommon( pParentWnd, CSize( 0, 0 ), dwStyle, nID ) )
  328. return FALSE;
  329. return TRUE;
  330. }
  331. BOOL CExtSplitterBaseWnd::CreateCommon( CWnd * pParentWnd, SIZE sizeMin, DWORD dwStyle, UINT nID )
  332. {
  333. ASSERT( pParentWnd != NULL );
  334. ASSERT( sizeMin.cx >= 0 && sizeMin.cy >= 0 );
  335. ASSERT( dwStyle & WS_CHILD );
  336. ASSERT( nID != 0 );
  337. ASSERT( m_pColInfo == NULL && m_pRowInfo == NULL );
  338. ASSERT( m_nMaxCols > 0 && m_nMaxRows > 0 );
  339. DWORD dwCreateStyle = dwStyle & ~(WS_HSCROLL|WS_VSCROLL);
  340. #if _MFC_VER < 0x700
  341. if( afxData.bWin4 )
  342. #endif //_MFC_VER < 0x700
  343. dwCreateStyle &= ~WS_BORDER;
  344. VERIFY( AfxDeferRegisterClass( AFX_WNDMDIFRAME_REG ) );
  345. static const TCHAR _afxWndMDIFrame[] = AFX_WNDMDIFRAME;
  346. if( ! CreateEx( WS_EX_CONTROLPARENT, _afxWndMDIFrame, NULL, dwCreateStyle, 0, 0, 0, 0, pParentWnd->m_hWnd, (HMENU)nID, NULL ) )
  347. return FALSE;
  348. TRY
  349. {
  350. m_pColInfo = new CRowColInfo[ m_nMaxCols ];
  351. for( int col = 0; col < m_nMaxCols; col++ )
  352. {
  353. m_pColInfo[col].nMinSize = m_pColInfo[col].nIdealSize = sizeMin.cx;
  354. m_pColInfo[col].nCurSize = -1;
  355. }
  356. m_pRowInfo = new CRowColInfo[m_nMaxRows];
  357. for( int row = 0; row < m_nMaxRows; row++ )
  358. {
  359. m_pRowInfo[row].nMinSize = m_pRowInfo[row].nIdealSize = sizeMin.cy;
  360. m_pRowInfo[row].nCurSize = -1;
  361. }
  362. SetScrollStyle( dwStyle );
  363. }
  364. CATCH_ALL( e )
  365. {
  366. DestroyWindow();
  367. return FALSE;
  368. }
  369. END_CATCH_ALL
  370. return TRUE;
  371. }
  372. BOOL CExtSplitterBaseWnd::OnNcCreate( LPCREATESTRUCT lpcs )
  373. {
  374. if( ! CSplitterWnd::OnNcCreate( lpcs ) )
  375. return FALSE;
  376. CWnd * pParent = GetParent();
  377. ASSERT_VALID( pParent );
  378. pParent->ModifyStyleEx( WS_EX_CLIENTEDGE, 0, SWP_DRAWFRAME );
  379. return TRUE;
  380. }
  381. BOOL CExtSplitterBaseWnd::CreateView(
  382. int row,
  383. int col,
  384. CRuntimeClass * pViewClass,
  385. SIZE sizeInit,
  386. CCreateContext * pContext
  387. )
  388. {
  389. ASSERT_VALID( this );
  390. ASSERT( row >= 0 && row < m_nRows );
  391. ASSERT( col >= 0 && col < m_nCols );
  392. ASSERT( pViewClass != NULL );
  393. ASSERT( pViewClass->IsDerivedFrom( RUNTIME_CLASS( CWnd ) ) );
  394. ASSERT( AfxIsValidAddress( pViewClass, sizeof( CRuntimeClass ), FALSE ) );
  395. #ifdef _DEBUG
  396. if( GetDlgItem( IdFromRowCol( row, col ) ) != NULL )
  397. {
  398. TRACE2(" Error: CreateView - pane already exists for row %d, col %d.n", row, col );
  399. ASSERT( FALSE );
  400. return FALSE;
  401. }
  402. #endif
  403. m_pColInfo[col].nIdealSize = sizeInit.cx;
  404. m_pRowInfo[row].nIdealSize = sizeInit.cy;
  405. BOOL bSendInitialUpdate = FALSE;
  406. CCreateContext contextT;
  407. if( pContext == NULL )
  408. {
  409. CView * pOldView = (CView*)GetActivePane();
  410. if( pOldView != NULL && pOldView->IsKindOf( RUNTIME_CLASS( CView ) ) )
  411. {
  412. ASSERT( contextT.m_pCurrentFrame == NULL );
  413. contextT.m_pLastView = pOldView;
  414. contextT.m_pCurrentDoc = pOldView->GetDocument();
  415. if( contextT.m_pCurrentDoc != NULL )
  416. contextT.m_pNewDocTemplate = contextT.m_pCurrentDoc->GetDocTemplate();
  417. }
  418. pContext = &contextT;
  419. bSendInitialUpdate = TRUE;
  420. }
  421. CWnd * pWnd = NULL;
  422. TRY
  423. {
  424. pWnd = (CWnd*)pViewClass->CreateObject();
  425. if( pWnd == NULL )
  426. AfxThrowMemoryException();
  427. }
  428. CATCH_ALL(e)
  429. {
  430. TRACE0("Out of memory creating a splitter pane.n");
  431. // Note: DELETE_EXCEPTION(e) not required
  432. return FALSE;
  433. }
  434. END_CATCH_ALL
  435. ASSERT_KINDOF( CWnd, pWnd );
  436. ASSERT( pWnd->m_hWnd == NULL );
  437. DWORD dwStyle = AFX_WS_DEFAULT_VIEW;
  438. #if _MFC_VER < 0x700
  439. if( afxData.bWin4 )
  440. #endif //_MFC_VER < 0x700
  441. dwStyle &= ~WS_BORDER;
  442. CRect rect(CPoint(0,0), sizeInit);
  443. if( ! pWnd->Create( NULL, NULL, dwStyle, rect, this, IdFromRowCol(row, col), pContext ) )
  444. {
  445. TRACE0("Warning: couldn't create client pane for splitter.n");
  446. return FALSE;
  447. }
  448. ASSERT( (int)_AfxGetDlgCtrlID( pWnd->m_hWnd ) == IdFromRowCol( row, col ) );
  449. if( bSendInitialUpdate )
  450. pWnd->SendMessage( WM_INITIALUPDATE );
  451. return TRUE;
  452. }
  453. BOOL CExtSplitterBaseWnd::CreateScrollBarCtrl( DWORD dwStyle, UINT nID )
  454. {
  455. ASSERT_VALID( this );
  456. ASSERT(m_hWnd != NULL);
  457. HWND hWnd =
  458. ::CreateWindow(
  459. _T("SCROLLBAR"),
  460. NULL,
  461. dwStyle|WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
  462. 0, 0, 1, 1,
  463. m_hWnd,
  464. (HMENU)nID,
  465. AfxGetInstanceHandle(),
  466. NULL
  467. );
  468. #ifdef _DEBUG
  469. if( hWnd == NULL )
  470. TRACE1( "Warning: Window creation failed: GetLastError returns 0x%8.8Xn", GetLastError() );
  471. #endif
  472. return hWnd != NULL;
  473. }
  474. int CExtSplitterBaseWnd::IdFromRowCol( int row, int col ) const
  475. {
  476. ASSERT_VALID( this );
  477. ASSERT( row >= 0 );
  478. ASSERT( row < m_nRows );
  479. ASSERT( col >= 0 );
  480. ASSERT( col < m_nCols );
  481. return AFX_IDW_PANE_FIRST + row * 16 + col;
  482. }
  483. CWnd * CExtSplitterBaseWnd::GetPane( int row, int col ) const
  484. {
  485. ASSERT_VALID( this );
  486. CWnd * pView = GetDlgItem( IdFromRowCol(row, col) );
  487. ASSERT( pView != NULL );
  488. return pView;
  489. }
  490. BOOL CExtSplitterBaseWnd::IsChildPane( CWnd * pWnd, int * pRow, int * pCol )
  491. {
  492. ASSERT_VALID( this );
  493. ASSERT_VALID( pWnd );
  494. UINT nID = _AfxGetDlgCtrlID( pWnd->m_hWnd );
  495. if( IsChild( pWnd ) && nID >= AFX_IDW_PANE_FIRST && nID <= AFX_IDW_PANE_LAST )
  496. {
  497. if( pRow != NULL )
  498. *pRow = (nID - AFX_IDW_PANE_FIRST) / 16;
  499. if( pCol != NULL )
  500. *pCol = (nID - AFX_IDW_PANE_FIRST) % 16;
  501. ASSERT( pRow == NULL || *pRow < m_nRows );
  502. ASSERT( pCol == NULL || *pCol < m_nCols );
  503. return TRUE;
  504. }
  505. else
  506. {
  507. if( pRow != NULL )
  508. *pRow = -1;
  509. if( pCol != NULL )
  510. *pCol = -1;
  511. return FALSE;
  512. }
  513. }
  514. void CExtSplitterBaseWnd::GetRowInfo( int row, int & cyCur, int & cyMin) const
  515. {
  516. ASSERT_VALID( this );
  517. ASSERT( row >= 0 && row < m_nMaxRows );
  518. cyCur = m_pRowInfo[row].nCurSize;
  519. cyMin = m_pRowInfo[row].nMinSize;
  520. }
  521. void CExtSplitterBaseWnd::SetRowInfo(int row, int cyIdeal, int cyMin)
  522. {
  523. ASSERT_VALID( this );
  524. ASSERT( row >= 0 && row < m_nMaxRows );
  525. ASSERT( cyIdeal >= 0 );
  526. ASSERT( cyMin >= 0 );
  527. m_pRowInfo[row].nIdealSize = cyIdeal;
  528. m_pRowInfo[row].nMinSize = cyMin;
  529. }
  530. void CExtSplitterBaseWnd::GetColumnInfo(int col, int& cxCur, int& cxMin) const
  531. {
  532. ASSERT_VALID( this );
  533. ASSERT( col >= 0 && col < m_nMaxCols );
  534. cxCur = m_pColInfo[col].nCurSize;
  535. cxMin = m_pColInfo[col].nMinSize;
  536. }
  537. void CExtSplitterBaseWnd::SetColumnInfo(int col, int cxIdeal, int cxMin)
  538. {
  539. ASSERT_VALID( this );
  540. ASSERT( col >= 0 && col < m_nMaxCols );
  541. ASSERT( cxIdeal >= 0 );
  542. ASSERT( cxMin >= 0 );
  543. m_pColInfo[col].nIdealSize = cxIdeal;
  544. m_pColInfo[col].nMinSize = cxMin;
  545. }
  546. DWORD CExtSplitterBaseWnd::GetScrollStyle() const
  547. {
  548. DWORD dwStyle = 0;
  549. if( m_bHasHScroll )
  550. dwStyle |= WS_HSCROLL;
  551. if( m_bHasVScroll )
  552. dwStyle |= WS_VSCROLL;
  553. return dwStyle;
  554. }
  555. void CExtSplitterBaseWnd::SetScrollStyle( DWORD dwStyle )
  556. {
  557. dwStyle &= (WS_HSCROLL|WS_VSCROLL);
  558. if( GetScrollStyle() == dwStyle )
  559. return;
  560. m_bHasHScroll = (dwStyle & WS_HSCROLL) != 0;
  561. m_bHasVScroll = (dwStyle & WS_VSCROLL) != 0;
  562. CWnd * pScrollBar = NULL;
  563. for( int col = 0; col < m_nCols; col++ )
  564. {
  565. pScrollBar = GetDlgItem( AFX_IDW_HSCROLL_FIRST + col );
  566. if( pScrollBar == NULL )
  567. {
  568. if( ! CreateScrollBarCtrl( SBS_HORZ, AFX_IDW_HSCROLL_FIRST + col ) )
  569. AfxThrowResourceException();
  570. pScrollBar = GetDlgItem( AFX_IDW_HSCROLL_FIRST + col );
  571. }
  572. pScrollBar->ShowWindow( m_bHasHScroll ? SW_SHOW : SW_HIDE );
  573. }
  574. for( int row = 0; row < m_nRows; row++ )
  575. {
  576. pScrollBar = GetDlgItem( AFX_IDW_VSCROLL_FIRST + row );
  577. if( pScrollBar == NULL )
  578. {
  579. if( ! CreateScrollBarCtrl( SBS_VERT, AFX_IDW_VSCROLL_FIRST + row ) )
  580. AfxThrowResourceException();
  581. pScrollBar = GetDlgItem( AFX_IDW_VSCROLL_FIRST + row );
  582. }
  583. pScrollBar->ShowWindow( m_bHasVScroll ? SW_SHOW : SW_HIDE );
  584. }
  585. if( m_bHasVScroll && m_bHasHScroll )
  586. {
  587. pScrollBar = GetDlgItem( AFX_IDW_SIZE_BOX );
  588. if( pScrollBar == NULL )
  589. {
  590. if( ! CreateScrollBarCtrl( SBS_SIZEBOX|WS_DISABLED, AFX_IDW_SIZE_BOX ) )
  591. AfxThrowResourceException();
  592. pScrollBar = GetDlgItem( AFX_IDW_SIZE_BOX );
  593. }
  594. pScrollBar->ShowWindow( SW_SHOW );
  595. }
  596. else
  597. {
  598. pScrollBar = GetDlgItem( AFX_IDW_SIZE_BOX );
  599. if( pScrollBar != NULL )
  600. pScrollBar->DestroyWindow();
  601. }
  602. }
  603. void CExtSplitterBaseWnd::DeleteView( int row, int col )
  604. {
  605. ASSERT_VALID( this );
  606. CWnd* pPane = GetPane(row, col);
  607. ASSERT_KINDOF( CView, pPane );
  608. if( GetActivePane() == pPane )
  609. ActivateNext( FALSE );
  610. pPane->DestroyWindow();
  611. }
  612. void CExtSplitterBaseWnd::OnDrawSplitter( CDC * pDC, CExtSplitterBaseWnd::ESplitType nType, const CRect & rectArg )
  613. {
  614. nType;
  615. if( pDC == NULL )
  616. {
  617. RedrawWindow( rectArg, NULL, RDW_INVALIDATE|RDW_NOCHILDREN );
  618. return;
  619. }
  620. // ASSERT_VALID( pDC );
  621. //CRect rect = rectArg;
  622. // switch( nType )
  623. // {
  624. // case splitBorder:
  625. //#if _MFC_VER < 0x700
  626. // ASSERT( afxData.bWin4 );
  627. //#endif //_MFC_VER < 0x700
  628. // pDC->Draw3dRect( rect, afxData.clrBtnShadow, afxData.clrBtnHilite );
  629. // rect.InflateRect( -__EXT_MFC_CX_BORDER, -__EXT_MFC_CY_BORDER );
  630. // pDC->Draw3dRect( rect, afxData.clrWindowFrame, afxData.clrBtnFace );
  631. // return;
  632. // case splitIntersection:
  633. //#if _MFC_VER < 0x700
  634. // ASSERT( ! afxData.bWin4 );
  635. //#endif //_MFC_VER < 0x700
  636. // break;
  637. // case splitBox:
  638. //#if _MFC_VER < 0x700
  639. // if( afxData.bWin4 )
  640. //#endif //_MFC_VER < 0x700
  641. // {
  642. // pDC->Draw3dRect(rect, afxData.clrBtnFace, afxData.clrWindowFrame);
  643. // rect.InflateRect(-__EXT_MFC_CX_BORDER, -__EXT_MFC_CY_BORDER);
  644. // pDC->Draw3dRect(rect, afxData.clrBtnHilite, afxData.clrBtnShadow);
  645. // rect.InflateRect(-__EXT_MFC_CX_BORDER, -__EXT_MFC_CY_BORDER);
  646. // break;
  647. // }
  648. // // fall through...
  649. // case splitBar:
  650. //#if _MFC_VER < 0x700
  651. // if( ! afxData.bWin4 )
  652. // {
  653. // pDC->Draw3dRect(rect, afxData.clrBtnHilite, afxData.clrBtnShadow);
  654. // rect.InflateRect(-__EXT_MFC_CX_BORDER, -__EXT_MFC_CY_BORDER);
  655. // }
  656. //#endif //_MFC_VER < 0x700
  657. // break;
  658. // default:
  659. // ASSERT(FALSE);
  660. // break;
  661. // }
  662. //COLORREF clr = afxData.clrBtnFace;
  663. // pDC->FillSolidRect( rect, clr );
  664. }
  665. BOOL CExtSplitterBaseWnd::SplitRow( int cyBefore )
  666. {
  667. ASSERT_VALID( this );
  668. ASSERT( GetStyle() & SPLS_DYNAMIC_SPLIT );
  669. ASSERT( m_pDynamicViewClass != NULL );
  670. ASSERT( m_nRows < m_nMaxRows );
  671. cyBefore -= m_cyBorder;
  672. int rowNew = m_nRows;
  673. int cyNew = stat_CanSplitRowCol( &m_pRowInfo[rowNew-1], cyBefore, m_cySplitter );
  674. if( cyNew == -1 )
  675. return FALSE;
  676. if( m_bHasVScroll
  677. && (! CreateScrollBarCtrl( SBS_VERT, AFX_IDW_VSCROLL_FIRST + rowNew ) )
  678. )
  679. {
  680. TRACE0("Warning: SplitRow failed to create scroll bar.n");
  681. return FALSE;
  682. }
  683. m_nRows++;
  684. for( int col = 0; col < m_nCols; col++ )
  685. {
  686. CSize size( m_pColInfo[col].nCurSize, cyNew );
  687. if( ! CreateView( rowNew, col, m_pDynamicViewClass, size, NULL ) )
  688. {
  689. TRACE0("Warning: SplitRow failed to create new row.n");
  690. while( col > 0 )
  691. DeleteView( rowNew, --col );
  692. if( m_bHasVScroll )
  693. GetDlgItem( AFX_IDW_VSCROLL_FIRST + rowNew )->DestroyWindow();
  694. m_nRows--;
  695. return FALSE;
  696. }
  697. }
  698. m_pRowInfo[rowNew-1].nIdealSize = cyBefore;
  699. m_pRowInfo[rowNew].nIdealSize = cyNew;
  700. ASSERT(m_nRows == rowNew+1);
  701. RecalcLayout();
  702. return TRUE;
  703. }
  704. BOOL CExtSplitterBaseWnd::SplitColumn( int cxBefore )
  705. {
  706. ASSERT_VALID( this );
  707. ASSERT( GetStyle() & SPLS_DYNAMIC_SPLIT );
  708. ASSERT( m_pDynamicViewClass != NULL );
  709. ASSERT( m_nCols < m_nMaxCols );
  710. cxBefore -= m_cxBorder;
  711. int colNew = m_nCols;
  712. int cxNew = stat_CanSplitRowCol(&m_pColInfo[colNew-1], cxBefore, m_cxSplitter);
  713. if( cxNew == -1 )
  714. return FALSE;
  715. if( m_bHasHScroll
  716. && (! CreateScrollBarCtrl( SBS_HORZ, AFX_IDW_HSCROLL_FIRST + colNew ) )
  717. )
  718. {
  719. TRACE0("Warning: SplitRow failed to create scroll bar.n");
  720. return FALSE;
  721. }
  722. m_nCols++;
  723. for( int row = 0; row < m_nRows; row++ )
  724. {
  725. CSize size( cxNew, m_pRowInfo[row].nCurSize );
  726. if( ! CreateView( row, colNew, m_pDynamicViewClass, size, NULL ) )
  727. {
  728. TRACE0("Warning: SplitColumn failed to create new column.n");
  729. while( row > 0 )
  730. DeleteView( --row, colNew );
  731. if( m_bHasHScroll )
  732. GetDlgItem( AFX_IDW_HSCROLL_FIRST + colNew )->DestroyWindow();
  733. m_nCols--;
  734. return FALSE;
  735. }
  736. }
  737. m_pColInfo[colNew-1].nIdealSize = cxBefore;
  738. m_pColInfo[colNew].nIdealSize = cxNew;
  739. ASSERT( m_nCols == colNew+1 );
  740. RecalcLayout();
  741. return TRUE;
  742. }
  743. void CExtSplitterBaseWnd::DeleteRow(int rowDelete)
  744. {
  745. ASSERT_VALID( this );
  746. ASSERT( GetStyle() & SPLS_DYNAMIC_SPLIT );
  747. ASSERT( m_nRows > 1 );
  748. ASSERT( rowDelete < m_nRows );
  749. int rowActive, colActive;
  750. if( GetActivePane( &rowActive, &colActive ) != NULL && rowActive == rowDelete )
  751. {
  752. if( ++rowActive >= m_nRows )
  753. rowActive = 0;
  754. SetActivePane( rowActive, colActive );
  755. }
  756. CWnd * pScrollDel = m_bHasVScroll ? GetDlgItem( AFX_IDW_VSCROLL_FIRST + rowDelete ) : NULL;
  757. for( int col = 0; col < m_nCols; col++ )
  758. {
  759. DeleteView( rowDelete, col );
  760. for( int row = rowDelete+1; row < m_nRows; row++ )
  761. {
  762. CWnd * pPane = GetPane( row, col );
  763. ASSERT( pPane != NULL );
  764. pPane->SetDlgCtrlID( IdFromRowCol( row-1, col ) );
  765. if( m_bHasVScroll && col == m_nCols-1 )
  766. {
  767. CWnd * pScroll = GetDlgItem( AFX_IDW_VSCROLL_FIRST + row );
  768. if( pScroll != NULL )
  769. pScroll->SetDlgCtrlID( AFX_IDW_VSCROLL_FIRST + row - 1 );
  770. }
  771. }
  772. }
  773. m_nRows--;
  774. if( pScrollDel != NULL )
  775. pScrollDel->DestroyWindow();
  776. RecalcLayout();
  777. }
  778. void CExtSplitterBaseWnd::DeleteColumn( int colDelete )
  779. {
  780. ASSERT_VALID( this );
  781. ASSERT( GetStyle() & SPLS_DYNAMIC_SPLIT );
  782. ASSERT( m_nCols > 1 );
  783. ASSERT( colDelete < m_nCols );
  784. int rowActive, colActive;
  785. if( GetActivePane( &rowActive, &colActive ) != NULL && colActive == colDelete )
  786. {
  787. if( ++colActive >= m_nCols )
  788. colActive = 0;
  789. SetActivePane( rowActive, colActive );
  790. }
  791. CWnd * pScrollDel = m_bHasHScroll ? GetDlgItem( AFX_IDW_HSCROLL_FIRST + colDelete ) : NULL;
  792. for( int row = 0; row < m_nRows; row++ )
  793. {
  794. DeleteView( row, colDelete );
  795. for( int col = colDelete+1; col < m_nCols; col++ )
  796. {
  797. CWnd * pPane = GetPane( row, col );
  798. ASSERT( pPane != NULL );
  799. pPane->SetDlgCtrlID( IdFromRowCol( row, col-1 ) );
  800. if( m_bHasHScroll && row == m_nRows - 1 )
  801. {
  802. CWnd * pScroll = GetDlgItem( AFX_IDW_HSCROLL_FIRST + col );
  803. if( pScroll != NULL )
  804. pScroll->SetDlgCtrlID( AFX_IDW_HSCROLL_FIRST + col - 1 );
  805. }
  806. }
  807. }
  808. m_nCols--;
  809. if( pScrollDel != NULL )
  810. pScrollDel->DestroyWindow();
  811. RecalcLayout();
  812. }
  813. void CExtSplitterBaseWnd::GetInsideRect( CRect & rect ) const
  814. {
  815. ASSERT_VALID( this );
  816. GetClientRect( rect );
  817. ASSERT( rect.left == 0 && rect.top == 0 );
  818. rect.InflateRect( -m_cxBorder, -m_cyBorder );
  819. if( m_bHasVScroll )
  820. rect.right -= afxData.cxVScroll - __EXT_MFC_CX_BORDER;
  821. if( m_bHasHScroll )
  822. rect.bottom -= afxData.cyHScroll - __EXT_MFC_CY_BORDER;
  823. }
  824. void CExtSplitterBaseWnd::StartTracking( int ht )
  825. {
  826. ASSERT_VALID( this );
  827. if( ht == noHit )
  828. return;
  829. GetInsideRect( m_rectLimit );
  830. if( ht >= splitterIntersection1 && ht <= splitterIntersection225 )
  831. {
  832. int row = (ht - splitterIntersection1) / 15;
  833. int col = (ht - splitterIntersection1) % 15;
  834. GetHitRect( row + vSplitterBar1, m_rectTracker );
  835. int yTrackOffset = m_ptTrackOffset.y;
  836. m_bTracking2 = TRUE;
  837. GetHitRect( col + hSplitterBar1, m_rectTracker2 );
  838. m_ptTrackOffset.y = yTrackOffset;
  839. }
  840. else if( ht == bothSplitterBox )
  841. {
  842. GetHitRect(vSplitterBox, m_rectTracker);
  843. int yTrackOffset = m_ptTrackOffset.y;
  844. m_bTracking2 = TRUE;
  845. GetHitRect( hSplitterBox, m_rectTracker2 );
  846. m_ptTrackOffset.y = yTrackOffset;
  847. m_rectTracker.OffsetRect( 0, m_rectLimit.Height()/2 );
  848. m_rectTracker2.OffsetRect( m_rectLimit.Width()/2, 0 );
  849. }
  850. else
  851. GetHitRect(ht, m_rectTracker);
  852. CView * pView = (CView*)GetActivePane();
  853. if( pView != NULL && pView->IsKindOf( RUNTIME_CLASS( CView ) )  )
  854. {
  855. ASSERT_VALID( pView );
  856. CFrameWnd * pFrameWnd = GetParentFrame();
  857. if( pFrameWnd != NULL )
  858. {
  859. ASSERT_VALID( pFrameWnd );
  860. ((friently_view_t*)pView)->OnActivateFrame( WA_INACTIVE, pFrameWnd );
  861. }
  862. }
  863. SetCapture();
  864. SetFocus();
  865. RedrawWindow( NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW );
  866. m_bTracking = TRUE;
  867. OnInvertTracker( m_rectTracker );
  868. if( m_bTracking2 )
  869. OnInvertTracker( m_rectTracker2 );
  870. m_htTrack = ht;
  871. SetSplitCursor( ht );
  872. }
  873. void CExtSplitterBaseWnd::TrackRowSize( int y, int row )
  874. {
  875. ASSERT_VALID( this );
  876. ASSERT( m_nRows > 1 );
  877. CPoint pt( 0, y );
  878. ClientToScreen( & pt);
  879. GetPane( row, 0 )->ScreenToClient( &pt );
  880. m_pRowInfo[row].nIdealSize = pt.y;
  881. if( pt.y < m_pRowInfo[row].nMinSize )
  882. {
  883. m_pRowInfo[row].nIdealSize = 0;
  884. if( GetStyle() & SPLS_DYNAMIC_SPLIT )
  885. DeleteRow( row );
  886. }
  887. else if( m_pRowInfo[row].nCurSize + m_pRowInfo[row+1].nCurSize < pt.y + m_pRowInfo[row+1].nMinSize )
  888. {
  889. if( GetStyle() & SPLS_DYNAMIC_SPLIT )
  890. DeleteRow( row + 1 );
  891. }
  892. }
  893. void CExtSplitterBaseWnd::TrackColumnSize( int x, int col )
  894. {
  895. ASSERT_VALID( this );
  896. ASSERT(m_nCols > 1);
  897. CPoint pt(x, 0);
  898. ClientToScreen(&pt);
  899. GetPane( 0, col )->ScreenToClient( &pt );
  900. m_pColInfo[col].nIdealSize = pt.x;
  901. if( pt.x < m_pColInfo[col].nMinSize )
  902. {
  903. m_pColInfo[col].nIdealSize = 0;
  904. if( GetStyle() & SPLS_DYNAMIC_SPLIT )
  905. DeleteColumn(col);
  906. }
  907. else if( m_pColInfo[col].nCurSize + m_pColInfo[col+1].nCurSize < pt.x + m_pColInfo[col+1].nMinSize )
  908. {
  909. if( GetStyle() & SPLS_DYNAMIC_SPLIT )
  910. DeleteColumn(col + 1);
  911. }
  912. }
  913. void CExtSplitterBaseWnd::StopTracking(BOOL bAccept)
  914. {
  915. ASSERT_VALID( this );
  916. if( ! m_bTracking )
  917. return;
  918. ReleaseCapture();
  919. OnInvertTracker( m_rectTracker );
  920. if( m_bTracking2 )
  921. OnInvertTracker( m_rectTracker2 );
  922. m_bTracking = m_bTracking2 = FALSE;
  923. CWnd * pOldActiveView = GetActivePane();
  924. m_rectTracker.OffsetRect( -__EXT_MFC_CX_BORDER , -__EXT_MFC_CY_BORDER );
  925. m_rectTracker2.OffsetRect( -__EXT_MFC_CX_BORDER, -__EXT_MFC_CY_BORDER );
  926. if( bAccept )
  927. {
  928. if( m_htTrack == vSplitterBox )
  929. SplitRow( m_rectTracker.top );
  930. else if( m_htTrack >= vSplitterBar1 && m_htTrack <= vSplitterBar15 )
  931. {
  932. TrackRowSize( m_rectTracker.top, m_htTrack - vSplitterBar1 );
  933. RecalcLayout();
  934. }
  935. else if( m_htTrack == hSplitterBox )
  936. SplitColumn(m_rectTracker.left);
  937. else if( m_htTrack >= hSplitterBar1 && m_htTrack <= hSplitterBar15 )
  938. {
  939. TrackColumnSize( m_rectTracker.left, m_htTrack - hSplitterBar1 );
  940. RecalcLayout();
  941. }
  942. else if( m_htTrack >= splitterIntersection1 && m_htTrack <= splitterIntersection225 )
  943. {
  944. int row = (m_htTrack - splitterIntersection1) / 15;
  945. int col = (m_htTrack - splitterIntersection1) % 15;
  946. TrackRowSize( m_rectTracker.top, row );
  947. TrackColumnSize( m_rectTracker2.left, col );
  948. RecalcLayout();
  949. }
  950. else if( m_htTrack == bothSplitterBox )
  951. {
  952. SplitRow( m_rectTracker.top );
  953. SplitColumn( m_rectTracker2.left );
  954. }
  955. }
  956. if( pOldActiveView == GetActivePane() )
  957. {
  958. if( pOldActiveView != NULL)
  959. {
  960. SetActivePane( -1, -1, pOldActiveView );
  961. pOldActiveView->SetFocus();
  962. }
  963. }
  964. }
  965. void CExtSplitterBaseWnd::GetHitRect( int ht, CRect & rectHit )
  966. {
  967. ASSERT_VALID( this );
  968. CRect rectClient;
  969. GetClientRect( &rectClient );
  970. rectClient.InflateRect( -m_cxBorder, -m_cyBorder );
  971. int cx = rectClient.Width();
  972. int cy = rectClient.Height();
  973. int x = rectClient.top;
  974. int y = rectClient.left;
  975. m_ptTrackOffset.x = 0;
  976. m_ptTrackOffset.y = 0;
  977. if( ht == vSplitterBox )
  978. {
  979. cy =
  980. m_cySplitter - ( 2*m_cyBorder -
  981. #if _MFC_VER < 0x700
  982. afxData.bWin4
  983. #else
  984. 1
  985. #endif
  986. );
  987. m_ptTrackOffset.y = -(cy / 2);
  988. ASSERT( m_pRowInfo[0].nCurSize > 0 );
  989. m_rectLimit.bottom -= cy;
  990. }
  991. else if( ht == hSplitterBox )
  992. {
  993. cx =
  994. m_cxSplitter - ( 2*m_cxBorder -
  995. #if _MFC_VER < 0x700
  996. afxData.bWin4
  997. #else
  998. 1
  999. #endif
  1000. );
  1001. m_ptTrackOffset.x = -(cx / 2);
  1002. ASSERT( m_pColInfo[0].nCurSize > 0 );
  1003. m_rectLimit.right -= cx;
  1004. }
  1005. else if( ht >= vSplitterBar1 && ht <= vSplitterBar15 )
  1006. {
  1007. cy =
  1008. m_cySplitter - ( 2*m_cyBorder -
  1009. #if _MFC_VER < 0x700
  1010. afxData.bWin4
  1011. #else
  1012. 1
  1013. #endif
  1014. );
  1015. m_ptTrackOffset.y = -(cy / 2);
  1016. int row = 0;
  1017. for( ; row < ht - vSplitterBar1; row++ )
  1018. y += m_pRowInfo[row].nCurSize + m_cySplitterGap;
  1019. m_rectLimit.top = y;
  1020. y +=
  1021. m_pRowInfo[row].nCurSize + m_cyBorderShare +
  1022. #if _MFC_VER < 0x700
  1023. afxData.bWin4
  1024. #else
  1025. 1
  1026. #endif
  1027. ;
  1028. m_rectLimit.bottom -= cy;
  1029. }
  1030. else if( ht >= hSplitterBar1 && ht <= hSplitterBar15 )
  1031. {
  1032. cx =
  1033. m_cxSplitter - ( 2*m_cxBorder -
  1034. #if _MFC_VER < 0x700
  1035. afxData.bWin4
  1036. #else
  1037. 1
  1038. #endif
  1039. );
  1040. m_ptTrackOffset.x = -(cx / 2);
  1041. int col = 0;
  1042. for( ; col < ht - hSplitterBar1; col++ )
  1043. x += m_pColInfo[col].nCurSize + m_cxSplitterGap;
  1044. m_rectLimit.left = x;
  1045. x +=
  1046. m_pColInfo[col].nCurSize + m_cxBorderShare +
  1047. #if _MFC_VER < 0x700
  1048. afxData.bWin4
  1049. #else
  1050. 1
  1051. #endif
  1052. ;
  1053. m_rectLimit.right -= cx;
  1054. }
  1055. else
  1056. {
  1057. TRACE1("Error: GetHitRect(%d): Not Found!n", ht);
  1058. ASSERT(FALSE);
  1059. }
  1060. rectHit.right = (rectHit.left = x) + cx;
  1061. rectHit.bottom = (rectHit.top = y) + cy;
  1062. }
  1063. int CExtSplitterBaseWnd::HitTest( CPoint pt ) const
  1064. {
  1065. ASSERT_VALID( this );
  1066. CRect rectClient;
  1067. GetClientRect(&rectClient);
  1068. rectClient.InflateRect(-m_cxBorder, -m_cyBorder);
  1069. CRect rectInside;
  1070. GetInsideRect(rectInside);
  1071. if( m_bHasVScroll
  1072. && m_nRows < m_nMaxRows
  1073. && CRect(
  1074. rectInside.right,
  1075. rectClient.top,
  1076. rectClient.right,
  1077. rectClient.top + m_cySplitter -
  1078. #if _MFC_VER < 0x700
  1079. afxData.bWin4
  1080. #else
  1081. 1
  1082. #endif
  1083. ).PtInRect( pt )
  1084. )
  1085. return vSplitterBox;
  1086. if( m_bHasHScroll
  1087. && m_nCols < m_nMaxCols
  1088. && CRect(
  1089. rectClient.left,
  1090. rectInside.bottom,
  1091. rectClient.left + m_cxSplitter -
  1092. #if _MFC_VER < 0x700
  1093. afxData.bWin4
  1094. #else
  1095. 1
  1096. #endif
  1097. ,
  1098. rectClient.bottom
  1099. ).PtInRect( pt )
  1100. )
  1101. return hSplitterBox;
  1102. CRect rect;
  1103. rect = rectClient;
  1104. int col = 0;
  1105. for( ; col < m_nCols - 1; col++ )
  1106. {
  1107. rect.left += m_pColInfo[col].nCurSize;
  1108. rect.right = rect.left + m_cxSplitterGap;
  1109. if( rect.PtInRect(pt) )
  1110. break;
  1111. rect.left = rect.right;
  1112. }
  1113. rect = rectClient;
  1114. int row = 0;
  1115. for( ; row < m_nRows - 1; row++ )
  1116. {
  1117. rect.top += m_pRowInfo[row].nCurSize;
  1118. rect.bottom = rect.top + m_cySplitterGap;
  1119. if( rect.PtInRect(pt))
  1120. break;
  1121. rect.top = rect.bottom;
  1122. }
  1123. if( col != m_nCols - 1 )
  1124. {
  1125. if( row != m_nRows - 1 )
  1126. return splitterIntersection1 + row * 15 + col;
  1127. return hSplitterBar1 + col;
  1128. }
  1129. if( row != m_nRows - 1 )
  1130. return vSplitterBar1 + row;
  1131. return noHit;
  1132. }
  1133. void CExtSplitterBaseWnd::OnInvertTracker( const CRect & rect )
  1134. {
  1135. ASSERT_VALID( this );
  1136. ASSERT( ! rect.IsRectEmpty() );
  1137. //ASSERT( (GetStyle() & WS_CLIPCHILDREN ) == 0 );
  1138. CDC * pDC = GetDCEx( NULL, DCX_WINDOW|DCX_CACHE );
  1139. ASSERT( pDC != NULL );
  1140. CBrush * pBrush = CDC::GetHalftoneBrush();
  1141. HBRUSH hOldBrush = NULL;
  1142. if( pBrush != NULL)
  1143. hOldBrush = (HBRUSH)SelectObject( pDC->m_hDC, pBrush->m_hObject );
  1144. pDC->PatBlt( rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT );
  1145. if( hOldBrush != NULL )
  1146. SelectObject( pDC->m_hDC, hOldBrush );
  1147. ReleaseDC(pDC);
  1148. }
  1149. BOOL CExtSplitterBaseWnd::DoKeyboardSplit()
  1150. {
  1151. ASSERT_VALID( this );
  1152. int ht;
  1153. if( m_nRows > 1 && m_nCols > 1 )
  1154. ht = splitterIntersection1;
  1155. else if( m_nRows > 1 )
  1156. ht = vSplitterBar1;
  1157. else if( m_nCols > 1 )
  1158. ht = hSplitterBar1;
  1159. else if( m_nMaxRows > 1 && m_nMaxCols > 1 )
  1160. ht = bothSplitterBox;
  1161. else if( m_nMaxRows > 1 )
  1162. ht = vSplitterBox;
  1163. else if( m_nMaxCols > 1 )
  1164. ht = hSplitterBox;
  1165. else
  1166. return FALSE;
  1167. StartTracking( ht );
  1168. CRect rect;
  1169. rect.left = m_rectTracker.Width() / 2;
  1170. rect.top = m_rectTracker.Height() / 2;
  1171. if( m_ptTrackOffset.y != 0 )
  1172. rect.top = m_rectTracker.top;
  1173. if( m_ptTrackOffset.x != 0 )
  1174. rect.left = m_bTracking2 ? m_rectTracker2.left :m_rectTracker.left;
  1175. rect.OffsetRect( -m_ptTrackOffset.x, -m_ptTrackOffset.y );
  1176. ClientToScreen( &rect );
  1177. SetCursorPos( rect.left, rect.top );
  1178. return TRUE;
  1179. }
  1180. void CExtSplitterBaseWnd::OnDisplayChange()
  1181. {
  1182. ASSERT_VALID( this );
  1183. if( !IsIconic() && IsWindowVisible() )
  1184. RecalcLayout();
  1185. }
  1186. LRESULT CExtSplitterBaseWnd::OnNextDlgCtrl( WPARAM wParam, LPARAM lParam )
  1187. {
  1188. ASSERT_VALID( this );
  1189. if( LOWORD(lParam) != 0 )
  1190. return 1;
  1191. HWND hWndParent = ::GetParent( m_hWnd );
  1192. if( hWndParent == NULL )
  1193. return 1;
  1194. HWND hWndControl = ::GetFocus();
  1195. if( hWndControl == NULL )
  1196. return 1;
  1197. BOOL bPrevious = ( wParam != 0 ) ? TRUE : FALSE;
  1198. HWND hWndNewFocus = CExtResizableDialog::stat_GetNextItemZ( hWndParent, hWndParent, hWndControl, bPrevious );
  1199. if( hWndNewFocus != NULL )
  1200. ::SetFocus( hWndNewFocus );
  1201. return 0;
  1202. }
  1203. void CExtSplitterBaseWnd::OnSize( UINT nType, int cx, int cy )
  1204. {
  1205. ASSERT_VALID( this );
  1206. if( nType != SIZE_MINIMIZED && cx > 0 && cy > 0 )
  1207. RecalcLayout();
  1208. CSplitterWnd::OnSize( nType, cx, cy );
  1209. }
  1210. CWnd * CExtSplitterBaseWnd::GetSizingParent()
  1211. {
  1212. ASSERT_VALID( this );
  1213. #if _MFC_VER < 0x700
  1214. if( ! afxData.bWin4 )
  1215. return NULL;
  1216. #endif //_MFC_VER < 0x700
  1217. CRect rectClient;
  1218. GetClientRect(rectClient);
  1219. CWnd * pParent = this;
  1220. if( ! ( pParent->GetStyle() & WS_THICKFRAME ) )
  1221. pParent = GetParent();
  1222. ASSERT_VALID( pParent );
  1223. if( ( pParent->GetStyle() & (WS_THICKFRAME|WS_MAXIMIZE) ) == WS_THICKFRAME )
  1224. {
  1225. CRect rect;
  1226. pParent->GetClientRect( &rect );
  1227. pParent->ClientToScreen( &rect );
  1228. ScreenToClient( &rect );
  1229. if( rectClient.BottomRight() == rect.BottomRight() )
  1230. return pParent;
  1231. }
  1232. return NULL;
  1233. }
  1234. void CExtSplitterBaseWnd::RecalcLayout()
  1235. {
  1236. ASSERT_VALID( this );
  1237. ASSERT( m_nRows > 0 && m_nCols > 0 );
  1238. CRect rectClient;
  1239. GetClientRect( rectClient );
  1240. rectClient.InflateRect( -m_cxBorder, -m_cyBorder );
  1241. CRect rectInside;
  1242. GetInsideRect( rectInside );
  1243. stat_LayoutRowCol( m_pColInfo, m_nCols, rectInside.Width(), m_cxSplitterGap );
  1244. stat_LayoutRowCol( m_pRowInfo, m_nRows, rectInside.Height(), m_cySplitterGap );
  1245. AFX_SIZEPARENTPARAMS layout;
  1246. layout.hDWP = ::BeginDeferWindowPos( (m_nCols + 1) * (m_nRows + 1) + 1 );
  1247. int cx = (rectClient.right - rectInside.right) -
  1248. #if _MFC_VER < 0x700
  1249. afxData.bNotWin4
  1250. #else
  1251. 0
  1252. #endif
  1253. ;
  1254. int cy = (rectClient.bottom - rectInside.bottom) -
  1255. #if _MFC_VER < 0x700
  1256. afxData.bNotWin4
  1257. #else
  1258. 0
  1259. #endif
  1260. ;
  1261. if( m_bHasHScroll && m_bHasVScroll )
  1262. {
  1263. CWnd* pScrollBar = GetDlgItem( AFX_IDW_SIZE_BOX );
  1264. ASSERT( pScrollBar != NULL );
  1265. BOOL bSizingParent = (GetSizingParent() != NULL);
  1266. if( pScrollBar->ModifyStyle(SBS_SIZEGRIP|SBS_SIZEBOX, bSizingParent ? SBS_SIZEGRIP : SBS_SIZEBOX ) )
  1267. pScrollBar->Invalidate();
  1268. pScrollBar->EnableWindow(bSizingParent);
  1269. stat_DeferClientPos(
  1270. &layout,
  1271. pScrollBar,
  1272. rectInside.right +
  1273. #if _MFC_VER < 0x700
  1274. afxData.bNotWin4
  1275. #else
  1276. 0
  1277. #endif
  1278. ,
  1279. rectInside.bottom +
  1280. #if _MFC_VER < 0x700
  1281. afxData.bNotWin4
  1282. #else
  1283. 0
  1284. #endif
  1285. ,
  1286. cx,
  1287. cy,
  1288. TRUE
  1289. );
  1290. }
  1291. if( m_bHasHScroll )
  1292. {
  1293. int cxSplitterBox =
  1294. m_cxSplitter +
  1295. #if _MFC_VER < 0x700
  1296. afxData.bNotWin4
  1297. #else
  1298. 0
  1299. #endif
  1300. ;
  1301. int x = rectClient.left;
  1302. int y =
  1303. rectInside.bottom +
  1304. #if _MFC_VER < 0x700
  1305. afxData.bNotWin4
  1306. #else
  1307. 0
  1308. #endif
  1309. ;
  1310. for( int col = 0; col < m_nCols; col++ )
  1311. {
  1312. CWnd* pScrollBar = GetDlgItem( AFX_IDW_HSCROLL_FIRST + col );
  1313. ASSERT( pScrollBar != NULL );
  1314. int cx = m_pColInfo[col].nCurSize;
  1315. if( col == 0 && m_nCols < m_nMaxCols )
  1316. x += cxSplitterBox, cx -= cxSplitterBox;
  1317. stat_DeferClientPos( &layout, pScrollBar, x, y, cx, cy, TRUE );
  1318. x += cx + m_cxSplitterGap;
  1319. }
  1320. }
  1321. if( m_bHasVScroll )
  1322. {
  1323. int cySplitterBox =
  1324. m_cySplitter +
  1325. #if _MFC_VER < 0x700
  1326. afxData.bNotWin4
  1327. #else
  1328. 0
  1329. #endif
  1330. ;
  1331. int x =
  1332. rectInside.right +
  1333. #if _MFC_VER < 0x700
  1334. afxData.bNotWin4
  1335. #else
  1336. 0
  1337. #endif
  1338. ;
  1339. int y = rectClient.top;
  1340. for( int row = 0; row < m_nRows; row++ )
  1341. {
  1342. CWnd* pScrollBar = GetDlgItem( AFX_IDW_VSCROLL_FIRST + row );
  1343. ASSERT(pScrollBar != NULL);
  1344. int cy = m_pRowInfo[row].nCurSize;
  1345. if( row == 0 && m_nRows < m_nMaxRows )
  1346. y += cySplitterBox, cy -= cySplitterBox;
  1347. stat_DeferClientPos( &layout, pScrollBar, x, y, cx, cy, TRUE );
  1348. y += cy + m_cySplitterGap;
  1349. }
  1350. }
  1351. {
  1352. int x = rectClient.left;
  1353. for( int col = 0; col < m_nCols; col++ )
  1354. {
  1355. int cx = m_pColInfo[col].nCurSize;
  1356. int y = rectClient.top;
  1357. for( int row = 0; row < m_nRows; row++)
  1358. {
  1359. int cy = m_pRowInfo[row].nCurSize;
  1360. CWnd* pWnd = GetPane(row, col);
  1361. stat_DeferClientPos( &layout, pWnd, x, y, cx, cy, FALSE );
  1362. y += cy + m_cySplitterGap;
  1363. }
  1364. x += cx + m_cxSplitterGap;
  1365. }
  1366. }
  1367. if( layout.hDWP == NULL || !::EndDeferWindowPos( layout.hDWP ) )
  1368. TRACE0("Warning: DeferWindowPos failed - low system resources.n");
  1369. DrawAllSplitBars( NULL, rectInside.right, rectInside.bottom );
  1370. }
  1371. void CExtSplitterBaseWnd::DrawAllSplitBars( CDC* pDC, int cxInside, int cyInside )
  1372. {
  1373. ASSERT_VALID( this );
  1374. CRect rect;
  1375. GetClientRect(rect);
  1376. rect.left += m_cxBorder;
  1377. int col = 0;
  1378. for( ; col < m_nCols - 1; col++ )
  1379. {
  1380. rect.left += m_pColInfo[col].nCurSize + m_cxBorderShare;
  1381. rect.right = rect.left + m_cxSplitter;
  1382. if( rect.left > cxInside)
  1383. break;
  1384. OnDrawSplitter(pDC, splitBar, rect);
  1385. rect.left = rect.right + m_cxBorderShare;
  1386. }
  1387. GetClientRect(rect);
  1388. rect.top += m_cyBorder;
  1389. int row = 0;
  1390. for( ; row < m_nRows - 1; row++ )
  1391. {
  1392. rect.top += m_pRowInfo[row].nCurSize + m_cyBorderShare;
  1393. rect.bottom = rect.top + m_cySplitter;
  1394. if( rect.top > cyInside)
  1395. break;
  1396. OnDrawSplitter( pDC, splitBar, rect );
  1397. rect.top = rect.bottom + m_cyBorderShare;
  1398. }
  1399. #if _MFC_VER < 0x700
  1400. if( afxData.bWin4 )
  1401. #endif //_MFC_VER < 0x700
  1402. {
  1403. GetClientRect( rect );
  1404. int x = rect.left;
  1405. for( col = 0; col < m_nCols; col++)
  1406. {
  1407. int cx = m_pColInfo[col].nCurSize + 2*m_cxBorder;
  1408. if( col == m_nCols-1 && m_bHasVScroll)
  1409. cx += afxData.cxVScroll - __EXT_MFC_CX_BORDER;
  1410. int y = rect.top;
  1411. for( int row = 0; row < m_nRows; row++)
  1412. {
  1413. int cy = m_pRowInfo[row].nCurSize + 2*m_cyBorder;
  1414. if( row == m_nRows-1 && m_bHasHScroll)
  1415. cy += afxData.cyHScroll - __EXT_MFC_CY_BORDER;
  1416. OnDrawSplitter( pDC, splitBorder, CRect( x, y, x+cx, y+cy ) );
  1417. y += cy + m_cySplitterGap - 2*m_cyBorder;
  1418. }
  1419. x += cx + m_cxSplitterGap - 2*m_cxBorder;
  1420. }
  1421. }
  1422. }
  1423. void CExtSplitterBaseWnd::OnPaint()
  1424. {
  1425. ASSERT_VALID( this );
  1426. CRect rectClient;
  1427. GetClientRect( &rectClient );
  1428. CPaintDC dcPaint( this );
  1429. CExtMemoryDC dc( &dcPaint, &rectClient );
  1430. CExtPaintManager::stat_ExcludeChildAreas(
  1431. dc,
  1432. GetSafeHwnd(),
  1433. CExtPaintManager::stat_DefExcludeChildAreaCallback
  1434. );
  1435. if( ! PmBridge_GetPM()->PaintDockerBkgnd( true, dc, this ) )
  1436. {
  1437. COLORREF clrBackground = OnQueryBackgroundColor();
  1438. dc.FillSolidRect( 
  1439. &rectClient, 
  1440. ( clrBackground != COLORREF(-1L) ) 
  1441. ? clrBackground 
  1442. : PmBridge_GetPM()->GetColor( CExtPaintManager::CLR_3DFACE_OUT, this ) 
  1443. );
  1444. }
  1445. rectClient.InflateRect( -m_cxBorder, -m_cyBorder );
  1446. CRect rectInside;
  1447. GetInsideRect(rectInside);
  1448. if( m_bHasVScroll && m_nRows < m_nMaxRows )
  1449. {
  1450. OnDrawSplitter(
  1451. &dc,
  1452. splitBox,
  1453. CRect(
  1454. rectInside.right +
  1455. #if _MFC_VER < 0x700
  1456. afxData.bNotWin4
  1457. #else
  1458. 0
  1459. #endif
  1460. ,
  1461. rectClient.top, rectClient.right,
  1462. rectClient.top + m_cySplitter
  1463. )
  1464. );
  1465. }
  1466. if( m_bHasHScroll && m_nCols < m_nMaxCols )
  1467. {
  1468. OnDrawSplitter(
  1469. &dc,
  1470. splitBox,
  1471. CRect(
  1472. rectClient.left,
  1473. rectInside.bottom +
  1474. #if _MFC_VER < 0x700
  1475. afxData.bNotWin4
  1476. #else
  1477. 0
  1478. #endif
  1479. ,
  1480. rectClient.left + m_cxSplitter,
  1481. rectClient.bottom
  1482. )
  1483. );
  1484. }
  1485. DrawAllSplitBars( &dc, rectInside.right, rectInside.bottom );
  1486. #if _MFC_VER < 0x700
  1487. if( ! afxData.bWin4 )
  1488. {
  1489. GetInsideRect( rectInside );
  1490. dc.IntersectClipRect( rectInside );
  1491. CRect rect;
  1492. rect.top = rectInside.top;
  1493. for( int row = 0; row < m_nRows - 1; row++ )
  1494. {
  1495. rect.top += m_pRowInfo[row].nCurSize + m_cyBorderShare;
  1496. rect.bottom = rect.top + m_cySplitter;
  1497. rect.left = rectInside.left;
  1498. for( int col = 0; col < m_nCols - 1; col++ )
  1499. {
  1500. rect.left += m_pColInfo[col].nCurSize + m_cxBorderShare;
  1501. rect.right = rect.left + m_cxSplitter;
  1502. OnDrawSplitter(&dc, splitIntersection, rect);
  1503. rect.left = rect.right + m_cxBorderShare;
  1504. }
  1505. rect.top = rect.bottom + m_cxBorderShare;
  1506. }
  1507. }
  1508. #endif //_MFC_VER < 0x700
  1509. }
  1510. BOOL CExtSplitterBaseWnd::OnSetCursor( CWnd * pWnd, UINT nHitTest, UINT message )
  1511. {
  1512. if( nHitTest == HTCLIENT && pWnd == this && ! m_bTracking )
  1513. return TRUE;
  1514. return CSplitterWnd::OnSetCursor(pWnd, nHitTest, message);
  1515. }
  1516. void CExtSplitterBaseWnd::SetSplitCursor( int ht )
  1517. {
  1518. UINT idcPrimary;
  1519. LPCTSTR idcSecondary;
  1520. AfxLockGlobals( CRIT_SPLITTERWND );
  1521. if( ht == vSplitterBox
  1522. || ht >= vSplitterBar1
  1523. && ht <= vSplitterBar15
  1524. )
  1525. {
  1526. idcPrimary = AFX_IDC_VSPLITBAR;
  1527. idcSecondary = IDC_SIZENS;
  1528. }
  1529. else if(
  1530. ht == hSplitterBox
  1531. || ht >= hSplitterBar1
  1532. && ht <= hSplitterBar15
  1533. )
  1534. {
  1535. idcPrimary = AFX_IDC_HSPLITBAR;
  1536. idcSecondary = IDC_SIZEWE;
  1537. }
  1538. else if(
  1539. ht == bothSplitterBox
  1540. || ( ht >= splitterIntersection1 && ht <= splitterIntersection225 )
  1541. )
  1542. {
  1543. idcPrimary = AFX_IDC_SMALLARROWS;
  1544. idcSecondary = IDC_SIZEALL;
  1545. }
  1546. else
  1547. {
  1548. SetCursor( afxData.hcurArrow );
  1549. idcPrimary = 0;
  1550. idcSecondary = 0;
  1551. }
  1552. if( idcPrimary != 0 )
  1553. {
  1554. HCURSOR hcurToDestroy = NULL;
  1555. if( idcPrimary != g_split_idcPrimaryLast )
  1556. {
  1557. HINSTANCE hInst = AfxFindResourceHandle( MAKEINTRESOURCE(idcPrimary), RT_GROUP_CURSOR );
  1558. hcurToDestroy = g_split_hcurDestroy;
  1559. if( ( g_split_hcurDestroy = g_split_hcurLast = ::LoadCursor(hInst, MAKEINTRESOURCE(idcPrimary) ) ) == NULL )
  1560. {
  1561. TRACE0("Warning: Could not find splitter cursor - using system provided alternative.n");
  1562. ASSERT( g_split_hcurDestroy == NULL );
  1563. g_split_hcurLast = ::LoadCursor( NULL, idcSecondary );
  1564. ASSERT(g_split_hcurLast != NULL);
  1565. }
  1566. g_split_idcPrimaryLast = idcPrimary;
  1567. }
  1568. ASSERT(g_split_hcurLast != NULL);
  1569. ::SetCursor(g_split_hcurLast);
  1570. ASSERT(g_split_hcurLast != hcurToDestroy);
  1571. if( hcurToDestroy != NULL)
  1572. ::DestroyCursor( hcurToDestroy );
  1573. }
  1574. AfxUnlockGlobals( CRIT_SPLITTERWND );
  1575. }
  1576. void CExtSplitterBaseWnd::OnMouseMove( UINT /*nFlags*/, CPoint pt )
  1577. {
  1578. if( GetCapture() != this )
  1579. StopTracking( FALSE );
  1580. if( m_bTracking )
  1581. {
  1582. pt.Offset( m_ptTrackOffset );
  1583. if( pt.y < m_rectLimit.top )
  1584. pt.y = m_rectLimit.top;
  1585. else if( pt.y > m_rectLimit.bottom)
  1586. pt.y = m_rectLimit.bottom;
  1587. if( pt.x < m_rectLimit.left )
  1588. pt.x = m_rectLimit.left;
  1589. else if( pt.x > m_rectLimit.right )
  1590. pt.x = m_rectLimit.right;
  1591. if( m_htTrack == vSplitterBox
  1592. || m_htTrack >= vSplitterBar1 && m_htTrack <= vSplitterBar15
  1593. )
  1594. {
  1595. if( m_rectTracker.top != pt.y )
  1596. {
  1597. OnInvertTracker( m_rectTracker );
  1598. m_rectTracker.OffsetRect( 0, pt.y - m_rectTracker.top );
  1599. OnInvertTracker( m_rectTracker );
  1600. }
  1601. }
  1602. else if(
  1603. m_htTrack == hSplitterBox
  1604. || m_htTrack >= hSplitterBar1 && m_htTrack <= hSplitterBar15
  1605. )
  1606. {
  1607. if( m_rectTracker.left != pt.x)
  1608. {
  1609. OnInvertTracker(m_rectTracker);
  1610. m_rectTracker.OffsetRect(pt.x - m_rectTracker.left, 0);
  1611. OnInvertTracker(m_rectTracker);
  1612. }
  1613. }
  1614. else if(
  1615. m_htTrack == bothSplitterBox
  1616. || ( m_htTrack >= splitterIntersection1 && m_htTrack <= splitterIntersection225 )
  1617. )
  1618. {
  1619. if( m_rectTracker.top != pt.y )
  1620. {
  1621. OnInvertTracker( m_rectTracker );
  1622. m_rectTracker.OffsetRect( 0, pt.y - m_rectTracker.top );
  1623. OnInvertTracker( m_rectTracker );
  1624. }
  1625. if( m_rectTracker2.left != pt.x )
  1626. {
  1627. OnInvertTracker( m_rectTracker2 );
  1628. m_rectTracker2.OffsetRect( pt.x - m_rectTracker2.left, 0 );
  1629. OnInvertTracker( m_rectTracker2 );
  1630. }
  1631. }
  1632. }
  1633. else
  1634. {
  1635. int ht = HitTest( pt );
  1636. SetSplitCursor( ht );
  1637. }
  1638. }
  1639. void CExtSplitterBaseWnd::OnLButtonDown( UINT /*nFlags*/, CPoint pt )
  1640. {
  1641. if( m_bTracking )
  1642. return;
  1643. StartTracking( HitTest( pt ) );
  1644. }
  1645. void CExtSplitterBaseWnd::OnLButtonDblClk( UINT /*nFlags*/, CPoint pt )
  1646. {
  1647. int ht = HitTest( pt );
  1648. CRect rect;
  1649. StopTracking( FALSE );
  1650. if( ( GetStyle() & SPLS_DYNAMIC_SPLIT ) == 0 )
  1651. return;
  1652. if( ht == vSplitterBox )
  1653. SplitRow( m_pRowInfo[0].nCurSize / 2 );
  1654. else if( ht == hSplitterBox)
  1655. SplitColumn( m_pColInfo[0].nCurSize / 2 );
  1656. else if( ht >= vSplitterBar1 && ht <= vSplitterBar15 )
  1657. {
  1658. int rowDelete = ht - vSplitterBar1;
  1659. int row;
  1660. if( GetActivePane(&row, NULL) != NULL && rowDelete == row )
  1661. ++rowDelete;
  1662. DeleteRow(rowDelete);
  1663. }
  1664. else if( ht >= hSplitterBar1 && ht <= hSplitterBar15 )
  1665. {
  1666. int colDelete = ht - hSplitterBar1;
  1667. int col;
  1668. if( GetActivePane( NULL, &col ) != NULL && colDelete == col )
  1669. ++colDelete;
  1670. DeleteColumn( colDelete );
  1671. }
  1672. else if( ht >= splitterIntersection1 && ht <= splitterIntersection225 )
  1673. {
  1674. int rowDelete = (ht - splitterIntersection1) / 15;
  1675. int colDelete = (ht - splitterIntersection1) % 15;
  1676. int row, col;
  1677. if( GetActivePane(&row, &col) != NULL )
  1678. {
  1679. if( col == colDelete )
  1680. ++colDelete;
  1681. if( row == rowDelete )
  1682. ++rowDelete;
  1683. }
  1684. DeleteRow( rowDelete );
  1685. DeleteColumn( colDelete );
  1686. }
  1687. }
  1688. void CExtSplitterBaseWnd::OnLButtonUp( UINT /*nFlags*/, CPoint /*pt*/ )
  1689. {
  1690. StopTracking(TRUE);
  1691. }
  1692. void CExtSplitterBaseWnd::OnCancelMode()
  1693. {
  1694. StopTracking(FALSE);
  1695. }
  1696. void CExtSplitterBaseWnd::OnKeyDown( UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/ )
  1697. {
  1698. CPoint pt;
  1699. GetCursorPos(&pt);
  1700. int cz = GetKeyState(VK_CONTROL) < 0 ? 1 : 16;
  1701. int dx = 0;
  1702. int dy = 0;
  1703. switch( nChar )
  1704. {
  1705. case VK_ESCAPE:
  1706. StopTracking( FALSE );
  1707. return;
  1708. case VK_RETURN:
  1709. StopTracking( TRUE );
  1710. return;
  1711. case VK_LEFT:
  1712. dx = -1;
  1713. break;
  1714. case VK_RIGHT:
  1715. dx = +1;
  1716. break;
  1717. case VK_UP:
  1718. dy = -1;
  1719. break;
  1720. case VK_DOWN:
  1721. dy = +1;
  1722. break;
  1723. default:
  1724. Default();
  1725. return;
  1726. }
  1727. if( m_htTrack == vSplitterBox
  1728. || m_htTrack >= vSplitterBar1 && m_htTrack <= vSplitterBar15
  1729. )
  1730. dx = 0;
  1731. if( m_htTrack == hSplitterBox
  1732. || m_htTrack >= hSplitterBar1 && m_htTrack <= hSplitterBar15
  1733. )
  1734. dy = 0;
  1735. pt.x += dx * cz;
  1736. pt.y += dy * cz;
  1737. ScreenToClient( &pt );
  1738. if( pt.y < m_rectLimit.top )
  1739. pt.y = m_rectLimit.top;
  1740. else if( pt.y > m_rectLimit.bottom )
  1741. pt.y = m_rectLimit.bottom;
  1742. if( pt.x < m_rectLimit.left )
  1743. pt.x = m_rectLimit.left;
  1744. else if( pt.x > m_rectLimit.right )
  1745. pt.x = m_rectLimit.right;
  1746. ClientToScreen( &pt );
  1747. SetCursorPos( pt.x, pt.y );
  1748. }
  1749. void CExtSplitterBaseWnd::OnSysCommand( UINT nID, LPARAM lParam )
  1750. {
  1751. if( ( nID & 0xFFF0 ) == SC_SIZE )
  1752. {
  1753. CWnd * pParent = GetSizingParent();
  1754. if( pParent != NULL )
  1755. {
  1756. pParent->SendMessage( WM_SYSCOMMAND, (WPARAM)nID, lParam );
  1757. return;
  1758. }
  1759. }
  1760. CSplitterWnd::OnSysCommand( nID, lParam );
  1761. }
  1762. BOOL CExtSplitterBaseWnd::OnCommand( WPARAM wParam, LPARAM lParam )
  1763. {
  1764. if( CSplitterWnd::OnCommand( wParam, lParam ) )
  1765. return TRUE;
  1766. CFrameWnd * pFrameWnd = GetParentFrame();
  1767. if( pFrameWnd != NULL )
  1768. {
  1769. ASSERT_VALID( pFrameWnd );
  1770. return ( pFrameWnd->SendMessage( WM_COMMAND, wParam, lParam ) != 0L ) ? TRUE : FALSE;
  1771. }
  1772. return FALSE;
  1773. }
  1774. BOOL CExtSplitterBaseWnd::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT * pResult )
  1775. {
  1776. if( CSplitterWnd::OnNotify( wParam, lParam, pResult ) )
  1777. return TRUE;
  1778. CFrameWnd * pFrameWnd = GetParentFrame();
  1779. if( pFrameWnd != NULL )
  1780. {
  1781. ASSERT_VALID( pFrameWnd );
  1782. *pResult = pFrameWnd->SendMessage( WM_NOTIFY, wParam, lParam );
  1783. return TRUE;
  1784. }
  1785. return FALSE;
  1786. }
  1787. BOOL CExtSplitterBaseWnd::OnMouseWheel( UINT fFlags, short zDelta, CPoint point )
  1788. {
  1789. BOOL bRetVal = FALSE;
  1790. int row;
  1791. int col;
  1792. for( row = 0; row < m_nRows; row++ )
  1793. {
  1794. for( col = 0; col < m_nCols; col++ )
  1795. {
  1796. CWnd * pPane = GetPane(row, col );
  1797. CScrollView* pView = DYNAMIC_DOWNCAST( CScrollView, pPane);
  1798. if( pView != NULL)
  1799. {
  1800. CScrollBar * pBar = pView->GetScrollBarCtrl( SB_VERT );
  1801. if( pBar == NULL)
  1802. {
  1803. pBar = pView->GetScrollBarCtrl( SB_HORZ );
  1804. if( pBar == NULL)
  1805. continue;
  1806. }
  1807. int nOldPos = pBar->GetScrollPos();
  1808. if( pView->DoMouseWheel( fFlags, zDelta, point ) )
  1809. bRetVal = TRUE;
  1810. if( col < m_nCols -1 )
  1811. pBar->SetScrollPos( nOldPos, FALSE );
  1812. }
  1813. }
  1814. }
  1815. return TRUE;
  1816. }
  1817. void CExtSplitterBaseWnd::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar * pScrollBar )
  1818. {
  1819. ASSERT(pScrollBar != NULL);
  1820. int col = _AfxGetDlgCtrlID( pScrollBar->m_hWnd ) - AFX_IDW_HSCROLL_FIRST;
  1821. ASSERT( col >= 0 && col < m_nMaxCols );
  1822. ASSERT( m_nRows > 0 );
  1823. int nOldPos = pScrollBar->GetScrollPos();
  1824. #ifdef _DEBUG
  1825. int nNewPos;
  1826. #endif
  1827. for( int row = 0; row < m_nRows; row++ )
  1828. {
  1829. GetPane(row, col)->SendMessage( WM_HSCROLL, MAKELONG(nSBCode, nPos), (LPARAM)pScrollBar->m_hWnd );
  1830. #ifdef _DEBUG
  1831. if( row == 0 )
  1832. {
  1833. nNewPos = pScrollBar->GetScrollPos();
  1834. if( pScrollBar->GetScrollPos() != nNewPos )
  1835. {
  1836. TRACE0("Warning: scroll panes setting different scroll positions.n");
  1837. }
  1838. }
  1839. #endif //_DEBUG
  1840. if( row < m_nRows - 1 )
  1841. pScrollBar->SetScrollPos( nOldPos, FALSE );
  1842. }
  1843. }
  1844. void CExtSplitterBaseWnd::OnVScroll( UINT nSBCode, UINT nPos, CScrollBar * pScrollBar )
  1845. {
  1846. ASSERT( pScrollBar != NULL );
  1847. int row = _AfxGetDlgCtrlID( pScrollBar->m_hWnd ) - AFX_IDW_VSCROLL_FIRST;
  1848. ASSERT( row >= 0 && row < m_nMaxRows );
  1849. ASSERT(m_nCols > 0);
  1850. int nOldPos = pScrollBar->GetScrollPos();
  1851. #ifdef _DEBUG
  1852. int nNewPos;
  1853. #endif
  1854. for( int col = 0; col < m_nCols; col++ )
  1855. {
  1856. GetPane( row, col )->SendMessage( WM_VSCROLL, MAKELONG(nSBCode, nPos), (LPARAM)pScrollBar->m_hWnd );
  1857. #ifdef _DEBUG
  1858. if( col == 0 )
  1859. {
  1860. nNewPos = pScrollBar->GetScrollPos();
  1861. if( pScrollBar->GetScrollPos() != nNewPos )
  1862. {
  1863. TRACE0("Warning: scroll panes setting different scroll positions.n");
  1864. }
  1865. }
  1866. #endif //_DEBUG
  1867. if( col < m_nCols - 1 )
  1868. pScrollBar->SetScrollPos( nOldPos, FALSE );
  1869. }
  1870. }
  1871. BOOL CExtSplitterBaseWnd::DoScroll( CView * pViewFrom, UINT nScrollCode, BOOL bDoScroll )
  1872. {
  1873. ASSERT_VALID( pViewFrom );
  1874. int rowFrom, colFrom;
  1875. if( ! IsChildPane( pViewFrom, &rowFrom, &colFrom ) )
  1876. return FALSE;
  1877. BOOL bResult = FALSE;
  1878. int nOldVert = 0;
  1879. CScrollBar * pScrollVert = pViewFrom->GetScrollBarCtrl( SB_VERT );
  1880. if( pScrollVert != NULL)
  1881. nOldVert = pScrollVert->GetScrollPos();
  1882. int nOldHorz = 0;
  1883. CScrollBar * pScrollHorz = pViewFrom->GetScrollBarCtrl( SB_HORZ );
  1884. if( pScrollHorz != NULL )
  1885. nOldHorz = pScrollHorz->GetScrollPos();
  1886. if( pViewFrom->OnScroll(nScrollCode, 0, bDoScroll ) )
  1887. bResult = TRUE;
  1888. if( pScrollVert != NULL )
  1889. {
  1890. #ifdef _DEBUG
  1891. int nNewVert = pScrollVert->GetScrollPos();
  1892. #endif
  1893. for( int col = 0; col < m_nCols; col++ )
  1894. {
  1895. if( col == colFrom )
  1896. continue;
  1897. pScrollVert->SetScrollPos( nOldVert, FALSE );
  1898. CView * pView = (CView*)GetPane( rowFrom, col );
  1899. ASSERT_KINDOF( CView, pView );
  1900. ASSERT( pView != pViewFrom );
  1901. if( pView->OnScroll( MAKEWORD( -1, HIBYTE( nScrollCode ) ), 0, bDoScroll ) )
  1902. {
  1903. bResult = TRUE;
  1904. }
  1905. #ifdef _DEBUG
  1906. if( pScrollVert->GetScrollPos() != nNewVert )
  1907. {
  1908. TRACE0("Warning: scroll panes setting different scroll positions.n");
  1909. }
  1910. #endif
  1911. }
  1912. }
  1913. if( pScrollHorz != NULL )
  1914. {
  1915. #ifdef _DEBUG
  1916. int nNewHorz = pScrollHorz->GetScrollPos();
  1917. #endif
  1918. for( int row = 0; row < m_nRows; row++ )
  1919. {
  1920. if( row == rowFrom)
  1921. continue;
  1922. pScrollHorz->SetScrollPos( nOldHorz, FALSE );
  1923. CView * pView = (CView*)GetPane( row, colFrom );
  1924. ASSERT_KINDOF( CView, pView );
  1925. ASSERT( pView != pViewFrom );
  1926. if( pView->OnScroll( MAKEWORD( LOBYTE( nScrollCode ), -1 ), 0, bDoScroll ) )
  1927. bResult = TRUE;
  1928. #ifdef _DEBUG
  1929. if( pScrollHorz->GetScrollPos() != nNewHorz )
  1930. {
  1931. TRACE0("Warning: scroll panes setting different scroll positions.n");
  1932. }
  1933. #endif
  1934. }
  1935. }
  1936. return bResult;
  1937. }
  1938. BOOL CExtSplitterBaseWnd::DoScrollBy( CView * pViewFrom, CSize sizeScroll, BOOL bDoScroll )
  1939. {
  1940. int rowFrom, colFrom;
  1941. if( ! IsChildPane( pViewFrom, &rowFrom, &colFrom ) )
  1942. return FALSE;
  1943. BOOL bResult = FALSE;
  1944. int nOldVert = 0;
  1945. CScrollBar * pScrollVert = pViewFrom->GetScrollBarCtrl( SB_VERT );
  1946. if( pScrollVert != NULL )
  1947. nOldVert = pScrollVert->GetScrollPos();
  1948. int nOldHorz = 0;
  1949. CScrollBar * pScrollHorz = pViewFrom->GetScrollBarCtrl( SB_HORZ );
  1950. if( pScrollHorz != NULL)
  1951. nOldHorz = pScrollHorz->GetScrollPos();
  1952. if( pViewFrom->OnScrollBy( sizeScroll, bDoScroll ) )
  1953. bResult = TRUE;
  1954. if( pScrollVert != NULL )
  1955. {
  1956. #ifdef _DEBUG
  1957. int nNewVert = pScrollVert->GetScrollPos();
  1958. #endif
  1959. for( int col = 0; col < m_nCols; col++ )
  1960. {
  1961. if( col == colFrom )
  1962. continue;
  1963. pScrollVert->SetScrollPos( nOldVert, FALSE );
  1964. CView * pView = (CView*)GetPane( rowFrom, col );
  1965. ASSERT_KINDOF( CView, pView );
  1966. ASSERT( pView != pViewFrom );
  1967. if( pView->OnScrollBy( CSize( 0, sizeScroll.cy ), bDoScroll ) )
  1968. bResult = TRUE;
  1969. #ifdef _DEBUG
  1970. if( pScrollVert->GetScrollPos() != nNewVert )
  1971. {
  1972. TRACE0("Warning: scroll panes setting different scroll positions.n");
  1973. }
  1974. #endif
  1975. }
  1976. }
  1977. if( pScrollHorz != NULL )
  1978. {
  1979. #ifdef _DEBUG
  1980. int nNewHorz = pScrollHorz->GetScrollPos();
  1981. #endif
  1982. for( int row = 0; row < m_nRows; row++ )
  1983. {
  1984. if( row == rowFrom)
  1985. continue;
  1986. pScrollHorz->SetScrollPos( nOldHorz, FALSE );
  1987. CView * pView = (CView*)GetPane( row, colFrom );
  1988. ASSERT_KINDOF( CView, pView );
  1989. ASSERT( pView != pViewFrom );
  1990. if( pView->OnScrollBy( CSize( sizeScroll.cx, 0 ), bDoScroll ) )
  1991. bResult = TRUE;
  1992. #ifdef _DEBUG
  1993. if( pScrollHorz->GetScrollPos() != nNewHorz )
  1994. {
  1995. TRACE0("Warning: scroll panes setting different scroll positions.n");
  1996. }
  1997. #endif
  1998. }
  1999. }
  2000. return bResult;
  2001. }
  2002. BOOL CExtSplitterBaseWnd::CanActivateNext( BOOL )
  2003. {
  2004. ASSERT_VALID( this );
  2005. if( GetActivePane() == NULL )
  2006. {
  2007. TRACE0("Warning: Can't go to next pane - there is no current pane.n");
  2008. return FALSE;
  2009. }
  2010. ASSERT(m_nRows != 0);
  2011. ASSERT(m_nCols != 0);
  2012. return (m_nRows > 1) || (m_nCols > 1);
  2013. }
  2014. void CExtSplitterBaseWnd::ActivateNext( BOOL bPrev )
  2015. {
  2016. ASSERT_VALID( this );
  2017. int row, col;
  2018. if( GetActivePane( &row, &col ) == NULL )
  2019. {
  2020. TRACE0("Warning: Cannot go to next pane - there is no current view.n");
  2021. return;
  2022. }
  2023. ASSERT(row >= 0 && row < m_nRows);
  2024. ASSERT(col >= 0 && col < m_nCols);
  2025. if( bPrev )
  2026. {
  2027. if( --col < 0 )
  2028. {
  2029. col = m_nCols - 1;
  2030. if( --row < 0 )
  2031. row = m_nRows - 1;
  2032. }
  2033. }
  2034. else
  2035. {
  2036. if( ++col >= m_nCols )
  2037. {
  2038. col = 0;
  2039. if( ++row >= m_nRows )
  2040. row = 0;
  2041. }
  2042. }
  2043. SetActivePane( row, col );
  2044. }
  2045. void CExtSplitterBaseWnd::SetActivePane( int row, int col, CWnd * pWnd )
  2046. {
  2047. CWnd* pPane = pWnd == NULL ? GetPane(row, col) : pWnd;
  2048. if( pPane->IsKindOf( RUNTIME_CLASS( CView ) ) )
  2049. {
  2050. CFrameWnd * pFrameWnd = GetParentFrame();
  2051. if( pFrameWnd != NULL )
  2052. {
  2053. ASSERT_VALID( pFrameWnd );
  2054. pFrameWnd->SetActiveView( (CView*) pPane );
  2055. }
  2056. }
  2057. else
  2058. {
  2059. TRACE0("Warning: Next pane is not a view - calling SetFocus.n");
  2060. pPane->SetFocus();
  2061. }
  2062. }
  2063. CWnd * CExtSplitterBaseWnd::GetActivePane( int * pRow, int * pCol )
  2064. {
  2065. ASSERT_VALID( this );
  2066. CWnd * pView = NULL;
  2067. CFrameWnd * pFrameWnd = GetParentFrame();
  2068. if( pFrameWnd != NULL )
  2069. {
  2070. ASSERT_VALID( pFrameWnd );
  2071. pView = pFrameWnd->GetActiveView();
  2072. }
  2073. if( pView == NULL )
  2074. pView = GetFocus();
  2075. if( pView != NULL && (! IsChildPane( pView, pRow, pCol ) ) )
  2076. pView = NULL;
  2077. return pView;
  2078. }
  2079. /////////////////////////////////////////////////////////////////////////////
  2080. // CExtSplitterWnd
  2081. IMPLEMENT_DYNCREATE( CExtSplitterWnd, CExtSplitterBaseWnd );
  2082. CExtSplitterWnd::CExtSplitterWnd()
  2083. {
  2084. }
  2085. CExtSplitterWnd::~CExtSplitterWnd()
  2086. {
  2087. }
  2088. BEGIN_MESSAGE_MAP( CExtSplitterWnd, CExtSplitterBaseWnd )
  2089. //{{AFX_MSG_MAP(CExtSplitterWnd)
  2090. ON_WM_HSCROLL()
  2091. ON_WM_VSCROLL()
  2092. //}}AFX_MSG_MAP
  2093. END_MESSAGE_MAP()
  2094. void CExtSplitterWnd::DrawAllSplitBars(
  2095. CDC * pDC,
  2096. int cxInside,
  2097. int cyInside
  2098. )
  2099. {
  2100. if( pDC == NULL )
  2101. {
  2102. RedrawWindow( NULL, NULL, RDW_INVALIDATE|RDW_NOCHILDREN );
  2103. return;
  2104. }
  2105. ASSERT_VALID( pDC );
  2106. if( (GetStyle()&WS_CLIPCHILDREN) == 0 )
  2107. ModifyStyle( 0, WS_CLIPCHILDREN );
  2108. if( (GetStyle()&WS_CLIPSIBLINGS) == 0 )
  2109. ModifyStyle( 0, WS_CLIPSIBLINGS );
  2110. CRect rcClient;
  2111. GetClientRect( &rcClient );
  2112. CWnd * pMainFrame = NULL, * pInnerFrame = GetParentFrame();
  2113. if( pInnerFrame != NULL )
  2114. {
  2115. ASSERT_VALID( pInnerFrame );
  2116. pMainFrame = pInnerFrame->GetParentFrame();
  2117. if( pMainFrame == NULL )
  2118. pMainFrame = pInnerFrame;
  2119. }
  2120. if( pMainFrame == NULL )
  2121. {
  2122. pMainFrame = GetParent();
  2123. for( ; pMainFrame != NULL; pMainFrame = pMainFrame->GetParent() )
  2124. {
  2125. if( ( pMainFrame->GetStyle() & WS_CHILD ) == 0 )
  2126. break;
  2127. }
  2128. }
  2129. #if (!defined __EXT_MFC_NO_TAB_ONENOTE_CTRL)
  2130. bool bDrawDefault = true;
  2131. CExtTabMdiOneNoteWnd * pOneNoteTabs = NULL;
  2132. CWnd * pWnd = ( pMainFrame != NULL ) ? pMainFrame->GetWindow( GW_CHILD ) : NULL;
  2133. for( ; pWnd != NULL; pWnd = pWnd->GetWindow( GW_HWNDNEXT ) )
  2134. {
  2135. pOneNoteTabs =
  2136. DYNAMIC_DOWNCAST(
  2137. CExtTabMdiOneNoteWnd,
  2138. pWnd
  2139. );
  2140. if( pOneNoteTabs != NULL )
  2141. break;
  2142. } // for( ; pWnd != NULL; pWnd = pWnd->GetWindow( GW_HWNDNEXT ) )
  2143. if( pOneNoteTabs != NULL )
  2144. {
  2145. bDrawDefault = false;
  2146. LONG nIndex = ( pInnerFrame != NULL ) ? pOneNoteTabs->ItemFindByHWND( pInnerFrame->m_hWnd ) : -1L;
  2147. // ASSERT( nIndex >= 0 );
  2148. if( nIndex >= 0 )
  2149. {
  2150. CExtTabOneNoteWnd::TAB_ITEM_INFO_ONENOTE * pTII =
  2151. pOneNoteTabs->ItemGet( nIndex );
  2152. COLORREF clrFill = pTII->GetColorBkDark();
  2153. pDC->FillSolidRect( rcClient, clrFill );
  2154. }
  2155. } // if( pOneNoteTabs != NULL )
  2156. if( bDrawDefault )
  2157. #endif
  2158. if( pMainFrame != NULL )
  2159. { // block
  2160. CExtPaintManager * pPM = PmBridge_GetPM();
  2161. ASSERT_VALID( pPM );
  2162. CRect rcWnd;
  2163. pMainFrame->GetWindowRect( &rcWnd );
  2164. ScreenToClient( &rcWnd );
  2165. if( pPM->m_clrForceSplitterBk != COLORREF(-1L) )
  2166. {
  2167. pDC->FillSolidRect( rcClient, pPM->m_clrForceSplitterBk );
  2168. return;
  2169. }
  2170. else if( (! pPM->GetCb2DbTransparentMode(this) )
  2171. || (! pPM->PaintDockerBkgnd(
  2172. true,
  2173. *pDC,
  2174. rcClient,
  2175. rcWnd
  2176. )
  2177. )
  2178. )
  2179. {
  2180. COLORREF clrFill =
  2181. pPM->GetColor( CExtPaintManager::CLR_3DFACE_OUT );
  2182. pDC->FillSolidRect( rcClient, clrFill );
  2183. }
  2184. //  else
  2185. //  return;
  2186. } // block
  2187. CExtSplitterBaseWnd::DrawAllSplitBars(
  2188. pDC,
  2189. cxInside,
  2190. cyInside
  2191. );
  2192. }
  2193. void CExtSplitterWnd::OnDrawSplitter(
  2194. CDC* pDC,
  2195. ESplitType nType,
  2196. const CRect & rectArg
  2197. )
  2198. {
  2199. if( pDC == NULL )
  2200. {
  2201. RedrawWindow( rectArg, NULL, RDW_INVALIDATE|RDW_NOCHILDREN );
  2202. return;
  2203. }
  2204. ASSERT_VALID( pDC );
  2205. CRect rect = rectArg;
  2206. switch( nType )
  2207. {
  2208. case splitBorder:
  2209. {
  2210. CExtPaintManager * pPM = PmBridge_GetPM();
  2211. ASSERT_VALID( pPM );
  2212. if( pPM->m_clrForceSplitterBk != COLORREF(-1L) )
  2213. pDC->FillSolidRect( rect, pPM->m_clrForceSplitterBk );
  2214. rect.InflateRect( -__EXT_MFC_CX_BORDER, -__EXT_MFC_CY_BORDER );
  2215. PmBridge_GetPM()->PaintResizableBarChildNcAreaRect(
  2216. *pDC,
  2217. rect,
  2218. this
  2219. );
  2220. }
  2221. return;
  2222. case splitIntersection:
  2223. case splitBox:
  2224. case splitBar:
  2225. {
  2226. CExtPaintManager * pPM = PmBridge_GetPM();
  2227. ASSERT_VALID( pPM );
  2228. if( pPM->m_clrForceSplitterBk != COLORREF(-1L) )
  2229. pDC->FillSolidRect( rect, pPM->m_clrForceSplitterBk );
  2230. }
  2231. return;
  2232. default:
  2233. ASSERT(FALSE);  // unknown splitter type
  2234. break;
  2235. } // switch( nType )
  2236. }
  2237. void CExtSplitterWnd::OnInvertTracker(
  2238. const CRect & rect
  2239. )
  2240. {
  2241. ASSERT_VALID( this );
  2242. ASSERT( ! rect.IsRectEmpty() );
  2243. CRect rc = rect;
  2244. CWnd * pWndParent = GetParent();
  2245. ClientToScreen( &rc );
  2246. pWndParent->ScreenToClient( &rc );
  2247. //CDC * pDC = pWndParent->GetDC();
  2248. CDC * pDC = pWndParent->GetDCEx( NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE | DCX_CLIPSIBLINGS );
  2249. CBrush * pBrush = CDC::GetHalftoneBrush();
  2250. HBRUSH hOldBrush = NULL;
  2251. if( pBrush != NULL )
  2252. hOldBrush = (HBRUSH)SelectObject( pDC->m_hDC, pBrush->m_hObject );
  2253. pDC->PatBlt( rc.left, rc.top, rc.Width(), rc.Height(), PATINVERT );
  2254. if( hOldBrush != NULL )
  2255. SelectObject( pDC->m_hDC, hOldBrush );
  2256. ReleaseDC( pDC );
  2257. }
  2258. BOOL CExtSplitterWnd::CreateScrollBarCtrl( DWORD dwStyle, UINT nID )
  2259. {
  2260. ASSERT_VALID( this );
  2261. ASSERT( m_hWnd != NULL );
  2262. if( (dwStyle&SBS_SIZEBOX) != 0 )
  2263. return CExtSplitterBaseWnd::CreateScrollBarCtrl( dwStyle, nID );
  2264. CExtScrollBar * pExtScrollBar = new CExtScrollBar;
  2265. pExtScrollBar->m_bAutoDeleteOnPostNcDestroy = true;
  2266. pExtScrollBar->m_bReflectParentSizing = false;
  2267. pExtScrollBar->m_bHelperLightAccent = false;
  2268. if( ! pExtScrollBar->Create(
  2269. dwStyle|WS_VISIBLE|WS_CHILD,
  2270. CRect(0,0,1,1),
  2271. this,
  2272. nID
  2273. )
  2274. )
  2275. return FALSE;
  2276. HWND hWnd = pExtScrollBar->GetSafeHwnd();
  2277. //HWND hWnd =
  2278. // ::CreateWindow(
  2279. // _T("SCROLLBAR"), NULL,
  2280. // dwStyle|WS_VISIBLE|WS_CHILD,
  2281. // 0,
  2282. // 0,
  2283. // 1,
  2284. // 1,
  2285. // m_hWnd, 
  2286. // (HMENU)nID,
  2287. // AfxGetInstanceHandle(),
  2288. // NULL
  2289. // );
  2290. #ifdef _DEBUG
  2291. if( hWnd == NULL )
  2292. TRACE1(
  2293. "Warning: Window creation failed: GetLastError returns 0x%8.8Xn",
  2294. GetLastError()
  2295. );
  2296. #endif
  2297. return ( hWnd != NULL ) ? TRUE : FALSE;
  2298. }
  2299. void CExtSplitterWnd::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
  2300. {
  2301. ASSERT( pScrollBar != NULL );
  2302. if( ! pScrollBar->IsKindOf( RUNTIME_CLASS(CExtScrollBar) ) )
  2303. {
  2304. CExtSplitterBaseWnd::OnHScroll( nSBCode, nPos, pScrollBar );
  2305. return;
  2306. }
  2307. int col = _AfxGetDlgCtrlID( pScrollBar->m_hWnd ) - AFX_IDW_HSCROLL_FIRST;
  2308. ASSERT( col >= 0 && col < m_nMaxCols );
  2309. ASSERT( m_nRows > 0 );
  2310. int nOldPos = pScrollBar->GetScrollPos();
  2311. #ifdef _DEBUG
  2312. int nNewPos;
  2313. #endif
  2314. for( int row = 0; row < m_nRows; row++ )
  2315. {
  2316. GetPane( row, col ) ->
  2317. SendMessage(
  2318. WM_HSCROLL,
  2319. MAKELONG( nSBCode, nPos ),
  2320. (LPARAM)pScrollBar->m_hWnd
  2321. );
  2322. #ifdef _DEBUG
  2323. if( row == 0 )
  2324. {
  2325. nNewPos = pScrollBar->GetScrollPos();
  2326. if( pScrollBar->GetScrollPos() != nNewPos )
  2327. {
  2328. TRACE0( "Warning: scroll panes setting different scroll positions.n" );
  2329. } // if( pScrollBar->GetScrollPos() != nNewPos )
  2330. } // if( row == 0 )
  2331. #endif //_DEBUG
  2332. if( row < ( m_nRows - 1 ) )
  2333. pScrollBar->SetScrollPos( nOldPos, FALSE );
  2334. //((CExtScrollBar*)pScrollBar)->_SetScrollPos( nOldPos, false, false );
  2335. } // for( int row = 0; row < m_nRows; row++ )
  2336. }
  2337. void CExtSplitterWnd::OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
  2338. {
  2339. ASSERT( pScrollBar != NULL );
  2340. if( ! pScrollBar->IsKindOf( RUNTIME_CLASS(CExtScrollBar) ) )
  2341. {
  2342. CExtSplitterBaseWnd::OnHScroll( nSBCode, nPos, pScrollBar );
  2343. return;
  2344. }
  2345. int row = _AfxGetDlgCtrlID( pScrollBar->m_hWnd ) - AFX_IDW_VSCROLL_FIRST;
  2346. ASSERT( row >= 0 && row < m_nMaxRows );
  2347. ASSERT( m_nCols > 0 );
  2348. int nOldPos = pScrollBar->GetScrollPos();
  2349. #ifdef _DEBUG
  2350. int nNewPos;
  2351. #endif
  2352. for( int col = 0; col < m_nCols; col++ )
  2353. {
  2354. GetPane( row, col ) ->
  2355. SendMessage(
  2356. WM_VSCROLL,
  2357. MAKELONG( nSBCode, nPos ),
  2358. (LPARAM)pScrollBar->m_hWnd
  2359. );
  2360. #ifdef _DEBUG
  2361. if( col == 0 )
  2362. {
  2363. nNewPos = pScrollBar->GetScrollPos();
  2364. if( pScrollBar->GetScrollPos() != nNewPos )
  2365. {
  2366. TRACE0("Warning: scroll panes setting different scroll positions.n");
  2367. } // if( pScrollBar->GetScrollPos() != nNewPos )
  2368. } // if( col == 0 )
  2369. #endif //_DEBUG
  2370. if( col < ( m_nCols - 1 ) )
  2371. pScrollBar->SetScrollPos( nOldPos, FALSE );
  2372. //((CExtScrollBar*)pScrollBar)->_SetScrollPos( nOldPos, false, false );
  2373. } // for( int col = 0; col < m_nCols; col++ )
  2374. }
  2375. #endif // (!defined __EXT_MFC_NO_SPLITTER_WND)