Forum
Please
Log In
to post a new message or reply to an existing one. If you are not registered, please
register.
NOTE: Some forums may be read-only if you are not currently subscribed to
our technical support services.
Subject |
Author |
Date |
|
renier
|
Jun 8, 2009 - 8:39 AM
|
Is there any way to get hold of the left top grid outer cell (i.e. the one at position (-1;-1) )?
|
|
Technical Support
|
Jun 8, 2009 - 10:57 AM
|
First of all, your grid window should have at least one outer header column at top and one header row on left. If this true, then you can instantiate header cells at top/left corner: CExtGridWnd & wndGrid = . . .
LONG nColNo = 0; // column index relatively to part of the grid (outer header part at top/bottom/left/right, outer corner part or inner data part)
LONG nRowNo = 0; // row index relatively to part of the grid (outer header part at top/bottom/left/right, outer corner part or inner data part)
INT nColType = -1; // -1 - header or corner area at left, 0 - middle data area, 1 - header or corner area at right
INT nRowType = -1; // -1 - header or corner area at top, 0 - middle data area, 1 - header or corner area at bottom
CExtGridCell * pCell = wndGrid.GridCellGet( nColNo, nRowNo, nColType, nRowType, RUNTIME_CLASS( CExtGridCellHeader ) );
pCell->TextSet( _T("top-left"));
|
|
tera tera
|
Jun 8, 2009 - 12:17 AM
|
Hello. When only one tab is displayed , I want to non-display a tab domain.
Is this impossible?
|
|
Technical Support
|
Jun 8, 2009 - 10:59 AM
|
It’s possible to make the CExtTabWnd window and any other CExtTabWnd -derived tabs invisible when there is only one tab item displayed. You should override the CExtTabWnd::OnTabWndSyncVisibility() virtual method and hide the tab window when it have only one tab item or zero tab items. All the MDI tab controls in Prof-UIS use the following overridden version of the CExtTabWnd::OnTabWndSyncVisibility() virtual method for hiding tab window when the tab item count is zero:
virtual void OnTabWndSyncVisibility()
{
LONG nItemCount = ItemGetCount();
LONG nItemVisibleCount = ItemGetVisibleCount();
DWORD dwWndStyle = GetStyle();
if( nItemCount > 0
&& nItemVisibleCount > 0
&& (!( CExtControlBar::FindPrintPreviewMode(
STATIC_DOWNCAST( CFrameWnd, GetParent() )
)
|| CExtControlBar::IsOleIpObjActive(
STATIC_DOWNCAST( CFrameWnd, GetParent() )
)
) )
)
{
if( (dwWndStyle & WS_VISIBLE) == 0 )
{
::SetWindowPos(
m_hWnd,
NULL, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER
|SWP_FRAMECHANGED
|SWP_SHOWWINDOW
);
HWND hWndMdiArea = _GetHwndMdiArea();
if( hWndMdiArea != NULL )
::SetWindowPos(
hWndMdiArea,
NULL, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER
|SWP_FRAMECHANGED
);
}
} // if( nItemCount > 0 ...
else
{
if( (dwWndStyle & WS_VISIBLE) != 0 )
::SetWindowPos(
m_hWnd,
NULL, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER
|SWP_NOSENDCHANGING
|SWP_HIDEWINDOW
);
} // else from if( nItemCount > 0 ...
dwWndStyle = GetStyle();
if( (dwWndStyle & WS_VISIBLE) == 0 )
m_nIndexVisFirst = m_nIndexVisLast = -1;
}
You can use this source code in your tabs class and hide the tab window if the number of tabs is less or equal to 1 . The Prof-UIS tab page containers have the same method even with the same name for synchronizing visibility of inner tab window: void CExtTabPageContainerWnd::OnTabWndSyncVisibility()
{
ASSERT_VALID( this );
if( GetSafeTabWindow() == NULL )
return;
LONG nItemCount = m_pWndTab->ItemGetCount();
LONG nItemVisibleCount = m_pWndTab->ItemGetVisibleCount();
DWORD dwWndStyle = m_pWndTab->GetStyle();
if( nItemCount > 0
&& nItemVisibleCount > 0
&& m_bTabWndVisible
)
{
if( (dwWndStyle & WS_VISIBLE) == 0 )
m_pWndTab->SetWindowPos(
NULL, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_FRAMECHANGED|SWP_SHOWWINDOW
);
}
else
{
if( (dwWndStyle & WS_VISIBLE) != 0 )
m_pWndTab->SetWindowPos(
NULL, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_HIDEWINDOW
);
}
}
This method also does not hide tabs with only one tab item visible. So, if you are using tab page container control, then you can override the CExtTabPageContainerWnd::OnTabWndSyncVisibility() virtual method and hide tabs with one visible tab item.
|
|
marc uchida
|
Jun 4, 2009 - 11:11 AM
|
Hello,
I posted a problem in 2007 that was never replied to. The issue has arisen again so I am re-posting.
see
http://www.prof-uis.com/prof-uis/tech-support/support-forum/exttabwnd-_syncallitems-changes-to-avoid-assertion-failure-57956.aspx .
The problem is related to a perceived logic error in ExtTabWnd’s _SyncAllItems().
Here is a clipping from that function with my notes inline...
ModifyTabWndStyle(
bCloseEnabled ? 0 : __ETWS_ENABLED_BTN_CLOSE,
bCloseEnabled ? __ETWS_ENABLED_BTN_CLOSE : 0,
false
);
INT nVisibleCount = 0;
for( ; hWndMdiChild != NULL; hWndMdiChild = ::GetWindow( hWndMdiChild, GW_HWNDNEXT ) )
{
// you code is checking for visibility property now
if( ( ::GetWindowLong( hWndMdiChild, GWL_STYLE ) & WS_VISIBLE ) != 0 )
nVisibleCount ++;
// your code now checks for handle
LONG nIndexExist = ItemFindByHWND( hWndMdiChild, -1, true, true );
if( nIndexExist >= 0 )
{
// should the above visibility check be done here instead, after the handle is checked??
if( ( ::GetWindowLong( hWndMdiChild, GWL_STYLE ) & WS_VISIBLE ) != 0 )
nVisibleCount ++;
if( hWndMdiChild == pWndActiveMdiChild->GetSafeHwnd() )
SelectionSet( nIndexExist, true, false );
continue;
}
ItemInsert(
NULL,
NULL, false,
0,
-1,
LPARAM( hWndMdiChild ),
false
);
In general, it seems like the code would be better served if the property is checked after a valid handle is confirmed.
Can this be changed for your next version? This will save us from having to continue employing an override of the _SyncAlItems() function and checking it each time you do a new release.
thanks for you time,
marc, vorum research
|
|
Technical Support
|
Jun 5, 2009 - 3:57 AM
|
We probably lost your forum message because of site maintenance. We are sorry.
Here is the loop with code statement inside:
for( ; hWndMdiChild != NULL; hWndMdiChild = ::GetWindow( hWndMdiChild, GW_HWNDNEXT ) )
{
if( ( ::__EXT_MFC_GetWindowLong( hWndMdiChild, GWL_STYLE ) & WS_VISIBLE ) != 0 )
nVisibleCount ++;
LONG nIndexExist = ItemFindByHWND( hWndMdiChild, -1, true, true );
if( nIndexExist >= 0 )
{
if( hWndMdiChild == pWndActiveMdiChild->GetSafeHwnd() )
SelectionSet( nIndexExist, true, false );
continue;
}
ItemInsert(
NULL,
NULL, false,
0,
-1,
LPARAM( hWndMdiChild ),
false
);
if( hWndMdiChild == pWndActiveMdiChild->GetSafeHwnd() )
SelectionSet( ItemGetCount()-1, true, false );
} // for( ; hWndMdiChild != NULL; hWndMdiChild = ::GetWindow( hWndMdiChild, GW_HWNDNEXT ) )
Only the valid MDI child frame window handles are reviewed by this loop’s statement. If the tab item does not exist for the currently enumerated window handle, then the tab item is added, otherwise not. It’s not important where to count visible MDI child frames if the window handles are always valid.
|
|
tera tera
|
Jun 4, 2009 - 4:27 AM
|
Hello. About a button existing in the status bar. In this key customize dialog ,
I want to customize the keys of status bars. Is not there the schedule improving a program?
|
|
Technical Support
|
Jun 4, 2009 - 5:05 AM
|
Please override the CExtRibbonPage::OnRibbonBuildCommandCategories() virtual method in your CExtRibbonBar -derived class. Your method should look like this: virtual void C__YOUR__RibbonBar::OnRibbonBuildCommandCategories( CExtCustomizeCmdTreeNode * pNode, __EXT_MFC_SAFE_LPCTSTR strCommandCategoryName = NULL)
{
//
// Invoke parent class method first:
//
CExtRibbonBar::OnRibbonBuildCommandCategories( pNode, strCommandCategoryName );
if( strCommandCategoryName != NULL )
return;
//
// Built your custom command categories or update existing command categories here.
// You should use the CExtCustomizeSite::Category***() methods.
// As result, your commands from the bottom toolbar will appear in the keyboard customization dialog box.
//
}
|
|
tera tera
|
Jun 5, 2009 - 3:02 AM
|
Hello. For example, how should I make a program when I add IDM_OUTSIDE_MENU1? _MuMakeRibbnoNodeNormal(
_T("OUTSIDE_MENU1"), _T(""), _T(""),
IDM_OUTSIDE_MENU1,
NULL,
IDB_BLANK_PAGE_SMALL,
pRibbonGroup
); pRibbonNodeTabPage->InsertNode( NULL, pRibbonGroup ); RibbonShowHide( false , pRibbonNodeTabPage ); } bool XXXXX::RibbonShowHide( bool blShowFlag , CExtCustomizeCmdTreeNode * pNode )
{
if ( pNode == NULL ){
return false;
} if ( ( pNode->GetFlags() & __ECTN_TBB_HIDDEN ) == 0 ){
if ( blShowFlag == false ){
pNode->ModifyFlags( __ECTN_TBB_HIDDEN );
return true;
}
}else{
if ( blShowFlag == true ){
pNode->ModifyFlags( 0, __ECTN_TBB_HIDDEN );
return true;
}
}
return false;
}
Because I want to display it in Quick Access , I made IDM_OUTSIDE_MENU1-RibbonNode of the non-display and customized it.
In addition, I got possible to perform a decision of the key to IDM_OUTSIDE_MENU1 input by making a IDM_OUTSIDE_MENU1-RibbonNode. If there is a better method, please teach it.
Thanks,
|
|
Technical Support
|
Jun 5, 2009 - 11:43 AM
|
The CExtRibbonBar::_OnCmdRibbonQuickAccessToolbarAddTo() method inserts new ribbon nodes into the quick access toolbar. It contains the ready to use code for this task. You should simply insert new ribbon node as child of the node returned by the Ribbon_GetQuickAccessRootNode() method. The new node should be marked with the __ECTN_RIBBON_QA_CLONED_COPY style. Then you should create new toolbar button using the OnRibbonCreateBarButton() method and attach new node to it. Finally you should update ribbon bar’s layout.
The CExtRibbonBar::_OnCmdRibbonQuickAccessToolbarAddTo() method inserts cloned copy of the toolbar button into the quick access toolbar. The source toolbar has the m_nHelperCtxIndexQA and the pRibbonNode pointer specifies its ribbon node. Then this method creates the new pButton button and the new pNewRibbonNode ribbon node and inserts them into quick access toolbar.
|
|
tera tera
|
Jun 4, 2009 - 4:04 AM
|
Hello. I want to always draw background colors of the caption title of the bars with blue.
Please teach a way.
|
|
Technical Support
|
Jun 9, 2009 - 12:32 PM
|
We changed the declaration of the CExtDynAutoHideSlider class to fix this issue:
class __PROF_UIS_API CExtDynAutoHideSlider
: public CWnd
, CExtPmBridge
{
protected: ///////////////////////////////////////////////////////// THIS LINE WAS ADDED
HWND m_hWndAnimateSrc, m_hWndBar;
public: ///////////////////////////////////////////////////////// THIS LINE WAS ADDED
CExtDynAutoHideArea * _GetWndAnimateSrc();
CExtControlBar * _GetBar();
protected: ///////////////////////////////////////////////////////// THIS LINE WAS ADDED
//CExtDynAutoHideArea * m_pWndAnimateSrc;
//CExtControlBar * m_pBar;
CSize m_sizeControlBar;
bool m_bActiveState:1;
bool m_bWndActive:1;
bool m_bDeactivateTesting:1;
bool m_bAnimation:1;
UINT m_nResizingMode;
INT m_nResizingStart, m_nResizingMetric;
CExtBarNcAreaButton
* m_pLastHitTestM,
* m_pLastHitTestT,
* m_pLastHitTestB;
CToolTipCtrl m_wndToolTip;
CRect m_rcMax;
void _AnalyzeButtonsHover();
. . .
Please also do not add the following line into the MuControlBar.cpp file: IMPLEMENT_DYNCREATE( CMuControlBar, CExtControlBar );
Then you can do a small experiment in your test project. You can find the following lines in the CMuControlBar::DoPaintNC() method: if( pFlashingBar->FlashCaptionIsInProgress( &bFlashCaptionHighlightedState ) )
{
_pgd.m_bFlashCaptionHighlightedState = bFlashCaptionHighlightedState;
_pgd.m_clrFlashCaptionText = pFlashingBar->m_clrFlashCaptionText;
_pgd.m_clrFlashCaptionBackground = pFlashingBar->m_clrFlashCaptionBackground;
if( pFlashingBar->FlashCaption_DoPaintNC(
*pDC,
(LPVOID)(&_pgd)
)
)
bDrawDefaultCaption = false;
} // if( pFlashingBar->FlashCaptionIsInProgress( &bFlashCaptionHighlightedState ) )
And replace them with the following lines: <pre>// if( pFlashingBar->FlashCaptionIsInProgress( &bFlashCaptionHighlightedState ) ) { _pgd.m_bFlashCaptionHighlightedState = true; // bFlashCaptionHighlightedState; _pgd.m_clrFlashCaptionText = RGB(255,255,0); // pFlashingBar->m_clrFlashCaptionText; _pgd.m_clrFlashCaptionBackground = RGB(255,0,0); // pFlashingBar->m_clrFlashCaptionBackground; if( pFlashingBar->FlashCaption_DoPaintNC( *pDC, (LPVOID)(&_pgd) ) ) bDrawDefaultCaption = false; } // if( pFlashingBar->FlashCaptionIsInProgress( &bFlashCaptionHighlightedState ) ) <pre>As a result, each CMuControlBar window will have red caption with yellow text on it. Here is the modified version of your project: http://www.prof-uis.com/download/forums/tmp/MDI-for-tera.zip
|
|
Technical Support
|
Jun 4, 2009 - 4:47 AM
|
You should override the CExtControlBar::DoPaintNC() virtual method. This method paints the non-client area (including borders and caption/gripper) for all Prof-UIS control bars. You can copy the source code from the original method and then modify it. The following part of the CExtControlBar::DoPaintNC() paints a caption: CExtPaintManager::PAINTGRIPPERDATA _pgd(
pFlashingBar, // this
rcGrip,
rcText,
IsBarWindowActive(),
false,
bHorz && !bGripperAtTop,
!bFixedMode,
sCaption.IsEmpty() ? LPCTSTR( NULL ) : sCaption,
( (g_ResourceManager->OnQueryLangLayout()&LAYOUT_RTL) != 0 ) ? true : false
);
bool bDrawDefaultCaption = true, bFlashCaptionHighlightedState = false;
if( pFlashingBar->FlashCaptionIsInProgress( &bFlashCaptionHighlightedState ) )
{
_pgd.m_bFlashCaptionHighlightedState = bFlashCaptionHighlightedState;
_pgd.m_clrFlashCaptionText = pFlashingBar->m_clrFlashCaptionText;
_pgd.m_clrFlashCaptionBackground = pFlashingBar->m_clrFlashCaptionBackground;
if( pFlashingBar->FlashCaption_DoPaintNC(
*pDC,
(LPVOID)(&_pgd)
)
)
bDrawDefaultCaption = false;
} // if( pFlashingBar->FlashCaptionIsInProgress( &bFlashCaptionHighlightedState ) )
if( bDrawDefaultCaption )
{
PmBridge_GetPM()->PaintGripper( *pDC, _pgd );
NcButtons_Paint( *pDC );
} // if( bDrawDefaultCaption )
The CExtControlBar class supports the caption flashing feature. This feature is very similar to what you need. The flashing captions of the CExtControlBar windows are implemented using timer based caption repainting: one period of time is an alternative caption background is painted and next period of time is the standard themed caption is painted. You need to do the similar thing but without timers.
|
|
tera tera
|
Jun 5, 2009 - 1:57 AM
|
I performed the derivation of the class
Because the following functions are protection, I cannot access it. if( pFlashingBar->FlashCaption_DoPaintNC(
|
|
Technical Support
|
Jun 5, 2009 - 11:42 AM
|
We made public the following methods of the CExtControlBar class :
bool FlashCaption_DoPaintNC(
CDC & dc,
LPVOID pPGD
);
virtual void FlashCaption_OnRepaint();
|
|
tera tera
|
Jun 7, 2009 - 8:27 PM
|
>We made public the following methods of the CExtControlBar class : Will it be necessary to copy a source in the user side?
When I copy a source in the user side
An error comes at the following points. void CMuControlBar::FlashCaption_OnRepaint()
{
ASSERT_VALID( this );
ASSERT( GetSafeHwnd() != NULL );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( AutoHideModeGet())
{
CFrameWnd * pFrame = GetParentFrame();
ASSERT_VALID( pFrame );
ASSERT( pFrame->GetSafeHwnd() != NULL );
ASSERT( ! pFrame->IsKindOf( RUNTIME_CLASS( CExtMiniDockFrameWnd ) ) );
CExtDynAutoHideArea * pDAHA = NULL;
CWnd * pWnd = pFrame->GetWindow( GW_CHILD );
for( ; pWnd != NULL; pWnd = pWnd->GetWindow( GW_HWNDNEXT ) )
{
CExtDynAutoHideArea * pDAHA2 = DYNAMIC_DOWNCAST( CExtDynAutoHideArea, pWnd );
if( pDAHA2 == NULL )
continue;
LONG nIndex = pDAHA2->FindControlBar( this );
if( nIndex < 0 )
continue;
pDAHA = pDAHA2;
break;
}
if( pDAHA->IsWindowVisible() )
pDAHA->Invalidate();
CExtDynAutoHideSlider * pDAHS = pDAHA->GetAutoHideSlider();
if( pDAHS != NULL
&& pDAHS->_GetBar() == this
Should I download the support version from Prof-UIS com?
|
|
Technical Support
|
Jun 8, 2009 - 10:58 AM
|
Please add the following lines to the top of the .CPP file where source code of the CMuControlBar::FlashCaption_OnRepaint() method is present: #if ( ! defined __EXT_MFC_NO_TAB_CONTROLBARS )
#if ( ! defined __EXT_CONTROLBAR_TABBED_FEATURES_H )
#include <../Src/ExtControlBarTabbedFeatures.h>
#endif
#endif
|
|
tera tera
|
Jun 8, 2009 - 7:18 PM
|
|
|
Rado Manzela
|
Jun 2, 2009 - 3:37 PM
|
My progam worked in previous versions (€currently 2.84), but after I’ve switched to 2.85 it crashes when I call CExtTreeGridDataProvider::TreeNodeSortChildren() while implementing my recursive sort. Line 1218 in exttreegridwnd.cpp is addressing array behind upper bound by 1. Line is: pNode = m_arrGridVis[ nExpandedOffsetSrc + nIndex ]; // nExpandedOffsetSrc=17, nIndex=1; array size = 18 Do you have idea what could be wrong? Thank you.
|
|
Technical Support
|
Jun 4, 2009 - 1:13 PM
|
Your sorting method is based on the standard sorting. It does not clone or re-create tree nodes and all the HTREEITEM handles are the same after resorting. This means your sorting does not produce invalid HTREEITEM handles and should work without any assertion failures. We re-checked the sorting in the FilteredGrids sample application and in the http://www.prof-uis.com/download/forums/test_tree_grid_idea.zip test project and it works. So, we suppose this assertion depends on some conditions specific for your project and we had to ask you to help us reproduce it with our sample/test projects.
|
|
Rado Manzela
|
Jun 9, 2009 - 12:06 PM
|
Just create 2 items in root, like "b" and "a" (so that it will have to be swapped). Each item must have child, but NOT expanded (tree should look like [+] A
[+] B Then click at column heading to sort it and it will assert. Let me know if you won’t be able to reproduce it, I’ll send some project for you. Thank you
|
|
Technical Support
|
Jun 11, 2009 - 2:23 AM
|
Thank you for reporting the bug. You can fix it by updating the following two methods:
bool CExtTreeGridDataProvider::_Tree_NodeExpand(
CExtTreeGridCellNode * pNode,
INT nActionTVE // = TVE_TOGGLE // TVE_COLLAPSE, TVE_EXPAND, TVE_TOGGLE only
)
{
ASSERT_VALID( this );
ASSERT_VALID( pNode );
ASSERT(
nActionTVE == TVE_COLLAPSE
|| nActionTVE == TVE_EXPAND
|| nActionTVE == TVE_TOGGLE
);
bool bExpanded = pNode->TreeNodeIsExpanded();
if( nActionTVE == TVE_TOGGLE )
{
if( bExpanded )
nActionTVE = TVE_COLLAPSE;
else
nActionTVE = TVE_EXPAND;
}
if( nActionTVE == TVE_EXPAND )
{
if( bExpanded )
return false;
pNode->TreeNodeMarkExpanded( true );
ULONG nWeightVisible = pNode->_ContentWeight_CalcVisible();
if( pNode->TreeNodeIsDisplayed() )
{
ULONG nOffset = pNode->TreeNodeCalcOffset( true, false );
if( nWeightVisible != 0 )
{
m_arrGridVis.InsertAt( ++ nOffset, NULL, nWeightVisible );
pNode->_Content_FillVisibleArray( m_arrGridVis, nOffset );
}
}
pNode->_ContentWeight_Increment( nWeightVisible, true );
}
else
{
if( ! bExpanded )
return false;
ULONG nWeightVisible = pNode->_ContentWeight_CalcVisible();
pNode->TreeNodeMarkExpanded( false );
if( pNode->TreeNodeIsDisplayed() )
{
ULONG nOffset = pNode->TreeNodeCalcOffset( true, false );
if( nWeightVisible != 0 )
m_arrGridVis.RemoveAt( nOffset + 1, nWeightVisible );
}
pNode->_ContentWeight_Decrement( nWeightVisible, true );
}
return true;
}
ULONG CExtTreeGridCellNode::_ContentWeight_CalcVisible() const
{
ASSERT_VALID( this );
if( TreeNodeHiddenGet() )
return 0L;
if( ! TreeNodeIsExpanded() )
return 0L;
ULONG nCount = TreeNodeGetChildCount();
ULONG nCalcVal = 0;
for( ULONG nIdx = 0; nIdx < nCount; nIdx++ )
{
const CExtTreeGridCellNode * pNode = TreeNodeGetChildAt( nIdx );
ASSERT_VALID( pNode );
if( pNode->TreeNodeHiddenGet() )
continue;
nCalcVal ++;
if( pNode->TreeNodeIsExpanded() )
nCalcVal += pNode->_ContentWeight_CalcVisible();
}
return nCalcVal;
}
|
|
Rado Manzela
|
Jun 12, 2009 - 11:46 AM
|
|
|
Technical Support
|
Jun 3, 2009 - 5:32 AM
|
This looks like memory damage or invalid HTREEITEM usage. Please help us reproduce this error. We need to know how did you implement your recursive sorting?
|
|
Rado Manzela
|
Jun 3, 2009 - 12:06 PM
|
Here is my implementation (I call it at root item): void CChildView::SortRecursive(HTREEITEM item, const CExtGridDataSortOrder &_gdso,CExtTreeGridDataProvider & _DP)
{
CExtTreeGridCellNode * pNode = CExtTreeGridCellNode::FromHTREEITEM( item );
ASSERT_VALID( pNode );
_DP.TreeNodeSortChildren( pNode, _gdso, this ) ;
HTREEITEM sItem;
for (sItem = ItemGetFirstChild(item); sItem; sItem = ItemGetNext(sItem,true,false,true))
{
if (ItemGetChildCount(sItem) < 2)
continue;
SortRecursive(sItem,_gdso,_DP);
}
}
|
|
tera tera
|
Jun 1, 2009 - 11:37 PM
|
Hello. With the following sample
http://ifreeta.dee.cc/20090508/RibbonBarMDI.lzh When I execute MenuRebuild,
Quick accelerator information of ClipBorad which I added is deleted. As the specifications that I expect
I perform MenuReuild ,
But please do not erase the QuickAccess information of clipborad.
|
|
Technical Support
|
Jun 11, 2009 - 9:25 AM
|
We improved the CExtRibbonBar and CExtRibbonPage classes. Now the SetButtons() method works and causes no crashes. Please drop us an e-mail to the support mail box at this web site so we will provide you with the FTP download for the source code update.
|
|
tera tera
|
Jun 11, 2009 - 7:12 PM
|
Thank you for a revision.
I am saved.
By the way,
Does not MenuRebuild have any problem in following program-code? void MenuRebuild( CExtRibbonNode * pRibbonNode )
{
CMemFile _file;
CArchive arSave( &_file, CArchive::store );
MenuInfoGetDefault()->AccelTableSerialize( arSave );
arSave.Close(); //
//
// PROF-UIS TECH SUPPORT
// The folloiwing code snippet fixes the assertion problem.
// You are reinitializing the ribbon bar control using
// the same command tree as was used in it before.
// But after the quick access toolbar customization, this command tree
// contains some temporarily command nodes.
// So, such command tree should not be assigned to the ribbon bar again.
// The code snippet below just cleans temporarily command nodes.
//
// //CExtRibbonNodeQuickAccessButtonsCollection * pNodeColQATB = Ribbon_GetQuickAccessRootNode();
//INT nIndex, nCount = pNodeColQATB->GetNodeCount();
//for( nIndex = 0; nIndex < nCount; )
//{
// CExtCustomizeCmdTreeNode * pNode = pNodeColQATB->ElementAt( nIndex );
// if( pNode == NULL )
// {
// nIndex ++;
// continue;
// }
// ASSERT_VALID( pNode );
// if( (pNode->GetFlags()&__ECTN_RIBBON_QA_CLONED_COPY) != 0 )
// {
// pNode->RemoveSelf( NULL );
// nCount --;
// continue;
// }
// else
// {
// pNode->ModifyFlags( 0, __ECTN_TBB_HIDDEN );
// nIndex ++;
// continue;
// }
//} // for( nIndex = 0; nIndex < nCount; ) SetButtons( NULL );
SetButtons( pRibbonNode );
_file.Seek( 0, CFile::begin );
CArchive arLoad( &_file, CArchive::load );
MenuInfoGetDefault()->AccelTableSerialize( arLoad );
arLoad.Close();
_RecalcPositionsImpl();
CMDIFrameWnd * pFrame = (CMDIFrameWnd *)AfxGetMainWnd();
OnUpdateCmdUI( pFrame , TRUE );
//
// PROF-UIS TECH SUPPORT
// We are sorry, we forgot to invoke the following line of code
// which updates in-MFC accelerator tables:
//
OnUpdateAccelGlobalInfo( true ); RedrawWindow( NULL, NULL, RDW_INVALIDATE|RDW_ALLCHILDREN );
CExtPaintManager::stat_PassPaintMessages();
}; };
|
|
Technical Support
|
Jun 12, 2009 - 5:59 AM
|
This will work because we tested the latest ribbon bar using the same version of the MenuRebuild() method. Of course, we also checked the accelerator table restoring.
|
|
Technical Support
|
Jun 3, 2009 - 4:33 AM
|
We are trying to improve the ribbon bar’s source code and make the SetButtons() method working without any preliminary and final serializations and without removing temporarily command nodes as we did in scope of your project. Please give us 2-3 days more.
|
|
tera tera
|
Jun 8, 2009 - 6:17 PM
|
Hi I want you to teach the revision days.
I want a revision soon. Give my best regards.
|
|
Technical Support
|
Jun 9, 2009 - 12:29 PM
|
We are sorry but the requested ribbon bar improvement is not finished yet. It requires some serious modification of the ribbon bar initialization and serialization procedures. Please give us a few days more.
|
|
tera tera
|
Jun 2, 2009 - 12:35 AM
|
|
|
tera tera
|
Jun 2, 2009 - 5:58 PM
|
I am troubled.
I ask for an answer.
|
|
armond glover
|
Jun 1, 2009 - 8:45 PM
|
Hi,
In our application, user has the capability to change the text and icon of any command on the toolbar. He can also drag commands to any toolbar, such that one command is present in more than one toolbar. I use the following code such that if he changes command text from "abc" to "abc1", it should be reflected to all instances of the button in various toolbars.
CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr(strProfileName, nCmdID);
pCmdItem->m_sToolbarText = ptrCust->name;
This does not work. What should i do.
Regards
Armond
|
|
Technical Support
|
Jun 2, 2009 - 12:55 PM
|
If you are using simple non-customizable toolbars, the CExtCmdItem::m_sToolbarText property is used as is and it defines text for toolbar buttons. If you changes it, you should recompute the layout of toolbar’s parent frame window.
If you are using customizable toolbars and menus, the CExtCmdItem::m_sToolbarText property is used for storing initial command’s text to be displayed in toolbar buttons. This initial text is used when user reset’s toolbar buttons via context menu in the customize mode. The customizable toolbar buttons are using text stored in the CExtCustomizeCmdTreeNode command tree node objects. The CExtCustomizeCmdTreeNode::GetTextInToolbar() and CExtCustomizeCmdTreeNode::SetTextInToolbar() methods are used for accessing and modifying the command’s text in toolbar. This text is initialized from the CExtCmdItem::m_sToolbarText property initially. Each cloned copy of the same command is able to keep and display different text because user can customize each toolbar button independently from each other. You should know that you can drag-n-drop customizable toolbar buttons and create copies of them. You also can create new toolbars. This means if you want to change text of some command in all its toolbar buttons, then you should analyze all the command trees of all the toolbars and all the menu objects too. The CExtCustomizeSite::CCmdMenuInfo menu information objects can be accessed using the CExtCustomizeSite::MenuInfo***() methods. The CExtCustomizeSite::CCmdMenuInfo::GetNode() can be used for accessing the active and initial command trees of the menu line. The CFrameWnd::m_listControlBars property contains all the control bars created inside the frame window. You should walk through all of them and review all the CExtToolControlBar objects but not the CExtMenuControlBar object. This is how you can enumerate all the toolbars. The CExtToolControlBar::GetCustomizeSite() method of each toolbar returns pointer to the customize site instance or NULL. This is how you can detect customizable toolbars. The CExtCustomizeSite::GetToolbarCmdNode() method returns pointer to the active or initial toolbar’s command tree node. Please note, the user defined toolbars created in the customize mode does not have initial command tree and does not support resetting in the customize mode. The CExtCustomizeSite::IsUserBarCommand() method can be used for checking whether toolbar is the user defined toolbar. This method should receive toolbar’s dialog control identifier in parameter. Now you can get root command tree nodes of each menu line and each toolbar. The next steps are: walk recursively through each command tree, detect commands to assign text in toolbar and/or to change other command properties by command identifier, change text in toolbar, etc. Finally you will need to redraw all the toolbars and, optionally, the menu bar for refreshing all the changed commands. The CExtCustomizeSite::RedrawCommandItems() does this work. It can refresh all the instances of the specified command in toolbars and menus.
In both cases (simple and customizable), if your code massively changes many toolbar commands, then you may have reason simply recompute layout of the main frame window and all the floating frame windows:
CMainFrame * pMainFrame = . . .
pMainFrame->RecalcLayout();
pMainFrame->RedrawWindow( NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN );
CExtControlBar::stat_RedrawFloatingFrames( pMainFrame );
CExtControlBar::stat_RecalcBarMetrics( pMainFrame );
|
|
Chris Anderson
|
Jun 1, 2009 - 6:02 PM
|
We are seeing significant performance degradation when a large number of records are added to the grid. Our product is currently built using 2.83. We do not see a similar problem when running the samples with v 2.84. Are there known performance fixes that can be applied manually from 2.84 to 2.83? Thanks.
|
|
Chris Anderson
|
Jun 2, 2009 - 5:25 PM
|
I’m comparing debug versions of 2.83 vs 2.84. Can you tell me if there are any performance fixes between these two version that I can apply?
|
|
Technical Support
|
Jun 3, 2009 - 5:42 AM
|
We have not changed the scrolling code, mouse and keyboard handling code in Prof-UIS grids since 2.83. The 2.83 and later grids should have exactly the same speed. Please review the following things:
1) Do not use the mouse hover events and effects based on it if your grid displays 50 rows and 30 columns at the same time on the screen.
2) Do not use in-memory grid if you have 5000 rows or columns in it. Switch to a virtually cacheable grid like demonstrated in the AdoRecordsetView sample application.
3) Do not repaint the entire grid if you need to repaint only one cell. The CExtGridWnd::GridCellRectsGet() method can compute rectangle of the grid cell which you then can use in the CWnd::Invalidate() method.
4) Do not repaint the grid window on timer very often, especially if your grid displays 50 rows and 30 columns at the same time on the screen. The Grid dialog page in the ProfUIS_Controls sample application is repainted on timer because this is needed for animated grid cells in the slider column. But this grid is not large.
5) Check all the timer based code, idle time based code and command updating code in your project. If such code is heavy, than it can decrease performance of anything.
Besides, the latest version is 2.85 rather than 2.84.
|
|
Technical Support
|
Jun 2, 2009 - 12:55 PM
|
Grid controls are 100 times slower in debug mode than they are in release mode. We are using heavy assertions everywhere in grids related code. Please check the release version.
|
|
David Skok
|
Jun 1, 2009 - 9:32 AM
|
I use ModifyStyle( 0, __ETWS_MULTI_ROW_COLUMN ) before any items inserted and I do not get multirow. Is there something else I have to do to get multiple rows of tabs rather than scrolled tabs? D.
|
|
Technical Support
|
Jun 1, 2009 - 1:18 PM
|
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;
}
}
|
|
Gevork Odabashyan
|
Jun 1, 2009 - 5:16 AM
|
|
|
Gevork Odabashyan
|
Jun 2, 2009 - 12:48 AM
|
Thanks for quick reply, can you say, when this fix for multi-monitor resizing, will be included into official release version?
|
|
Technical Support
|
Jun 2, 2009 - 12:40 PM
|
Yes, this issue fix is included into the next release.
|
|
Technical Support
|
Jun 1, 2009 - 1:19 PM
|
The skinned window non client area support code in Prof-UIS 2.85 fixes a very important issue related to the non-selected Windows Task Bar’s buttons on application startup. It looks like this issue fix re-created the issue related to the multi-monitor resizing. We re-checked both issues. Please update the .../Prof-UIS/ExtNcFrame.cpp source code file:
http://www.prof-uis.com/download/forums/tmp/ExtNcFrame.cpp
|
|
Gevork Odabashyan
|
Jun 2, 2009 - 12:49 AM
|
Thanks for quick reply, can you say, when this fix for multi-monitor resizing, will be included into official release version?
|
|
Gevork Odabashyan
|
Jun 1, 2009 - 5:29 AM
|
|
|
Neville Franks
|
May 27, 2009 - 3:31 AM
|
I have a CExtResizableDialog inside CExtPageNavigatorWnd inside a CExtResizableDialog and Keyboard accelerators aren’t being processed. ex. VK_F5, ID_TreeShowAllFolders, VIRTKEY BEGIN_MESSAGE_MAP(CKnowledgeTreePageDLG, CExtResizableDialog)
//{{AFX_MSG_MAP(CKnowledgeTreePageDLG)
ON_WM_SIZE()
ON_COMMAND_EX( ID_TreeShowAllFolders, OnDespatchCommand )
.....
//}}AFX_MSG_MAP
END_MESSAGE_MAP() When F5 is pressed CKnowledgeTreePageDLG::OnDespatchCommand() isn’t called. Originally there was only a CExtResizableDialog and this code worked correctly, but since putting it inside CExtPageNavigatorWnd which is inside a CExtResizableDialog it doesn’t. I have a Toolbar button which does ID_TreeShowAllFolders and it does call CKnowledgeTreePageDLG::OnDespatchCommand(). So it appears to be just a keyboard problem. Cwnd::OnWndMsg() for the CKnowledgeTreePageDLG never gets a WM_COMMAND message when F5 is pressed.
|
|
Neville Franks
|
May 28, 2009 - 1:09 AM
|
Thanks, I added the following code to my xxx::::PreTranslateMessage() function and which resolved this issue. HACCEL m_hAccelTable = pMainFrame()->MenuInfoGetDefault()->AccelTableGet( false );
if ( m_hAccelTable )
{ // Note pMainFrame()->m_hWnd not this->m_hWnd so it handles the commands..
if ( ::TranslateAccelerator( pMainFrame()->m_hWnd, m_hAccelTable, pMsg ) )
{
return TRUE;
}
}
|
|
Technical Support
|
May 28, 2009 - 11:42 AM
|
Your code snippet is absolutely OK.
|
|
Technical Support
|
May 27, 2009 - 12:52 PM
|
The CDialog class pre-translates keyboard messages differently, not like the CFrameWnd class does. You created a page navigator inside a frame window and then created a dialog inside a page navigator. The frame window pre-translates the keyboard messages using its accelerator table. Most of other windows are pre-translating keyboard messages via their parent windows and, as a result, the frame window makes accelerators working. But not the dialog windows. The CDialog class implements the VK_TAB key based focus changing via message pre-translation. Dialogs are not friendly to their parent windows. So, you should implement the PreTranslateMessage() virtual method in your dialog class and use the mail frame’s accelerator table for pre-translating keyboard messages. You can also keep a stand-alone HACCEL accelerator table in your dialog class and use it instead if this is needed.
|
|
Robert Webb
|
May 26, 2009 - 2:20 AM
|
Hi, Is there a way to catch the event when we switch to a different tab in the ribbon bar? (Either because user clicks on it, or keyboard navigation was used, or Ribbon_PageSelectionSet() was called). I need a callback for that case, and need to know the old and new tabs/pages. Can it be done? Thanks, Rob.
|
|
Technical Support
|
May 26, 2009 - 2:01 PM
|
The CExtRibbonBar::Ribbon_PageSelectionSet() method is virtual and you can override it to catch the ribbon tab page selection changing event. The CExtRibbonBar::Ribbon_PageSelectionGet() method can be invoked in your overridden method before invoking the parent class method. This is how you can get index of the previously selected ribbon tab page. Please note, the previous selected page index can be -1 if there were no selected ribbon tab pages. But the CExtRibbonBar::Ribbon_OnPageSelectionChanging() virtual method is more handy for catching the ribbon page selection changing because its provides you both new and old indices in parameters.
|
|
tera tera
|
May 25, 2009 - 9:11 PM
|
Hello. I have already made it here....
|
|
tera tera
|
May 25, 2009 - 6:39 PM
|
Hello. >// PROF-UIS TECH SUPPORT
>The folloiwing code snippet fixes the assertion problem.
>You are reinitializing the ribbon bar control using
>the same command tree as was used in it before.
>But after the quick access toolbar customization, this command tree
>contains some temporarily command nodes.
>So, such command tree should not be assigned to the ribbon bar again.
>The code snippet below just cleans temporarily command nodes. Thank you for support.
The Assert does not occur.
The program works. However, The Quick accelerator information that I customized becomes invalid.
I hope to maintain the setting information of the Quick accelerator.
Will the repair of the program be difficult?
Give my best regards. http://www.prof-uis.com/prof-uis/tech-support/support-forum/ribbonmenu-question-part2-64504.aspx
|
|
Technical Support
|
May 26, 2009 - 2:02 PM
|
We visited your desktop and fixed the accelerators issue by adding the OnUpdateAccelGlobalInfo( true ); line of code.
|
|
tera tera
|
May 26, 2009 - 7:06 PM
|
Hello. The program does not yet work well. I add clipborad.
After MenuRebuild , clipborad which I added disappears.
ClipBorad which I added ,
Please do not delete it. Please cope.
I move a remote PC today.
|
|
Technical Support
|
May 27, 2009 - 1:12 PM
|
Yes, of course it disappears. We reset the ribbon nodes after re-assigning the root node. We suspected that is what you really need. You can use the CExtRibbonBar::CustomizeStateSerialize() method instead of accelerator table serialization and ribbon node re-assignment and the quick access toolbar will be restored. But in this case your menu rebuilding method will simply does nothing. So, we need to know more details about your task.
|
|
tera tera
|
May 27, 2009 - 7:01 PM
|
Hello. Can you meet the following specifications? When ClipBorad is displayed, QA-ClipBorad is enable When ClipBorad is non-displayed, QA-ClipBorad is not enable ( QA = QuickAccessButton ) Give my best regards
|
|
Technical Support
|
May 29, 2009 - 11:01 AM
|
|
|
tera tera
|
May 28, 2009 - 11:53 PM
|
Hello. I’m sorry.
The specifications that I hope for are as follows. Anyway, I set it in this setting window.
Please do not erase the QuickAccess information. I perform MenuReuild ,
but Please do not erase the QuickAccess information
|
|
tera tera
|
May 28, 2009 - 6:09 PM
|
I ask for an answer.
I am troubled
Give my best regards
|
|
tera tera
|
May 26, 2009 - 7:12 AM
|
Today, I started a remote PC.
|
|
tera tera
|
May 22, 2009 - 3:09 AM
|
|
|
Technical Support
|
May 23, 2009 - 11:47 AM
|
We have 3 white columns with fixed size. We have one blue column and it’s resizable. We have one magenta column with fixed size. First of all we need to get the header cells for this column from the top header row:
CExtGridWnd & wndGrid = . . .
CExtGridCell * pHeaderCellWhite0 = wndGrid.GridCellGetOuterAtTop( 0L, 0L );
CExtGridCell * pHeaderCellWhite1 = wndGrid.GridCellGetOuterAtTop( 1L, 0L );
CExtGridCell * pHeaderCellWhite2 = wndGrid.GridCellGetOuterAtTop( 2L, 0L );
CExtGridCell * pHeaderCellBlue = wndGrid.GridCellGetOuterAtTop( 3L, 0L );
CExtGridCell * pHeaderCellMagenta = wndGrid.GridCellGetOuterAtTop( 4L, 0L );
Then, we need to set the proportional extents for these columns: pHeaderCellWhite0->ExtentPercentSet( 0.0 );
pHeaderCellWhite1->ExtentPercentSet( 0.0 );
pHeaderCellWhite2->ExtentPercentSet( 0.0 );
pHeaderCellBlue->ExtentPercentSet( 1.0 );
pHeaderCellMagenta->ExtentPercentSet( 0.0 );
That’s all. These columns will be automatically resizable like demonstrated on your video. But if you want to disable resizing of the white and magenta columns by user, then you also should set the fixed widths of their columns in pixels: INT nSomeWidthInPixels = . . .
pHeaderCellWhite0->ExtentSet( nSomeWidthInPixels, -1 );
pHeaderCellWhite0->ExtentSet( nSomeWidthInPixels, 0 );
pHeaderCellWhite0->ExtentSet( nSomeWidthInPixels, 1 );
pHeaderCellWhite1->ExtentSet( nSomeWidthInPixels, -1 );
pHeaderCellWhite1->ExtentSet( nSomeWidthInPixels, 0 );
pHeaderCellWhite1->ExtentSet( nSomeWidthInPixels, 1 );
pHeaderCellWhite2->ExtentSet( nSomeWidthInPixels, -1 );
pHeaderCellWhite2->ExtentSet( nSomeWidthInPixels, 0 );
pHeaderCellWhite2->ExtentSet( nSomeWidthInPixels, 1 );
pHeaderCellMagenta->ExtentSet( nSomeWidthInPixels, -1 );
pHeaderCellMagenta->ExtentSet( nSomeWidthInPixels, 0 );
pHeaderCellMagenta->ExtentSet( nSomeWidthInPixels, 1 );
|
|
tera tera
|
May 24, 2009 - 6:40 PM
|
Thank you very much for your advice.
The program worked well.
|
|
tera tera
|
May 19, 2009 - 9:07 PM
|
Hello. I do not want to display the shadow of the tool tip.
Should I set a flag?
|
|
Technical Support
|
May 20, 2009 - 5:03 AM
|
The code to remove a shadow from all tooltips:
CExtPopupMenuSite::g_DefPopupMenuSite.GetTip().SetShadowSize( 0 );
But the ribbon bar control displays ribbon screen tips which are not tooltips. To remove a shadow from ribbon screen tips, you should implement the following virtual method in your CExtRibbonBar -derived class: virtual CExtPopupMenuTipWnd * OnAdvancedPopupMenuTipWndGet(
CObject * pHelperSrc = NULL,
LPARAM lParam = 0
) const
{
CExtPopupMenuTipWnd * pTip = __PARENT_CLASS__::OnAdvancedPopupMenuTipWndGet( pHelperSrc, lParam );
If( pTip != NULL )
pTip->SetShadowSize( 0 );
return pTip;
}
|
|
Kevin Murray
|
May 19, 2009 - 12:04 PM
|
Is there a plan for the Prof-UIS library to support Windows 7, and if so, what is the time table on that support? K.
|
|
Technical Support
|
May 20, 2009 - 5:05 AM
|
At this moment we tested only release versions of Prof-UIS sample applications on Windows 7 and they are working exactly in the same way like they do on Windows Vista. We used Windows 7 without any Visual Studio versions installed on it and without any other software installed on it. The sample applications with the statically linked Prof-UIS are simply running on Windows 7 without any problems. The sample applications compiled with Prof-UIS as DLL are also running without any problems if the Prof-UIS DLL is available on the same computer. At this moment we are trying to find the most correct way to solve the "The application failed to initialize properly (0xc0000135)" problem when running the Prof-UIS based applications on Windows 7 under the following conditions:
1) The message box with this error message appears on the Windows 7 screen when we run the release version of the Prof-UIS based application which is based on Prof-UIS as DLL and there is no required DLL of the Prof-UIS library is present on the Windows 7 computer.
2) This error occurs on Windows 7 when running any debug version of Prof-UIS / DLL based application even if all the Prof-UIS / MFC / Visual C++ run time libraries are copied into the same folder with the Prof-UIS / DLL based application.
Please note, we have used the clean Windows 7 OS. We didn’t installed any Visual Studio on it. We didn’t installed any other software on it. We just copied Prof-UIS sample applications and run it. So, we can assume Prof-UIS 2.84 and 2.85 versions are 95% compatible with the Windows 7 OS. They will be exactly 100% compatible only after the official release of the Windows 7 which can differ from any beta and release candidate versions. In conclusion, the current version of the manifest resource embedded into all the Prof-UIS sample applications and all the applications generated with the Prof-UIS Application Wizard is enough to run on Windows 7 desktop. But we cannot be 100% that it’s will be enough to run on the release version of Windows 7.
|
|
Nicholas Vezirgiannis
|
May 19, 2009 - 5:22 AM
|
Hallo sir, I’m using your Prof-UIS project for almost 2 years now and everything seems fine. Now the project needs have raised a question. Is it possible to somehow put a COMBOBOX in a TOOLBAR, instead of buttons? Combining combobox and buttons in a dockable toolbar would be ideal. Please respond with example code or detailed guidelines on how to do this with your interface. Thanks for all your help in advance.
|
|
Nicholas Vezirgiannis
|
May 25, 2009 - 10:03 AM
|
Thank you for your responce it was very helpful. I have created the combo box in the toolbar and I have derived a class out of the CExtComboBox to catch the OnCBSetCurSel event. Unfortunatelly this event does not run when I am changing the selection of the combobox. Please tell me if I am using the wrong event or if I have an error in the derived class and how to correct it. My derivation code follows. Thanks in advance for all your help.
CPageSelectionCombo : public CExtComboBox
public :
CPageSelectionCombo();
~CPageSelectionCombo();
LRESULT CPageSelectionCombo::OnCBSetCurSel(WPARAM wParam, LPARAM lParam);
};
CPageSelectionCombo::CPageSelectionCombo()
{
}
CPageSelectionCombo::~CPageSelectionCombo()
{
}
LRESULT CPageSelectionCombo::OnCBSetCurSel(WPARAM wParam, LPARAM lParam)
{
} int k=0;return CExtComboBox::OnCBSetCurSel(wParam, lParam); class {
|
|
Technical Support
|
May 25, 2009 - 12:49 PM
|
Please add the following line to the message map of your CExtComboBox -derived class: ON_CONTROL_REFLECT( CBN_SELENDOK, OnSelEndOK )
Then please add the following method into the same class: afx_msg void OnSelEndOK();
void CYourComboBoxClassName::OnSelEndOK()
{
ASSERT_VALID( this );
Default();
//
// TO-DO: handle combo box selection changing here
//
}
|
|
Technical Support
|
May 20, 2009 - 10:01 AM
|
There are three different ways to put a combo box into a toolbar:
1) This approach is based on simple toolbars. Just create the CExtComboBox window as child of the CExtToolControlBar window and attach it to some toolbar button using the CExtToolControlBar::SetButtonCtrl() method. You can use the CExtToolControlBar::CommandToIndex() method to get the zero based button index by its command identifier. Indeed, you should create your own CExtComboBox -derived class because you will need to use the message reflection to handle the input events of this combo box. The combo box will be visible when the toolbar is docked horizontally or floating. The toolbar button will be visible in the vertically docked toolbar and in the chevron menu. So, the toolbar button should have an icon and you should handle this button as command. The combo box window is automatically disabled/enabled via MFC command updating mechanism. You can see such combo box controls inside toolbars on the Menubar & Toolbars dialog page in the ProfUIS_Controls sample application. The GLViews sample application uses the CExtComboBox -derived windows in toolbars for configuring view cameras and this is the ready to use code for you.
2) This approach is based on customizable toolbars and menus. The CExtCustomizeSite -based customization subsystem for toolbars and menus supports built-in text and combo fields in toolbars and menus. Please take a look at the StyleEditor sample application. You can see style, font name and font size combo boxes in toolbar and menus there. These combo boxes are not the HWND -based windows attached tool toolbar buttons like described in the first approach. These three combo boxes are built in combo fields supported by the Prof-UIS customization subsystem for toolbars and menus. Such combo fields can be seen in menus, including chevron menu of toolbar. You can drag-n-drop the combo fields with Alt key pressed and you can create cloned copies of them when dropping into new location in toolbars and menus with the Ctrl key pressed. The customization subsystem supports automatic synchronization of such combo field copies. To use such combo fields you should switch using customizable toolbars and menus first:
http://www.prof-uis.com/prof-uis/tech-support/feature-articles/prof-uis-customization-subsystem.aspx
3) This approach is similar to the second, but you can choose more advanced version of the customization subsystem for toolbars and menus. It’s called Prof-UIS Automation Pack or shortly ProfAuto. It’s demonstrated in the ActiveScripts and SimpleScripting sample application. ProfAuto is set of wrapper COM objects for customizable toolbars and menus. It’s discussed here:
http://www.prof-uis.com/prof-uis/tech-support/feature-articles/scripting-support-in-prof-uis-applications.aspx
|
|
tera tera
|
May 19, 2009 - 4:32 AM
|
Hello. To Prof2.84, I was able to print View with the following sample definitely. OK!!
However, I cannot print it to size of the paper from Prof2.85 definitely.
I am troubled.
It is program this of the problem.
http://ifreeta.dee.cc/20090519/SampleMDITest.lzh Give my best regards
|
|
Technical Support
|
May 19, 2009 - 1:30 PM
|
|
|
tera tera
|
May 19, 2009 - 8:46 PM
|
Thank you for a sample
However, The program does not work as before.
Not the resolution of the screen I want to draw with the resolution of the printer.
Number of the x maximum dots 4747.
Number of the y maximum dots 6802.
|
|
Technical Support
|
May 20, 2009 - 12:26 PM
|
|
|
tera tera
|
May 20, 2009 - 10:51 PM
|
I was saved.
Thank you very much for your advice.
|
|