et us assume we have the following:
CExtControlBar * pSomeBar = . . .
CFrameWnd * pMainFrame = . . .
CFrameWnd * pParentFrame = pSomeBar->GetParentFrame();
Then we can compute this:
bool bSingleFloatingBarInItsMiniFrame = pSomeBar->IsFloating();
if( bSingleFloatingBarInItsMiniFrame )
return; // the pSomeBar bar is alone in its floating mini frame window
if( pParentFrame == pMainFrame )
return; // the pSomeBar bar is docked inside the main frame window
Now we know that the
pSomeBar
bar is inside a complex mini frame window. Its parent window is an
CExtDockBar
object. But we need to find the nearest
CExtDockDynBar
parent window which can be either a dynamic horizontal/vertical bar container or a tabbed bar container:
CWnd * pParentWnd = pSomeBar->GetParent();
CExtDockDynBar * pDynDockBar = NULL;
for( ; pParentWnd != pParentFrame; pParentWnd = pParentWnd->GetParent() )
{
pDynDockBar = DYNAMIC_DOWNCAST( CExtDockDynBar, pParentWnd );
if( pDynDockBar != NULL)
break;
}
if( pDynDockBar == NULL )
return;
You should not face a situation when the
pDynDockBar
is NULL. You may come across this only when the resizable bar is being drag-and-dropped.
Now we should check whether the
pDynDockBar
window is a dynamic tabbed bar container:
CExtDockDynTabBar * pTabbedGroupContainer = DYNAMIC_DOWNCAST( CExtDockDynTabBar, pDynDockBar );
if( pTabbedGroupContainer != NULL )
return; // this is not interesting for us
Now we know that the
pDynDockBar
window is a container for one row or one column of bars and we can walk though all the bars in this container and check where each bar in this container is:
// first check the horizontal or vertical orientation
DWORD dwWndID = (DWORD)pDynDockBar->GetDlgCtrlID();
bool bContainerOrientationIsHorizontal =
( dwWndID == AFX_IDW_DOCKBAR_TOP || dwWndID == AFX_IDW_DOCKBAR_BOTTOM ) ? true : false;
// this pre-processor function is needed for the next step
#if _MFC_VER >= 0x710
#define __ARRAY_ENTRY_IS_PLACEHODLER_MARKER__( __CB__ ) ( ( DWORD_PTR(__CB__) ) <= 0x0FFFF )
#else
#define __ARRAY_ENTRY_IS_PLACEHODLER_MARKER__( __CB__ ) ( ( HIWORD(__CB__) ) == 0 )
#endif
// now we will walk through all the bars in the container
INT nIndexInArray, nCountOfArrayEntries = pDynDockBar->m_arrBars.GetSize();
for( nIndexInArray = 0; nIndexInArray < nCountOfArrayEntries; nIndexInArray ++ )
{
CExtControlBar * pBar = (CExtControlBar *)pDynDockBar->m_arrBars[nIndexInArray];
if( pBar == NULL || __ARRAY_ENTRY_IS_PLACEHODLER_MARKER__( pBar ) )
continue; // pBar is not a valid pointer
//
//
// You can analyze pBar here and detect which of your bars are
// at left/top/right/bottom relative to your other bars
//
//
}