We fixed 3 issues related to the multi row MDI tabs. Please update the source code for the following methods:
1) The repainting issue in the CExtTMWI::_SyncAllItems()
method:
bool CExtTabWnd::_RecalcLayoutImpl()
{
ASSERT_VALID( this );
if( GetSafeHwnd() == NULL || ( ! ::IsWindow(GetSafeHwnd()) ) )
return true;
if( ! m_bDelayRecalcLayout )
return true;
m_bDelayRecalcLayout = false;
m_rcTabItemsArea.SetRectEmpty();
m_rcTabNearBorderArea.SetRectEmpty();
m_nIndexVisFirst = m_nIndexVisLast = -1;
CRect rcClient;
_RecalcLayout_GetClientRect( rcClient );
if( rcClient.IsRectEmpty()
|| rcClient.right <= rcClient.left
|| rcClient.bottom <= rcClient.top
)
return true;
m_rcTabItemsArea = rcClient;
DWORD dwOrientation = OrientationGet();
bool bHorz = OrientationIsHorizontal();
CWindowDC dcMeasure( this );
LONG nTabAreaMetric = 0;
bool bMultiRowColumn = OnTabWndQueryMultiRowColumnLayout();
LONG nItemCount = ItemGetCount();
DWORD dwTabWndStyle = GetTabWndStyle();
bool bEqualWidth = (dwTabWndStyle&__ETWS_EQUAL_WIDTHS) ? true : false;
bool bEnableScrollButtons = ! bEqualWidth;
bool bGrouped = (dwTabWndStyle&__ETWS_GROUPED) ? true : false;
bool bGroupedExpandItems = (dwTabWndStyle&__ETWS_GROUPED_EXPAND_ITEMS) ? true : false;
int nPartExtent = 0;
int nPartCrossExtent = 0;
int nMaxAvailPartExtent = 0;
int nPartDistance = 0;
if( bMultiRowColumn )
{
nPartDistance = OnTabWndQueryMultiRowColumnDistance();
CSize _sizeButton = OnTabWndCalcButtonSize( dcMeasure, 20 );
ASSERT( _sizeButton.cx > 0 && _sizeButton.cy > 0 );
INT nButtonExtent = bHorz ? _sizeButton.cx : _sizeButton.cy;
INT nBetweenButtonExtent = bHorz ? __EXTTAB_BETWEEN_BTN_GAP_DX : __EXTTAB_BETWEEN_BTN_GAP_DY;
int nButtonsPreCalcExtent = OnTabWndButtonsCalcWidth( nButtonExtent, nBetweenButtonExtent );
bEnableScrollButtons = false;
m_nItemsExtent = m_nScrollMaxPos = 0;
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
nMaxAvailPartExtent = rcClient.Width();
m_rcTabItemsArea.bottom = m_rcTabItemsArea.top;
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
nMaxAvailPartExtent = rcClient.Height();
m_rcTabItemsArea.right = m_rcTabItemsArea.left;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( dwOrientation )
nMaxAvailPartExtent -= nButtonsPreCalcExtent;
} // if( bMultiRowColumn )
else
{
if( bGrouped )
m_nItemsExtent = m_nScrollMaxPos = 10;
else
m_nItemsExtent = m_nScrollMaxPos = 0;
} // else from if( bMultiRowColumn )
if( bGrouped )
bEqualWidth = false;
INT nVisibleNo = 0;
LONG nIndex = 0;
TAB_ITEM_INFO * pTiiLV = NULL;
for( nIndex = 0; nIndex < nItemCount; )
{ // compute extent of items
TAB_ITEM_INFO * pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
pTii->MultiRowWrapSet( false );
if( bGrouped )
{
if( ! pTii->VisibleGet() )
{
nIndex++;
continue;
}
if( ! bGroupedExpandItems )
{
INT nMaxInGroupExtent = 0;
INT nNormalGroupItemExtent = 0;
INT nGroupStartIndex = nIndex;
INT nCountInGroup = 0;
for( nCountInGroup = 0; true ; )
{
CSize _size = pTii->Measure( &dcMeasure );
CSize _sizeText = pTii->GetLastMeasuredTextSize();
CSize _sizeIcon = pTii->GetLastMeasuredIconSize();
bool bGroupStart = (nVisibleNo == 0) || pTii->GroupStartGet();
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
{
nMaxInGroupExtent = max( nMaxInGroupExtent, _size.cx );
INT nGroupItemExtent =
_size.cx
- _sizeText.cx
- ((_sizeIcon.cx > 0) ? __EXTTAB_MARGIN_ICON2TEXT_X : 0)
;
nNormalGroupItemExtent = max( nNormalGroupItemExtent, nGroupItemExtent );
if( nVisibleNo != 0 && bGroupStart )
m_nItemsExtent += __EXTTAB_BETWEEN_GROUP_GAP_DX;
nTabAreaMetric = max( nTabAreaMetric, _size.cy );
}
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
{
nMaxInGroupExtent = max( nMaxInGroupExtent, _size.cy );
INT nGroupItemExtent =
_size.cy
- _sizeText.cx
- ((_sizeIcon.cy > 0) ? __EXTTAB_MARGIN_ICON2TEXT_Y : 0)
;
nNormalGroupItemExtent = max( nNormalGroupItemExtent, nGroupItemExtent );
if( nVisibleNo != 0 && bGroupStart )
m_nItemsExtent += __EXTTAB_BETWEEN_GROUP_GAP_DY;
nTabAreaMetric = max( nTabAreaMetric, _size.cx );
}
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( dwOrientation )
nIndex++;
nVisibleNo++;
nCountInGroup++;
ASSERT( nIndex <= nItemCount );
if( nIndex == nItemCount )
break;
pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
if( pTii->GroupStartGet() )
break;
} // for( nCountInGroup = 0; true ; )
ASSERT( nCountInGroup >= 1 );
INT nGroupExtent =
nMaxInGroupExtent
+ nNormalGroupItemExtent * (nCountInGroup-1);
m_nItemsExtent += nGroupExtent;
for( INT n = 0; n < nCountInGroup; n++ )
{ // reset in group minimal sizes
pTii = ItemGet( nGroupStartIndex + n );
ASSERT_VALID( pTii );
bool bInGroupActive = pTii->InGroupActiveGet();
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
if( bInGroupActive )
pTii->m_sizeLastMeasuredItem.cx = nMaxInGroupExtent;
else
pTii->m_sizeLastMeasuredItem.cx = nNormalGroupItemExtent;
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
if( bInGroupActive )
pTii->m_sizeLastMeasuredItem.cy = nMaxInGroupExtent;
else
pTii->m_sizeLastMeasuredItem.cy = nNormalGroupItemExtent;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( dwOrientation )
} // reset in group minimal sizes
} // if( ! bGroupedExpandItems )
else
{
CSize _size = pTii->Measure( &dcMeasure );
bool bGroupStart = (nVisibleNo == 0) || pTii->GroupStartGet();
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
m_nItemsExtent += _size.cx;
nTabAreaMetric = max( nTabAreaMetric, _size.cy );
if( nVisibleNo != 0 && bGroupStart )
m_nItemsExtent += __EXTTAB_BETWEEN_GROUP_GAP_DX;
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
m_nItemsExtent += _size.cy;
nTabAreaMetric = max( nTabAreaMetric, _size.cx );
if( nVisibleNo != 0 && bGroupStart )
m_nItemsExtent += __EXTTAB_BETWEEN_GROUP_GAP_DY;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( dwOrientation )
nIndex++;
nVisibleNo++;
} // else from if( ! bGroupedExpandItems )
} // if( bGrouped )
else
{
CSize _size( 0, 0 );
if( pTii->VisibleGet() )
_size = pTii->Measure( &dcMeasure );
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
if( bMultiRowColumn )
{
int nTestPartExtent = nPartExtent + _size.cx;
if( nTestPartExtent > nMaxAvailPartExtent /*|| nIndex == (nItemCount-1)*/ )
{
nPartCrossExtent = max( nPartCrossExtent, _size.cy );
nPartCrossExtent += nPartDistance;
m_nItemsExtent = max( m_nItemsExtent, nPartCrossExtent );
m_rcTabItemsArea.bottom += nPartCrossExtent;
nPartExtent = _size.cx;
nPartCrossExtent = _size.cy;
if( pTiiLV != NULL )
pTiiLV->MultiRowWrapSet();
else
pTii->MultiRowWrapSet();
}
else
{
nPartExtent += _size.cx;
nPartCrossExtent = max( nPartCrossExtent, _size.cy );
m_nItemsExtent = max( m_nItemsExtent, nPartCrossExtent );
}
if( nIndex == (nItemCount-1) )
{
m_nItemsExtent = max( m_nItemsExtent, nPartCrossExtent );
m_rcTabItemsArea.bottom += nPartCrossExtent;
}
} // if( bMultiRowColumn )
else
{
if( ! pTii->VisibleGet() )
{
nIndex++;
continue;
}
m_nItemsExtent += _size.cx;
nTabAreaMetric = max( nTabAreaMetric, _size.cy );
} // else from if( bMultiRowColumn )
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
if( bMultiRowColumn )
{
int nTestPartExtent = nPartExtent + _size.cy;
if( nTestPartExtent > nMaxAvailPartExtent /*|| nIndex == (nItemCount-1)*/ )
{
nPartCrossExtent = max( nPartCrossExtent, _size.cx );
m_nItemsExtent = max( m_nItemsExtent, nPartCrossExtent );
nPartCrossExtent += nPartDistance;
m_rcTabItemsArea.right += nPartCrossExtent;
nPartExtent = _size.cy;
nPartCrossExtent = _size.cx;
if( pTiiLV != NULL )
pTiiLV->MultiRowWrapSet();
else
pTii->MultiRowWrapSet();
}
else
{
nPartExtent += _size.cy;
nPartCrossExtent = max( nPartCrossExtent, _size.cx );
m_nItemsExtent = max( m_nItemsExtent, nPartCrossExtent );
}
if( nIndex == (nItemCount-1) )
{
m_nItemsExtent = max( m_nItemsExtent, nPartCrossExtent );
m_rcTabItemsArea.right += nPartCrossExtent;
}
} // if( bMultiRowColumn )
else
{
if( ! pTii->VisibleGet() )
{
nIndex++;
continue;
}
m_nItemsExtent += _size.cy;
nTabAreaMetric = max( nTabAreaMetric, _size.cx );
} // else from if( bMultiRowColumn )
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( dwOrientation )
nIndex++;
nVisibleNo++;
} // else from if( bGrouped )
if( pTii->VisibleGet() )
pTiiLV = pTii;
} // compute extent of items
LONG nSpaceBefore = 0, nSpaceAfter = 0, nSpaceOver = 0;
OnTabWndMeasureItemAreaMargins( nSpaceBefore, nSpaceAfter, nSpaceOver );
LONG nAddShiftForBtns = nSpaceAfter;
// pre-compute button size
CSize _sizeButton = OnTabWndCalcButtonSize( dcMeasure, nTabAreaMetric );
ASSERT( _sizeButton.cx > 0 && _sizeButton.cy > 0 );
INT nButtonExtent = bHorz ? _sizeButton.cx : _sizeButton.cy;
INT nBetweenButtonExtent = bHorz ? __EXTTAB_BETWEEN_BTN_GAP_DX : __EXTTAB_BETWEEN_BTN_GAP_DY;
nSpaceAfter += OnTabWndButtonsCalcWidth( nButtonExtent, nBetweenButtonExtent );
LONG nItemRectStartPos = 0;
LONG nItemRectOffs = 0;
// compute tab window areas
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
nTabAreaMetric = max( nTabAreaMetric, __EXTTAB_MIN_HORZ_HEIGHT );
if( ! bMultiRowColumn )
{
m_rcTabItemsArea.top += nSpaceOver;
m_rcTabItemsArea.bottom =
m_rcTabItemsArea.top + nTabAreaMetric;
m_rcTabItemsArea.bottom =
min( m_rcTabItemsArea.bottom, rcClient.bottom );
if( m_rcTabItemsArea.bottom < rcClient.bottom )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.top = m_rcTabItemsArea.bottom;
}
m_rcTabItemsArea.left += nSpaceBefore;
m_rcTabItemsArea.right -= nSpaceAfter;
nItemRectOffs += m_rcTabItemsArea.top;
m_nScrollMaxPos = m_nItemsExtent - m_rcTabItemsArea.Width();
if( m_nScrollMaxPos < 0 )
m_nScrollMaxPos = 0;
}
else
{
m_rcTabItemsArea.top += nSpaceOver;
m_rcTabItemsArea.bottom += nSpaceOver;
m_rcTabItemsArea.left += nSpaceBefore;
m_rcTabItemsArea.right -= nSpaceAfter;
nItemRectOffs += nSpaceOver;
if( m_rcTabItemsArea.bottom < rcClient.bottom )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.top = m_rcTabItemsArea.bottom;
}
}
break;
case __ETWS_ORIENT_BOTTOM:
nTabAreaMetric = max( nTabAreaMetric, __EXTTAB_MIN_HORZ_HEIGHT );
if( ! bMultiRowColumn )
{
m_rcTabItemsArea.bottom -= nSpaceOver;
m_rcTabItemsArea.top =
m_rcTabItemsArea.bottom - nTabAreaMetric;
m_rcTabItemsArea.top =
max( m_rcTabItemsArea.top, rcClient.top );
if( m_rcTabItemsArea.top > rcClient.top )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.bottom = m_rcTabItemsArea.top;
}
m_rcTabItemsArea.left += nSpaceBefore;
m_rcTabItemsArea.right -= nSpaceAfter;
nItemRectOffs += m_rcTabItemsArea.top;
m_nScrollMaxPos = m_nItemsExtent - m_rcTabItemsArea.Width();
if( m_nScrollMaxPos < 0 )
m_nScrollMaxPos = 0;
}
else
{
m_rcTabItemsArea.top += nSpaceOver;
m_rcTabItemsArea.bottom += nSpaceOver;
m_rcTabItemsArea.left += nSpaceBefore;
m_rcTabItemsArea.right -= nSpaceAfter;
nItemRectOffs += nSpaceOver;
if( m_rcTabItemsArea.top > rcClient.top )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.bottom = m_rcTabItemsArea.top;
}
}
break;
case __ETWS_ORIENT_LEFT:
nTabAreaMetric =
max( nTabAreaMetric, __EXTTAB_MIN_VERT_WIDTH );
if( ! bMultiRowColumn )
{
m_rcTabItemsArea.left += nSpaceOver;
m_rcTabItemsArea.right =
m_rcTabItemsArea.left + nTabAreaMetric;
m_rcTabItemsArea.right =
min( m_rcTabItemsArea.right, rcClient.right );
if( m_rcTabItemsArea.right < rcClient.right )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.left = m_rcTabItemsArea.right;
}
m_rcTabItemsArea.top += nSpaceBefore;
m_rcTabItemsArea.bottom -= nSpaceAfter;
nItemRectOffs += m_rcTabItemsArea.left;
m_nScrollMaxPos = m_nItemsExtent - m_rcTabItemsArea.Height();
if( m_nScrollMaxPos < 0 )
m_nScrollMaxPos = 0;
}
else
{
m_rcTabItemsArea.left += nSpaceOver;
m_rcTabItemsArea.right += nSpaceOver;
m_rcTabItemsArea.top += nSpaceBefore;
m_rcTabItemsArea.bottom -= nSpaceAfter;
nItemRectOffs += nSpaceOver;
if( m_rcTabItemsArea.right < rcClient.right )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.left = m_rcTabItemsArea.right;
}
}
break;
case __ETWS_ORIENT_RIGHT:
nTabAreaMetric =
max( nTabAreaMetric, __EXTTAB_MIN_VERT_WIDTH );
if( ! bMultiRowColumn )
{
m_rcTabItemsArea.right -= nSpaceOver;
m_rcTabItemsArea.left =
m_rcTabItemsArea.right - nTabAreaMetric;
m_rcTabItemsArea.left =
max( m_rcTabItemsArea.left, rcClient.left );
if( m_rcTabItemsArea.left > rcClient.left )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.right = m_rcTabItemsArea.left;
}
m_rcTabItemsArea.top += nSpaceBefore;
m_rcTabItemsArea.bottom -= nSpaceAfter;
nItemRectOffs += m_rcTabItemsArea.left;
m_nScrollMaxPos = m_nItemsExtent - m_rcTabItemsArea.Height();
if( m_nScrollMaxPos < 0 )
m_nScrollMaxPos = 0;
}
else
{
m_rcTabItemsArea.left += nSpaceOver;
m_rcTabItemsArea.right += nSpaceOver;
m_rcTabItemsArea.top += nSpaceBefore;
m_rcTabItemsArea.bottom -= nSpaceAfter;
nItemRectOffs += nSpaceOver;
if( m_rcTabItemsArea.left > rcClient.left )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.right = m_rcTabItemsArea.left;
}
}
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( dwOrientation )
if( ! bMultiRowColumn )
{
ASSERT( m_nScrollPos >= 0 );
ASSERT( m_nScrollMaxPos >= 0 );
if( m_nScrollPos > m_nScrollMaxPos )
m_nScrollPos = m_nScrollMaxPos;
}
else
m_nScrollPos = m_nScrollMaxPos = 0;
LONG nEqualItemExtent = bHorz ? __EXTTAB_MIN_HORZ_WIDTH : __EXTTAB_MIN_VERT_HEIGHT;
bool bCancelEqualWidth = false;
if( bEqualWidth && m_nVisibleItemCount > 0 )
{
if( ! _IsScrollAvail() )
{
if( (m_dwTabWndStyle & __ETWS_FULL_WIDTH) == 0 )
bCancelEqualWidth = true;
}
if( ! bCancelEqualWidth )
{
INT nTestExtent = bHorz ? m_rcTabItemsArea.Width() : m_rcTabItemsArea.Height();
nTestExtent /= m_nVisibleItemCount;
nEqualItemExtent = max( nTestExtent, nEqualItemExtent );
}
} // if( bEqualWidth && m_nVisibleItemCount > 0 )
CRect rcButton( m_rcTabItemsArea );
if( bHorz )
rcButton.right = rcClient.right - nAddShiftForBtns;
else
rcButton.bottom = rcClient.bottom - nAddShiftForBtns;
rcButton.OffsetRect(
bHorz ? 0 : (m_rcTabItemsArea.Width() - _sizeButton.cx) / 2,
bHorz ? (m_rcTabItemsArea.Height() - _sizeButton.cy) / 2 : 0
);
rcButton.OffsetRect(
bHorz ? (-nBetweenButtonExtent) : 0,
bHorz ? 0 : (-nBetweenButtonExtent)
);
if( bHorz )
{
rcButton.left = rcButton.right - _sizeButton.cx;
rcButton.bottom = rcButton.top + _sizeButton.cy;
}
else
{
rcButton.right = rcButton.left + _sizeButton.cx;
rcButton.top = rcButton.bottom - _sizeButton.cy;
}
OnTabWndButtonsRecalcLayout( rcButton, nButtonExtent, nBetweenButtonExtent );
m_nIndexVisFirst = -1;
m_nIndexVisLast = -1;
nVisibleNo = 0;
m_bEnableTrackToolTips = false;
if( bMultiRowColumn )
{
int nCurSel = SelectionGet(), nSelRangeStart = -1, nSelRangeEnd = -1;
if( nCurSel >= 0 )
{
TAB_ITEM_INFO * pTii = ItemGet( nCurSel );
ASSERT_VALID( pTii );
if( pTii->VisibleGet() )
{
nSelRangeStart = nSelRangeEnd = nCurSel;
for( nIndex = nCurSel; nIndex < nItemCount; nIndex ++ )
{
TAB_ITEM_INFO * pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
continue;
nSelRangeEnd = nIndex;
bool bMultiRowWrap =
( LPVOID(pTii) == LPVOID(pTiiLV)
|| pTii->MultiRowWrapGet()
) ? true : false;
if( bMultiRowWrap )
break;
}
for( nIndex = nCurSel - 1; nIndex >= 0; nIndex -- )
{
TAB_ITEM_INFO * pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
continue;
if( nIndex == 0 )
{
nSelRangeStart = nIndex;
break;
}
bool bMultiRowWrap =
( ( nIndex == 0 )
|| pTii->MultiRowWrapGet()
) ? true : false;
if( bMultiRowWrap )
break;
nSelRangeStart = nIndex;
}
} // if( pTii->VisibleGet() )
else
nCurSel = -1;
} // if( nCurSel >= 0 )
bool bTopLeft = OrientationIsTopLeft();
int nPartStart = 0;
nPartCrossExtent = 0;
if( bTopLeft )
{
nPartStart = ( nSelRangeEnd >= 0 ) ? ( nSelRangeEnd + 1 ) : 0;
if( nPartStart >= nItemCount )
{
nPartStart = 0;
nCurSel = nSelRangeStart = nSelRangeEnd = -1;
}
}
else
{
nPartStart = ( nSelRangeStart >= 0 ) ? nSelRangeStart : 0;
}
int nWalkStart = nPartStart;
int nWalkEnd = nItemCount - 1;
int nWalkShift = 1;
int nPartVisibleCount = 0;
int nEqualItemExtentSaved = nEqualItemExtent;
for( nIndex = nWalkStart; nIndex <= nWalkEnd; )
{ // setup item rectangles (1st part)
TAB_ITEM_INFO * pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
{
nIndex += nWalkShift;
pTii->MultiRowWrapSet( false );
continue;
}
if( m_nIndexVisFirst < 0 || nIndex < m_nIndexVisFirst )
m_nIndexVisFirst = nIndex;
if( m_nIndexVisLast < 0 || m_nIndexVisLast < nIndex )
m_nIndexVisLast = nIndex;
nVisibleNo++;
bool bMultiRowWrap =
( LPVOID(pTii) == LPVOID(pTiiLV) // ( nIndex == ( nItemCount - 1 ) )
|| pTii->MultiRowWrapGet()
) ? true : false;
if( ! pTii->VisibleGet() )
{
bMultiRowWrap = false;
pTii->MultiRowWrapSet( false );
}
if( nIndex == ( nItemCount - 1 ) )
bMultiRowWrap = true;
if( ! bMultiRowWrap )
{
if( pTii->VisibleGet() )
{
nPartVisibleCount ++;
const CSize & _size = pTii->GetLastMeasuredItemSize();
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
nPartCrossExtent = max( nPartCrossExtent, _size.cy );
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
nPartCrossExtent = max( nPartCrossExtent, _size.cx );
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( dwOrientation )
} // if( pTii->VisibleGet() )
nIndex += nWalkShift;
continue;
} // if( ! bMultiRowWrap )
if( pTii->VisibleGet() )
nPartVisibleCount ++;
if( bEqualWidth && (! bCancelEqualWidth ) && nPartVisibleCount > 0 )
{
nEqualItemExtent = bHorz ? m_rcTabItemsArea.Width() : m_rcTabItemsArea.Height();
nEqualItemExtent /= nPartVisibleCount;
}
else
nEqualItemExtent = nEqualItemExtentSaved;
int nReviewIndex = nPartStart;
for( ; nReviewIndex <= nIndex; nReviewIndex ++ )
{
TAB_ITEM_INFO * pTii = ItemGet( nReviewIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
continue;
pTii->m_bHelperToolTipAvail = false;
if( bEqualWidth && (! bCancelEqualWidth ) )
{
if( bHorz )
{
if( pTii->m_sizeLastMeasuredItem.cx > nEqualItemExtent )
{
m_bEnableTrackToolTips = true;
pTii->m_bHelperToolTipAvail = true;
}
pTii->m_sizeLastMeasuredItem.cx = nEqualItemExtent;
}
else
{
if( pTii->m_sizeLastMeasuredItem.cy > nEqualItemExtent )
{
m_bEnableTrackToolTips = true;
pTii->m_bHelperToolTipAvail = true;
}
pTii->m_sizeLastMeasuredItem.cy = nEqualItemExtent;
}
} // if( bEqualWidth && (! bCancelEqualWidth ) )
const CSize & _size = pTii->GetLastMeasuredItemSize();
CRect rcItem( 0, 0, _size.cx, _size.cy );
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
nPartCrossExtent = max( nPartCrossExtent, _size.cy );
rcItem.OffsetRect( nItemRectStartPos, nItemRectOffs );
nItemRectStartPos += _size.cx;
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
nPartCrossExtent = max( nPartCrossExtent, _size.cx );
rcItem.OffsetRect( nItemRectOffs, nItemRectStartPos );
nItemRectStartPos += _size.cy;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( dwOrientation )
pTii->ItemRectSet( rcItem );
CSize _sizeCloseButton = OnTabWndQueryItemCloseButtonSize( pTii );
if( _sizeCloseButton.cx > 0 && _sizeCloseButton.cy > 0 )
{
CRect rcTabItemCloseButton = rcItem;
if( bHorz )
{
rcTabItemCloseButton.left = rcTabItemCloseButton.right - _sizeCloseButton.cx;
rcTabItemCloseButton.bottom = rcTabItemCloseButton.top + _sizeCloseButton.cy;
rcTabItemCloseButton.OffsetRect(
- __EXTTAB_MARGIN_ICON2TEXT_X,
( rcItem.Height() - rcTabItemCloseButton.Height() ) / 2
);
} // if( bHorz )
else
{
rcTabItemCloseButton.right = rcTabItemCloseButton.left + _sizeCloseButton.cx;
rcTabItemCloseButton.top = rcTabItemCloseButton.bottom - _sizeCloseButton.cy;
rcTabItemCloseButton.OffsetRect(
( rcItem.Width() - rcTabItemCloseButton.Width() ) / 2,
- __EXTTAB_MARGIN_ICON2TEXT_Y - 2
);
} // else from if( bHorz )
CExtPaintManager * pPM = PmBridge_GetPM();
ASSERT_VALID( pPM );
pPM->TabWnd_AdjustItemCloseButtonRect( rcTabItemCloseButton, this );
pTii->CloseButtonRectSet( rcTabItemCloseButton );
} // if( _sizeCloseButton.cx > 0 && _sizeCloseButton.cy > 0 )
nVisibleNo++;
} // for( ; nReviewIndex <= nIndex; nReviewIndex ++ )
nIndex += nWalkShift;
nPartStart = nIndex;
nItemRectStartPos = 0;
nPartCrossExtent += nPartDistance;
nItemRectOffs += nPartCrossExtent;
nPartCrossExtent = 0;
nPartVisibleCount = 0;
} // setup item rectangles (1st part)
if( nSelRangeStart >= 0 )
{ // setup item rectangles (2nd part)
ASSERT( nSelRangeStart <= nSelRangeEnd );
nItemRectStartPos = 0;
nPartStart = 0;
nPartVisibleCount = 0;
if( bTopLeft )
{
nWalkStart = nPartStart;
nWalkEnd = nSelRangeEnd;
}
else
{
nWalkStart = 0;
nWalkEnd = nSelRangeStart - 1;
}
for( nIndex = nWalkStart; nIndex <= nWalkEnd; )
{ // setup item rectangles (2nd part)
TAB_ITEM_INFO * pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
{
nIndex += nWalkShift;
pTii->MultiRowWrapSet( false );
continue;
}
if( m_nIndexVisFirst < 0 || nIndex < m_nIndexVisFirst )
m_nIndexVisFirst = nIndex;
if( m_nIndexVisLast < 0 || m_nIndexVisLast < nIndex )
m_nIndexVisLast = nIndex;
nVisibleNo++;
bool bMultiRowWrap =
( LPVOID(pTii) == LPVOID(pTiiLV) // ( nIndex == ( nItemCount - 1 ) )
|| pTii->MultiRowWrapGet()
) ? true : false;
if( ! pTii->VisibleGet() )
{
bMultiRowWrap = false;
pTii->MultiRowWrapSet( false );
}
if( nIndex == ( nItemCount - 1 ) )
bMultiRowWrap = true;
if( ! bMultiRowWrap )
{
if( pTii->VisibleGet() )
{
nPartVisibleCount ++;
const CSize & _size = pTii->GetLastMeasuredItemSize();
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
nPartCrossExtent = max( nPartCrossExtent, _size.cy );
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
nPartCrossExtent = max( nPartCrossExtent, _size.cx );
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( dwOrientation )
} // if( pTii->VisibleGet() )
nIndex += nWalkShift;
continue;
} // if( ! bMultiRowWrap )
if( pTii->VisibleGet() )
nPartVisibleCount ++;
if( bEqualWidth && (! bCancelEqualWidth ) && nPartVisibleCount > 0 )
{
nEqualItemExtent = bHorz ? m_rcTabItemsArea.Width() : m_rcTabItemsArea.Height();
nEqualItemExtent /= nPartVisibleCount;
}
else
nEqualItemExtent = nEqualItemExtentSaved;
int nReviewIndex = nPartStart;
for( ; nReviewIndex <= nIndex; nReviewIndex ++ )
{
TAB_ITEM_INFO * pTii = ItemGet( nReviewIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
continue;
pTii->m_bHelperToolTipAvail = false;
if( bEqualWidth && (! bCancelEqualWidth ) )
{
if( bHorz )
{
if( pTii->m_sizeLastMeasuredItem.cx > nEqualItemExtent )
{
m_bEnableTrackToolTips = true;
pTii->m_bHelperToolTipAvail = true;
}
pTii->m_sizeLastMeasuredItem.cx = nEqualItemExtent;
}
else
{
if( pTii->m_sizeLastMeasuredItem.cy > nEqualItemExtent )
{
m_bEnableTrackToolTips = true;
pTii->m_bHelperToolTipAvail = true;
}
pTii->m_sizeLastMeasuredItem.cy = nEqualItemExtent;
}
} // if( bEqualWidth && (! bCancelEqualWidth ) )
const CSize & _size = pTii->GetLastMeasuredItemSize();
CRect rcItem( 0, 0, _size.cx, _size.cy );
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
nPartCrossExtent = max( nPartCrossExtent, _size.cy );
rcItem.OffsetRect( nItemRectStartPos, nItemRectOffs );
nItemRectStartPos += _size.cx;
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
nPartCrossExtent = max( nPartCrossExtent, _size.cx );
rcItem.OffsetRect( nItemRectOffs, nItemRectStartPos );
nItemRectStartPos += _size.cy;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( dwOrientation )
pTii->ItemRectSet( rcItem );
CSize _sizeCloseButton = OnTabWndQueryItemCloseButtonSize( pTii );
if( _sizeCloseButton.cx > 0 && _sizeCloseButton.cy > 0 )
{
CRect rcTabItemCloseButton = rcItem;
if( bHorz )
{
rcTabItemCloseButton.left = rcTabItemCloseButton.right - _sizeCloseButton.cx;
rcTabItemCloseButton.bottom = rcTabItemCloseButton.top + _sizeCloseButton.cy;
rcTabItemCloseButton.OffsetRect(
- __EXTTAB_MARGIN_ICON2TEXT_X,
( rcItem.Height() - rcTabItemCloseButton.Height() ) / 2
);
} // if( bHorz )
else
{
rcTabItemCloseButton.right = rcTabItemCloseButton.left + _sizeCloseButton.cx;
rcTabItemCloseButton.top = rcTabItemCloseButton.bottom - _sizeCloseButton.cy;
rcTabItemCloseButton.OffsetRect(
( rcItem.Width() - rcTabItemCloseButton.Width() ) / 2,
- __EXTTAB_MARGIN_ICON2TEXT_Y - 2
);
} // else from if( bHorz )
CExtPaintManager * pPM = PmBridge_GetPM();
ASSERT_VALID( pPM );
pPM->TabWnd_AdjustItemCloseButtonRect( rcTabItemCloseButton, this );
pTii->CloseButtonRectSet( rcTabItemCloseButton );
} // if( _sizeCloseButton.cx > 0 && _sizeCloseButton.cy > 0 )
nVisibleNo++;
} // for( ; nReviewIndex <= nIndex; nReviewIndex ++ )
nIndex += nWalkShift;
nPartStart = nIndex;
nItemRectStartPos = 0;
nPartCrossExtent += nPartDistance;
nItemRectOffs += nPartCrossExtent;
nPartCrossExtent = 0;
nPartVisibleCount = 0;
} // setup item rectangles (2nd part)
} // setup item rectangles (2nd part)
} // if( bMultiRowColumn )
else
{
for( nIndex = 0; nIndex < nItemCount; nIndex++ )
{ // setup item rectangles
TAB_ITEM_INFO * pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
continue;
pTii->m_bHelperToolTipAvail = false;
if( (! bMultiRowColumn ) && bEqualWidth && (! bCancelEqualWidth ) )
{
if( bHorz )
{
if( pTii->m_sizeLastMeasuredItem.cx > nEqualItemExtent )
{
m_bEnableTrackToolTips = true;
pTii->m_bHelperToolTipAvail = true;
}
pTii->m_sizeLastMeasuredItem.cx = nEqualItemExtent;
}
else
{
if( pTii->m_sizeLastMeasuredItem.cy > nEqualItemExtent )
{
m_bEnableTrackToolTips = true;
pTii->m_bHelperToolTipAvail = true;
}
pTii->m_sizeLastMeasuredItem.cy = nEqualItemExtent;
}
}
const CSize & _size = pTii->GetLastMeasuredItemSize();
CRect rcItem( 0, 0, _size.cx, _size.cy );
bool bGroupStart = bGrouped && pTii->GroupStartGet();
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
if( nVisibleNo != 0
&& bGroupStart
)
nItemRectStartPos += __EXTTAB_BETWEEN_GROUP_GAP_DX;
rcItem.OffsetRect( nItemRectStartPos, nItemRectOffs );
nItemRectStartPos += _size.cx;
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
if( nVisibleNo != 0
&& bGroupStart
)
nItemRectStartPos += __EXTTAB_BETWEEN_GROUP_GAP_DY;
rcItem.OffsetRect( nItemRectOffs, nItemRectStartPos );
nItemRectStartPos += _size.cy;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( dwOrientation )
pTii->ItemRectSet( rcItem );
rcItem.OffsetRect(
bHorz ? ( m_rcTabItemsArea.left - m_nScrollPos ) : 0,
bHorz ? 0 : (m_rcTabItemsArea.top - m_nScrollPos)
);
CSize _sizeCloseButton = OnTabWndQueryItemCloseButtonSize( pTii );
if( _sizeCloseButton.cx > 0 && _sizeCloseButton.cy > 0 )
{
CRect rcTabItemCloseButton = rcItem;
if( bHorz )
{
rcTabItemCloseButton.left = rcTabItemCloseButton.right - _sizeCloseButton.cx;
rcTabItemCloseButton.bottom = rcTabItemCloseButton.top + _sizeCloseButton.cy;
rcTabItemCloseButton.OffsetRect(
- __EXTTAB_MARGIN_ICON2TEXT_X,
( rcItem.Height() - rcTabItemCloseButton.Height() ) / 2
);
} // if( bHorz )
else
{
rcTabItemCloseButton.right = rcTabItemCloseButton.left + _sizeCloseButton.cx;
rcTabItemCloseButton.top = rcTabItemCloseButton.bottom - _sizeCloseButton.cy;
rcTabItemCloseButton.OffsetRect(
( rcItem.Width() - rcTabItemCloseButton.Width() ) / 2,
- __EXTTAB_MARGIN_ICON2TEXT_Y - 2
);
} // else from if( bHorz )
CExtPaintManager * pPM = PmBridge_GetPM();
ASSERT_VALID( pPM );
pPM->TabWnd_AdjustItemCloseButtonRect( rcTabItemCloseButton, this );
pTii->CloseButtonRectSet( rcTabItemCloseButton );
} // if( _sizeCloseButton.cx > 0 && _sizeCloseButton.cy > 0 )
INT nItemExtentMinVal = bHorz ? rcItem.left : rcItem.top;
INT nItemExtentMaxVal = bHorz ? rcItem.right : rcItem.bottom;
INT nAreaExtentMinVal = 0;
INT nAreaExtentMaxVal =
bHorz
? (m_rcTabItemsArea.right - m_rcTabItemsArea.left)
: (m_rcTabItemsArea.bottom - m_rcTabItemsArea.top)
;
nAreaExtentMaxVal += __EXTTAB_ADD_END_SCROLL_SPACE + 2;
if( m_nIndexVisFirst < 0 )
{
if( nItemExtentMaxVal >= nAreaExtentMinVal )
m_nIndexVisFirst = nIndex;
}
if( nItemExtentMinVal <= nAreaExtentMaxVal )
m_nIndexVisLast = nIndex;
nVisibleNo++;
} // setup item rectangles
} // else from if( bMultiRowColumn )
if( nVisibleNo != m_nVisibleItemCount )
return false;
if( m_nIndexVisFirst < 0 || m_nIndexVisLast < 0 )
{
m_nIndexVisFirst = m_nIndexVisLast = -1;
bEnableScrollButtons = false;
}
else
{
if( m_nIndexVisFirst > m_nIndexVisLast )
m_nIndexVisLast = m_nIndexVisFirst;
ASSERT( m_nIndexVisFirst <= m_nIndexVisLast );
ASSERT( 0 <= m_nIndexVisFirst && m_nIndexVisFirst < nItemCount );
ASSERT( 0 <= m_nIndexVisLast && m_nIndexVisLast < nItemCount );
}
ASSERT_VALID( this );
return true;
}
2) The multi row layout issue in the
CExtTabWnd::_RecalcLayoutImpl()
method:
bool CExtTabWnd::_RecalcLayoutImpl()
{
ASSERT_VALID( this );
if( GetSafeHwnd() == NULL || ( ! ::IsWindow(GetSafeHwnd()) ) )
return true;
if( ! m_bDelayRecalcLayout )
return true;
m_bDelayRecalcLayout = false;
m_rcTabItemsArea.SetRectEmpty();
m_rcTabNearBorderArea.SetRectEmpty();
m_nIndexVisFirst = m_nIndexVisLast = -1;
CRect rcClient;
_RecalcLayout_GetClientRect( rcClient );
if( rcClient.IsRectEmpty()
|| rcClient.right <= rcClient.left
|| rcClient.bottom <= rcClient.top
)
return true;
m_rcTabItemsArea = rcClient;
DWORD dwOrientation = OrientationGet();
bool bHorz = OrientationIsHorizontal();
CWindowDC dcMeasure( this );
LONG nTabAreaMetric = 0;
bool bMultiRowColumn = OnTabWndQueryMultiRowColumnLayout();
LONG nItemCount = ItemGetCount();
DWORD dwTabWndStyle = GetTabWndStyle();
bool bEqualWidth = (dwTabWndStyle&__ETWS_EQUAL_WIDTHS) ? true : false;
bool bEnableScrollButtons = ! bEqualWidth;
bool bGrouped = (dwTabWndStyle&__ETWS_GROUPED) ? true : false;
bool bGroupedExpandItems = (dwTabWndStyle&__ETWS_GROUPED_EXPAND_ITEMS) ? true : false;
int nPartExtent = 0;
int nPartCrossExtent = 0;
int nMaxAvailPartExtent = 0;
int nPartDistance = 0;
if( bMultiRowColumn )
{
nPartDistance = OnTabWndQueryMultiRowColumnDistance();
CSize _sizeButton = OnTabWndCalcButtonSize( dcMeasure, 20 );
ASSERT( _sizeButton.cx > 0 && _sizeButton.cy > 0 );
INT nButtonExtent = bHorz ? _sizeButton.cx : _sizeButton.cy;
INT nBetweenButtonExtent = bHorz ? __EXTTAB_BETWEEN_BTN_GAP_DX : __EXTTAB_BETWEEN_BTN_GAP_DY;
int nButtonsPreCalcExtent = OnTabWndButtonsCalcWidth( nButtonExtent, nBetweenButtonExtent );
bEnableScrollButtons = false;
m_nItemsExtent = m_nScrollMaxPos = 0;
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
nMaxAvailPartExtent = rcClient.Width();
m_rcTabItemsArea.bottom = m_rcTabItemsArea.top;
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
nMaxAvailPartExtent = rcClient.Height();
m_rcTabItemsArea.right = m_rcTabItemsArea.left;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif
}
nMaxAvailPartExtent -= nButtonsPreCalcExtent;
}
else
{
if( bGrouped )
m_nItemsExtent = m_nScrollMaxPos = 10;
else
m_nItemsExtent = m_nScrollMaxPos = 0;
}
if( bGrouped )
bEqualWidth = false;
INT nVisibleNo = 0;
LONG nIndex = 0;
TAB_ITEM_INFO * pTiiLV = NULL;
for( nIndex = 0; nIndex < nItemCount; )
{
TAB_ITEM_INFO * pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
pTii->MultiRowWrapSet( false );
if( bGrouped )
{
if( ! pTii->VisibleGet() )
{
nIndex++;
continue;
}
if( ! bGroupedExpandItems )
{
INT nMaxInGroupExtent = 0;
INT nNormalGroupItemExtent = 0;
INT nGroupStartIndex = nIndex;
INT nCountInGroup = 0;
for( nCountInGroup = 0; true ; )
{
CSize _size = pTii->Measure( &dcMeasure );
CSize _sizeText = pTii->GetLastMeasuredTextSize();
CSize _sizeIcon = pTii->GetLastMeasuredIconSize();
bool bGroupStart = (nVisibleNo == 0) || pTii->GroupStartGet();
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
{
nMaxInGroupExtent = max( nMaxInGroupExtent, _size.cx );
INT nGroupItemExtent = _size.cx - _sizeText.cx - ((_sizeIcon.cx > 0) ? __EXTTAB_MARGIN_ICON2TEXT_X : 0);
nNormalGroupItemExtent = max( nNormalGroupItemExtent, nGroupItemExtent );
if( nVisibleNo != 0 && bGroupStart )
m_nItemsExtent += __EXTTAB_BETWEEN_GROUP_GAP_DX;
nTabAreaMetric = max( nTabAreaMetric, _size.cy );
}
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
{
nMaxInGroupExtent = max( nMaxInGroupExtent, _size.cy );
INT nGroupItemExtent = _size.cy - _sizeText.cx - ((_sizeIcon.cy > 0) ? __EXTTAB_MARGIN_ICON2TEXT_Y : 0);
nNormalGroupItemExtent = max( nNormalGroupItemExtent, nGroupItemExtent );
if( nVisibleNo != 0 && bGroupStart )
m_nItemsExtent += __EXTTAB_BETWEEN_GROUP_GAP_DY;
nTabAreaMetric = max( nTabAreaMetric, _size.cx );
}
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif
}
nIndex++;
nVisibleNo++;
nCountInGroup++;
ASSERT( nIndex <= nItemCount );
if( nIndex == nItemCount )
break;
pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
if( pTii->GroupStartGet() )
break;
}
ASSERT( nCountInGroup >= 1 );
INT nGroupExtent = nMaxInGroupExtent + nNormalGroupItemExtent * (nCountInGroup-1);
m_nItemsExtent += nGroupExtent;
for( INT n = 0; n < nCountInGroup; n++ )
{
pTii = ItemGet( nGroupStartIndex + n );
ASSERT_VALID( pTii );
bool bInGroupActive = pTii->InGroupActiveGet();
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
if( bInGroupActive )
pTii->m_sizeLastMeasuredItem.cx = nMaxInGroupExtent;
else
pTii->m_sizeLastMeasuredItem.cx = nNormalGroupItemExtent;
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
if( bInGroupActive )
pTii->m_sizeLastMeasuredItem.cy = nMaxInGroupExtent;
else
pTii->m_sizeLastMeasuredItem.cy = nNormalGroupItemExtent;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif
}
}
}
else
{
CSize _size = pTii->Measure( &dcMeasure );
bool bGroupStart = (nVisibleNo == 0) || pTii->GroupStartGet();
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
m_nItemsExtent += _size.cx;
nTabAreaMetric = max( nTabAreaMetric, _size.cy );
if( nVisibleNo != 0 && bGroupStart )
m_nItemsExtent += __EXTTAB_BETWEEN_GROUP_GAP_DX;
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
m_nItemsExtent += _size.cy;
nTabAreaMetric = max( nTabAreaMetric, _size.cx );
if( nVisibleNo != 0 && bGroupStart )
m_nItemsExtent += __EXTTAB_BETWEEN_GROUP_GAP_DY;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif
}
nIndex++;
nVisibleNo++;
}
}
else
{
CSize _size( 0, 0 );
if( pTii->VisibleGet() )
_size = pTii->Measure( &dcMeasure );
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
if( bMultiRowColumn )
{
int nTestPartExtent = nPartExtent + _size.cx;
if( nTestPartExtent > nMaxAvailPartExtent )
{
nPartCrossExtent = max( nPartCrossExtent, _size.cy );
nPartCrossExtent += nPartDistance;
m_nItemsExtent = max( m_nItemsExtent, nPartCrossExtent );
m_rcTabItemsArea.bottom += nPartCrossExtent;
nPartExtent = _size.cx;
nPartCrossExtent = _size.cy;
if( pTiiLV != NULL )
pTiiLV->MultiRowWrapSet();
else
pTii->MultiRowWrapSet();
}
else
{
nPartExtent += _size.cx;
nPartCrossExtent = max( nPartCrossExtent, _size.cy );
m_nItemsExtent = max( m_nItemsExtent, nPartCrossExtent );
}
if( nIndex == (nItemCount-1) )
{
m_nItemsExtent = max( m_nItemsExtent, nPartCrossExtent );
m_rcTabItemsArea.bottom += nPartCrossExtent;
}
}
else
{
if( ! pTii->VisibleGet() )
{
nIndex++;
continue;
}
m_nItemsExtent += _size.cx;
nTabAreaMetric =
max( nTabAreaMetric, _size.cy );
}
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
if( bMultiRowColumn )
{
int nTestPartExtent = nPartExtent + _size.cy;
if( nTestPartExtent > nMaxAvailPartExtent )
{
nPartCrossExtent = max( nPartCrossExtent, _size.cx );
m_nItemsExtent = max( m_nItemsExtent, nPartCrossExtent );
nPartCrossExtent += nPartDistance;
m_rcTabItemsArea.right += nPartCrossExtent;
nPartExtent = _size.cy;
nPartCrossExtent = _size.cx;
if( pTiiLV != NULL )
pTiiLV->MultiRowWrapSet();
else
pTii->MultiRowWrapSet();
}
else
{
nPartExtent += _size.cy;
nPartCrossExtent = max( nPartCrossExtent, _size.cx );
m_nItemsExtent = max( m_nItemsExtent, nPartCrossExtent );
}
if( nIndex == (nItemCount-1) )
{
m_nItemsExtent = max( m_nItemsExtent, nPartCrossExtent );
m_rcTabItemsArea.right += nPartCrossExtent;
}
}
else
{
if( ! pTii->VisibleGet() )
{
nIndex++;
continue;
}
m_nItemsExtent += _size.cy;
nTabAreaMetric =
max( nTabAreaMetric, _size.cx );
}
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif
}
nIndex++;
nVisibleNo++;
}
if( pTii->VisibleGet() )
pTiiLV = pTii;
}
LONG nSpaceBefore = 0, nSpaceAfter = 0, nSpaceOver = 0;
OnTabWndMeasureItemAreaMargins( nSpaceBefore, nSpaceAfter, nSpaceOver );
LONG nAddShiftForBtns = nSpaceAfter;
CSize _sizeButton = OnTabWndCalcButtonSize( dcMeasure, nTabAreaMetric );
ASSERT( _sizeButton.cx > 0 && _sizeButton.cy > 0 );
INT nButtonExtent = bHorz ? _sizeButton.cx : _sizeButton.cy;
INT nBetweenButtonExtent = bHorz ? __EXTTAB_BETWEEN_BTN_GAP_DX : __EXTTAB_BETWEEN_BTN_GAP_DY;
nSpaceAfter += OnTabWndButtonsCalcWidth( nButtonExtent, nBetweenButtonExtent );
LONG nItemRectStartPos = 0;
LONG nItemRectOffs = 0;
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
nTabAreaMetric = max( nTabAreaMetric, __EXTTAB_MIN_HORZ_HEIGHT );
if( ! bMultiRowColumn )
{
m_rcTabItemsArea.top += nSpaceOver;
m_rcTabItemsArea.bottom = m_rcTabItemsArea.top + nTabAreaMetric;
m_rcTabItemsArea.bottom = min( m_rcTabItemsArea.bottom, rcClient.bottom );
if( m_rcTabItemsArea.bottom < rcClient.bottom )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.top = m_rcTabItemsArea.bottom;
}
m_rcTabItemsArea.left += nSpaceBefore;
m_rcTabItemsArea.right -= nSpaceAfter;
nItemRectOffs += m_rcTabItemsArea.top;
m_nScrollMaxPos = m_nItemsExtent - m_rcTabItemsArea.Width();
if( m_nScrollMaxPos < 0 )
m_nScrollMaxPos = 0;
}
else
{
m_rcTabItemsArea.top += nSpaceOver;
m_rcTabItemsArea.bottom += nSpaceOver;
m_rcTabItemsArea.left += nSpaceBefore;
m_rcTabItemsArea.right -= nSpaceAfter;
nItemRectOffs += nSpaceOver;
if( m_rcTabItemsArea.bottom < rcClient.bottom )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.top = m_rcTabItemsArea.bottom;
}
}
break;
case __ETWS_ORIENT_BOTTOM:
nTabAreaMetric = max( nTabAreaMetric, __EXTTAB_MIN_HORZ_HEIGHT );
if( ! bMultiRowColumn )
{
m_rcTabItemsArea.bottom -= nSpaceOver;
m_rcTabItemsArea.top = m_rcTabItemsArea.bottom - nTabAreaMetric;
m_rcTabItemsArea.top = max( m_rcTabItemsArea.top, rcClient.top );
if( m_rcTabItemsArea.top > rcClient.top )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.bottom = m_rcTabItemsArea.top;
}
m_rcTabItemsArea.left += nSpaceBefore;
m_rcTabItemsArea.right -= nSpaceAfter;
nItemRectOffs += m_rcTabItemsArea.top;
m_nScrollMaxPos = m_nItemsExtent - m_rcTabItemsArea.Width();
if( m_nScrollMaxPos < 0 )
m_nScrollMaxPos = 0;
}
else
{
m_rcTabItemsArea.top += nSpaceOver;
m_rcTabItemsArea.bottom += nSpaceOver;
m_rcTabItemsArea.left += nSpaceBefore;
m_rcTabItemsArea.right -= nSpaceAfter;
nItemRectOffs += nSpaceOver;
if( m_rcTabItemsArea.top > rcClient.top )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.bottom = m_rcTabItemsArea.top;
}
}
break;
case __ETWS_ORIENT_LEFT:
nTabAreaMetric = max( nTabAreaMetric, __EXTTAB_MIN_VERT_WIDTH );
if( ! bMultiRowColumn )
{
m_rcTabItemsArea.left += nSpaceOver;
m_rcTabItemsArea.right = m_rcTabItemsArea.left + nTabAreaMetric;
m_rcTabItemsArea.right = min( m_rcTabItemsArea.right, rcClient.right );
if( m_rcTabItemsArea.right < rcClient.right )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.left = m_rcTabItemsArea.right;
}
m_rcTabItemsArea.top += nSpaceBefore;
m_rcTabItemsArea.bottom -= nSpaceAfter;
nItemRectOffs += m_rcTabItemsArea.left;
m_nScrollMaxPos = m_nItemsExtent - m_rcTabItemsArea.Height();
if( m_nScrollMaxPos < 0 )
m_nScrollMaxPos = 0;
}
else
{
m_rcTabItemsArea.left += nSpaceOver;
m_rcTabItemsArea.right += nSpaceOver;
m_rcTabItemsArea.top += nSpaceBefore;
m_rcTabItemsArea.bottom -= nSpaceAfter;
nItemRectOffs += nSpaceOver;
if( m_rcTabItemsArea.right < rcClient.right )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.left = m_rcTabItemsArea.right;
}
}
break;
case __ETWS_ORIENT_RIGHT:
nTabAreaMetric = max( nTabAreaMetric, __EXTTAB_MIN_VERT_WIDTH );
if( ! bMultiRowColumn )
{
m_rcTabItemsArea.right -= nSpaceOver;
m_rcTabItemsArea.left = m_rcTabItemsArea.right - nTabAreaMetric;
m_rcTabItemsArea.left = max( m_rcTabItemsArea.left, rcClient.left );
if( m_rcTabItemsArea.left > rcClient.left )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.right = m_rcTabItemsArea.left;
}
m_rcTabItemsArea.top += nSpaceBefore;
m_rcTabItemsArea.bottom -= nSpaceAfter;
nItemRectOffs += m_rcTabItemsArea.left;
m_nScrollMaxPos = m_nItemsExtent - m_rcTabItemsArea.Height();
if( m_nScrollMaxPos < 0 )
m_nScrollMaxPos = 0;
}
else
{
m_rcTabItemsArea.left += nSpaceOver;
m_rcTabItemsArea.right += nSpaceOver;
m_rcTabItemsArea.top += nSpaceBefore;
m_rcTabItemsArea.bottom -= nSpaceAfter;
nItemRectOffs += nSpaceOver;
if( m_rcTabItemsArea.left > rcClient.left )
{
m_rcTabNearBorderArea = rcClient;
m_rcTabNearBorderArea.right = m_rcTabItemsArea.left;
}
}
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif
}
if( ! bMultiRowColumn )
{
ASSERT( m_nScrollPos >= 0 );
ASSERT( m_nScrollMaxPos >= 0 );
if( m_nScrollPos > m_nScrollMaxPos )
m_nScrollPos = m_nScrollMaxPos;
}
else
m_nScrollPos = m_nScrollMaxPos = 0;
LONG nEqualItemExtent = bHorz ? __EXTTAB_MIN_HORZ_WIDTH : __EXTTAB_MIN_VERT_HEIGHT ;
bool bCancelEqualWidth = false;
if( bEqualWidth && m_nVisibleItemCount > 0 )
{
if( ! _IsScrollAvail() )
{
if( (m_dwTabWndStyle & __ETWS_FULL_WIDTH) == 0 )
bCancelEqualWidth = true;
}
if( ! bCancelEqualWidth )
{
INT nTestExtent = bHorz ? m_rcTabItemsArea.Width() : m_rcTabItemsArea.Height();
nTestExtent /= m_nVisibleItemCount;
nEqualItemExtent = max( nTestExtent, nEqualItemExtent );
}
}
CRect rcButton( m_rcTabItemsArea );
if( bHorz )
rcButton.right = rcClient.right - nAddShiftForBtns;
else
rcButton.bottom = rcClient.bottom - nAddShiftForBtns;
rcButton.OffsetRect( bHorz ? 0 : (m_rcTabItemsArea.Width() - _sizeButton.cx) / 2, bHorz ? (m_rcTabItemsArea.Height() - _sizeButton.cy) / 2 : 0 );
rcButton.OffsetRect( bHorz ? (-nBetweenButtonExtent) : 0, bHorz ? 0 : (-nBetweenButtonExtent) );
if( bHorz )
{
rcButton.left = rcButton.right - _sizeButton.cx;
rcButton.bottom = rcButton.top + _sizeButton.cy;
}
else
{
rcButton.right = rcButton.left + _sizeButton.cx;
rcButton.top = rcButton.bottom - _sizeButton.cy;
}
OnTabWndButtonsRecalcLayout( rcButton, nButtonExtent, nBetweenButtonExtent );
m_nIndexVisFirst = -1;
m_nIndexVisLast = -1;
nVisibleNo = 0;
m_bEnableTrackToolTips = false;
if( bMultiRowColumn )
{
int nCurSel = SelectionGet(), nSelRangeStart = -1, nSelRangeEnd = -1;
if( nCurSel >= 0 )
{
TAB_ITEM_INFO * pTii = ItemGet( nCurSel );
ASSERT_VALID( pTii );
if( pTii->VisibleGet() )
{
nSelRangeStart = nSelRangeEnd = nCurSel;
for( nIndex = nCurSel; nIndex < nItemCount; nIndex ++ )
{
TAB_ITEM_INFO * pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
continue;
nSelRangeEnd = nIndex;
bool bMultiRowWrap = ( LPVOID(pTii) == LPVOID(pTiiLV) || pTii->MultiRowWrapGet() ) ? true : false;
if( bMultiRowWrap )
break;
}
for( nIndex = nCurSel - 1; nIndex >= 0; nIndex -- )
{
TAB_ITEM_INFO * pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
continue;
if( nIndex == 0 )
{
nSelRangeStart = nIndex;
break;
}
bool bMultiRowWrap = ( ( nIndex == 0 ) || pTii->MultiRowWrapGet() ) ? true : false;
if( bMultiRowWrap )
break;
nSelRangeStart = nIndex;
}
}
else
nCurSel = -1;
}
bool bTopLeft = OrientationIsTopLeft();
int nPartStart = 0;
nPartCrossExtent = 0;
if( bTopLeft )
{
nPartStart = ( nSelRangeEnd >= 0 ) ? ( nSelRangeEnd + 1 ) : 0;
if( nPartStart >= nItemCount )
{
nPartStart = 0;
nCurSel = nSelRangeStart = nSelRangeEnd = -1;
}
}
else
{
nPartStart = ( nSelRangeStart >= 0 ) ? nSelRangeStart : 0;
}
int nWalkStart = nPartStart;
int nWalkEnd = nItemCount - 1;
int nWalkShift = 1;
int nPartVisibleCount = 0;
int nEqualItemExtentSaved = nEqualItemExtent;
for( nIndex = nWalkStart; nIndex <= nWalkEnd; )
{
TAB_ITEM_INFO * pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
{
nIndex += nWalkShift;
pTii->MultiRowWrapSet( false );
continue;
}
if( m_nIndexVisFirst < 0 || nIndex < m_nIndexVisFirst )
m_nIndexVisFirst = nIndex;
if( m_nIndexVisLast < 0 || m_nIndexVisLast < nIndex )
m_nIndexVisLast = nIndex;
nVisibleNo++;
bool bMultiRowWrap =
( LPVOID(pTii) == LPVOID(pTiiLV)
|| pTii->MultiRowWrapGet()
) ? true : false;
if( ! pTii->VisibleGet() )
{
bMultiRowWrap = false;
pTii->MultiRowWrapSet( false );
}
if( nIndex == ( nItemCount - 1 ) )
bMultiRowWrap = true;
if( ! bMultiRowWrap )
{
if( pTii->VisibleGet() )
{
nPartVisibleCount ++;
const CSize & _size = pTii->GetLastMeasuredItemSize();
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
nPartCrossExtent = max( nPartCrossExtent, _size.cy );
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
nPartCrossExtent = max( nPartCrossExtent, _size.cx );
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif
}
}
nIndex += nWalkShift;
continue;
}
if( pTii->VisibleGet() )
nPartVisibleCount ++;
if( bEqualWidth && (! bCancelEqualWidth ) && nPartVisibleCount > 0 )
{
nEqualItemExtent = bHorz ? m_rcTabItemsArea.Width() : m_rcTabItemsArea.Height();
nEqualItemExtent /= nPartVisibleCount;
}
else
nEqualItemExtent = nEqualItemExtentSaved;
int nReviewIndex = nPartStart;
for( ; nReviewIndex <= nIndex; nReviewIndex ++ )
{
TAB_ITEM_INFO * pTii = ItemGet( nReviewIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
continue;
pTii->m_bHelperToolTipAvail = false;
if( bEqualWidth && (! bCancelEqualWidth ) )
{
if( bHorz )
{
if( pTii->m_sizeLastMeasuredItem.cx > nEqualItemExtent )
{
m_bEnableTrackToolTips = true;
pTii->m_bHelperToolTipAvail = true;
}
pTii->m_sizeLastMeasuredItem.cx = nEqualItemExtent;
}
else
{
if( pTii->m_sizeLastMeasuredItem.cy > nEqualItemExtent )
{
m_bEnableTrackToolTips = true;
pTii->m_bHelperToolTipAvail = true;
}
pTii->m_sizeLastMeasuredItem.cy = nEqualItemExtent;
}
}
const CSize & _size = pTii->GetLastMeasuredItemSize();
CRect rcItem( 0, 0, _size.cx, _size.cy );
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
nPartCrossExtent = max( nPartCrossExtent, _size.cy );
rcItem.OffsetRect( nItemRectStartPos, nItemRectOffs );
nItemRectStartPos += _size.cx;
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
nPartCrossExtent = max( nPartCrossExtent, _size.cx );
rcItem.OffsetRect( nItemRectOffs, nItemRectStartPos );
nItemRectStartPos += _size.cy;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif
}
pTii->ItemRectSet( rcItem );
nVisibleNo++;
}
nIndex += nWalkShift;
nPartStart = nIndex;
nItemRectStartPos = 0;
nPartCrossExtent += nPartDistance;
nItemRectOffs += nPartCrossExtent;
nPartCrossExtent = 0;
nPartVisibleCount = 0;
}
if( nSelRangeStart >= 0 )
{
ASSERT( nSelRangeStart <= nSelRangeEnd );
nItemRectStartPos = 0;
nPartStart = 0;
nPartVisibleCount = 0;
if( bTopLeft )
{
nWalkStart = nPartStart;
nWalkEnd = nSelRangeEnd;
}
else
{
nWalkStart = 0;
nWalkEnd = nSelRangeStart - 1;
}
for( nIndex = nWalkStart; nIndex <= nWalkEnd; )
{
TAB_ITEM_INFO * pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
{
nIndex += nWalkShift;
pTii->MultiRowWrapSet( false );
continue;
}
if( m_nIndexVisFirst < 0 || nIndex < m_nIndexVisFirst )
m_nIndexVisFirst = nIndex;
if( m_nIndexVisLast < 0 || m_nIndexVisLast < nIndex )
m_nIndexVisLast = nIndex;
nVisibleNo++;
bool bMultiRowWrap =
( LPVOID(pTii) == LPVOID(pTiiLV)
|| pTii->MultiRowWrapGet()
) ? true : false;
if( ! pTii->VisibleGet() )
{
bMultiRowWrap = false;
pTii->MultiRowWrapSet( false );
}
if( nIndex == ( nItemCount - 1 ) )
bMultiRowWrap = true;
if( ! bMultiRowWrap )
{
if( pTii->VisibleGet() )
{
nPartVisibleCount ++;
const CSize & _size = pTii->GetLastMeasuredItemSize();
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
nPartCrossExtent = max( nPartCrossExtent, _size.cy );
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
nPartCrossExtent = max( nPartCrossExtent, _size.cx );
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif
}
}
nIndex += nWalkShift;
continue;
}
if( pTii->VisibleGet() )
nPartVisibleCount ++;
if( bEqualWidth && (! bCancelEqualWidth ) && nPartVisibleCount > 0 )
{
nEqualItemExtent = bHorz ? m_rcTabItemsArea.Width() : m_rcTabItemsArea.Height();
nEqualItemExtent /= nPartVisibleCount;
}
else
nEqualItemExtent = nEqualItemExtentSaved;
int nReviewIndex = nPartStart;
for( ; nReviewIndex <= nIndex; nReviewIndex ++ )
{
TAB_ITEM_INFO * pTii = ItemGet( nReviewIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
continue;
pTii->m_bHelperToolTipAvail = false;
if( bEqualWidth && (! bCancelEqualWidth ) )
{
if( bHorz )
{
if( pTii->m_sizeLastMeasuredItem.cx > nEqualItemExtent )
{
m_bEnableTrackToolTips = true;
pTii->m_bHelperToolTipAvail = true;
}
pTii->m_sizeLastMeasuredItem.cx = nEqualItemExtent;
}
else
{
if( pTii->m_sizeLastMeasuredItem.cy > nEqualItemExtent )
{
m_bEnableTrackToolTips = true;
pTii->m_bHelperToolTipAvail = true;
}
pTii->m_sizeLastMeasuredItem.cy = nEqualItemExtent;
}
}
const CSize & _size = pTii->GetLastMeasuredItemSize();
CRect rcItem( 0, 0, _size.cx, _size.cy );
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
nPartCrossExtent = max( nPartCrossExtent, _size.cy );
rcItem.OffsetRect( nItemRectStartPos, nItemRectOffs );
nItemRectStartPos += _size.cx;
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
nPartCrossExtent = max( nPartCrossExtent, _size.cx );
rcItem.OffsetRect( nItemRectOffs, nItemRectStartPos );
nItemRectStartPos += _size.cy;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif
}
pTii->ItemRectSet( rcItem );
nVisibleNo++;
}
nIndex += nWalkShift;
nPartStart = nIndex;
nItemRectStartPos = 0;
nPartCrossExtent += nPartDistance;
nItemRectOffs += nPartCrossExtent;
nPartCrossExtent = 0;
nPartVisibleCount = 0;
}
}
}
else
{
for( nIndex = 0; nIndex < nItemCount; nIndex++ )
{
TAB_ITEM_INFO * pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
if( ! pTii->VisibleGet() )
continue;
pTii->m_bHelperToolTipAvail = false;
if( (! bMultiRowColumn ) && bEqualWidth && (! bCancelEqualWidth ) )
{
if( bHorz )
{
if( pTii->m_sizeLastMeasuredItem.cx > nEqualItemExtent )
{
m_bEnableTrackToolTips = true;
pTii->m_bHelperToolTipAvail = true;
}
pTii->m_sizeLastMeasuredItem.cx = nEqualItemExtent;
}
else
{
if( pTii->m_sizeLastMeasuredItem.cy > nEqualItemExtent )
{
m_bEnableTrackToolTips = true;
pTii->m_bHelperToolTipAvail = true;
}
pTii->m_sizeLastMeasuredItem.cy = nEqualItemExtent;
}
}
const CSize & _size = pTii->GetLastMeasuredItemSize();
CRect rcItem( 0, 0, _size.cx, _size.cy );
bool bGroupStart = bGrouped && pTii->GroupStartGet();
switch( dwOrientation )
{
case __ETWS_ORIENT_TOP:
case __ETWS_ORIENT_BOTTOM:
if( nVisibleNo != 0 && bGroupStart )
nItemRectStartPos += __EXTTAB_BETWEEN_GROUP_GAP_DX;
rcItem.OffsetRect( nItemRectStartPos, nItemRectOffs );
nItemRectStartPos += _size.cx;
break;
case __ETWS_ORIENT_LEFT:
case __ETWS_ORIENT_RIGHT:
if( nVisibleNo != 0 && bGroupStart )
nItemRectStartPos += __EXTTAB_BETWEEN_GROUP_GAP_DY;
rcItem.OffsetRect( nItemRectOffs, nItemRectStartPos );
nItemRectStartPos += _size.cy;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif
}
pTii->ItemRectSet( rcItem );
rcItem.OffsetRect( bHorz ? ( m_rcTabItemsArea.left - m_nScrollPos ) : 0, bHorz ? 0 : (m_rcTabItemsArea.top - m_nScrollPos) );
CSize _sizeCloseButton = OnTabWndQueryItemCloseButtonSize( pTii );
if( _sizeCloseButton.cx > 0 && _sizeCloseButton.cy > 0 )
{
CRect rcTabItemCloseButton = rcItem;
if( bHorz )
{
rcTabItemCloseButton.left = rcTabItemCloseButton.right - _sizeCloseButton.cx;
rcTabItemCloseButton.bottom = rcTabItemCloseButton.top + _sizeCloseButton.cy;
rcTabItemCloseButton.OffsetRect( - __EXTTAB_MARGIN_ICON2TEXT_X, ( rcItem.Height() - rcTabItemCloseButton.Height() ) / 2 );
}
else
{
rcTabItemCloseButton.right = rcTabItemCloseButton.left + _sizeCloseButton.cx;
rcTabItemCloseButton.top = rcTabItemCloseButton.bottom - _sizeCloseButton.cy;
rcTabItemCloseButton.OffsetRect( ( rcItem.Width() - rcTabItemCloseButton.Width() ) / 2, - __EXTTAB_MARGIN_ICON2TEXT_Y - 2 );
}
CExtPaintManager * pPM = PmBridge_GetPM();
ASSERT_VALID( pPM );
pPM->TabWnd_AdjustItemCloseButtonRect( rcTabItemCloseButton, this );
pTii->CloseButtonRectSet( rcTabItemCloseButton );
}
INT nItemExtentMinVal = bHorz ? rcItem.left : rcItem.top;
INT nItemExtentMaxVal = bHorz ? rcItem.right : rcItem.bottom;
INT nAreaExtentMinVal = 0;
INT nAreaExtentMaxVal = bHorz ? (m_rcTabItemsArea.right - m_rcTabItemsArea.left) : (m_rcTabItemsArea.bottom - m_rcTabItemsArea.top);
nAreaExtentMaxVal += __EXTTAB_ADD_END_SCROLL_SPACE + 2;
if( m_nIndexVisFirst < 0 )
{
if( nItemExtentMaxVal >= nAreaExtentMinVal )
m_nIndexVisFirst = nIndex;
}
if( nItemExtentMinVal <= nAreaExtentMaxVal )
m_nIndexVisLast = nIndex;
nVisibleNo++;
}
}
if( nVisibleNo != m_nVisibleItemCount )
return false;
if( m_nIndexVisFirst < 0 || m_nIndexVisLast < 0 )
{
m_nIndexVisFirst = m_nIndexVisLast = -1;
bEnableScrollButtons = false;
}
else
{
if( m_nIndexVisFirst > m_nIndexVisLast )
m_nIndexVisLast = m_nIndexVisFirst;
ASSERT( m_nIndexVisFirst <= m_nIndexVisLast );
ASSERT( 0 <= m_nIndexVisFirst && m_nIndexVisFirst < nItemCount );
ASSERT( 0 <= m_nIndexVisLast && m_nIndexVisLast < nItemCount );
}
ASSERT_VALID( this );
return true;
}
3) The One Note specific layout issue in the
CExtTabOneNoteWnd::OnTabWndUpdateItemMeasure()
method:
void CExtTabOneNoteWnd::OnTabWndUpdateItemMeasure(
CExtTabWnd::TAB_ITEM_INFO * pTii,
CDC & dcMeasure,
CSize & sizePreCalc
)
{
ASSERT_VALID( this );
ASSERT_VALID( pTii );
ASSERT( dcMeasure.GetSafeHdc() != NULL );
ASSERT( pTii->GetTabWnd() == this );
pTii;
dcMeasure;
bool bHorz = OrientationIsHorizontal();
bool bFirstInChain = false;
LONG nIndex = pTii->GetIndexOf();
ASSERT( nIndex >= 0 );
if( nIndex == 0 )
bFirstInChain = true;
else
{
bool bMultiRowColumn = OnTabWndQueryMultiRowColumnLayout();
CExtTabWnd::TAB_ITEM_INFO * pTiiWalk = NULL;
nIndex --;
for( ; true; )
{
pTiiWalk = ItemGet( nIndex );
ASSERT( pTiiWalk != NULL );
bool bVisibleItem = pTiiWalk->VisibleGet();
if( bVisibleItem )
break;
pTiiWalk = NULL;
if( nIndex == 0 )
break;
nIndex --;
}
if( pTiiWalk == NULL )
bFirstInChain = true;
else if( bMultiRowColumn && pTiiWalk->MultiRowWrapGet() )
bFirstInChain = true;
}
if( bHorz )
{
sizePreCalc.cx += (__EXTTAB_ONENOTE_INDENT_LEFT + __EXTTAB_ONENOTE_INDENT_RIGHT);
if( bFirstInChain )
sizePreCalc.cx += 16;
sizePreCalc.cy = 19;
}
else
{
sizePreCalc.cy += (__EXTTAB_ONENOTE_INDENT_LEFT + __EXTTAB_ONENOTE_INDENT_RIGHT);
if( bFirstInChain )
sizePreCalc.cy += 16;
sizePreCalc.cx = 19;
}
}