This is interesting, but I have reproduced it in the MDI_DynamicBars sample. First, some history.
When we switched from our previous GUI library to Prof-UIS we lost one feature of the docking system. Namely, when a window was in MDI mode, the old system had on the docking menu an extra popup menu entry labeled "Dock To" with the choices Left, Right, Top, Bottom. Only available in MDI mode, it allowed the user the ability to redock the window to the side they wanted, not simply back to where it was docked before being made into an MDI window. I was tasked with adding this functionality into our new Prof-UIS driven docking system. I did, but it lead to the discovery of a very interesting bug.
Now, to reproduce this is MDI_DynamicBars sample, add the following methods to the CSimpleControlBar class found in MainFrm.h:
LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam ){
LRESULT rc = __super::WindowProc( message, wParam, lParam );
switch( message )
{
case WM_COMMAND:
{
UINT nCmdID = (UINT)wParam;
if( (nCmdID >= 4001) && (nCmdID <= 4004) )
{
DockToSide( nCmdID );
}
}
break;
}
return rc;
}
virtual bool OnInitDbsMenu( CExtPopupMenuWnd * pPopup, HWND hWndTrack, CObject * pHelperSrc, LPARAM lParamHelper = 0 )
{
bool rc = CExtDynamicControlBar::OnInitDbsMenu( pPopup, hWndTrack, pHelperSrc, lParamHelper );
if( (rc == true) &&
(BarStateGet() == CExtDynamicControlBar::__EDBS_DOCUMENT) )
{
CExtPopupMenuWnd* pmenu = new CExtPopupMenuWnd();
pmenu->CreatePopupMenu( m_hWnd );
if( g_CmdManager->CmdIsRegistered( g_CmdManager->ProfileNameFromWnd( m_hWnd ), 4001 ) == false )
{
CExtCmdItem* pItem;
pItem = g_CmdManager->CmdAllocPtr( g_CmdManager->ProfileNameFromWnd( m_hWnd ), 4001 );
pItem->m_sMenuText = "Left";
pItem->StateEnable();
pItem = g_CmdManager->CmdAllocPtr( g_CmdManager->ProfileNameFromWnd( m_hWnd ), 4002 );
pItem->m_sMenuText = "Top";
pItem->StateEnable();
pItem = g_CmdManager->CmdAllocPtr( g_CmdManager->ProfileNameFromWnd( m_hWnd ), 4003 );
pItem->m_sMenuText = "Right";
pItem->StateEnable();
pItem = g_CmdManager->CmdAllocPtr( g_CmdManager->ProfileNameFromWnd( m_hWnd ), 4004 );
pItem->m_sMenuText = "Bottom";
pItem->StateEnable();
}
pmenu->ItemInsert( 4001 );
pmenu->ItemInsert( 4002 );
pmenu->ItemInsert( 4003 );
pmenu->ItemInsert( 4004 );
pmenu->ItemGetInfo( 0 ).SetNoCmdUI( true );
pmenu->ItemGetInfo( 1 ).SetNoCmdUI( true );
pmenu->ItemGetInfo( 2 ).SetNoCmdUI( true );
pmenu->ItemGetInfo( 3 ).SetNoCmdUI( true );
pPopup->ItemInsertSpecPopup( pmenu, -1, "Dock to" );
}
return rc;
}
void DockToSide( int nSide )
{
UINT uiSide = AFX_IDW_DOCKBAR_LEFT;
switch( nSide )
{
case 4001:
uiSide = AFX_IDW_DOCKBAR_LEFT;
break;
case 4002:
uiSide = AFX_IDW_DOCKBAR_TOP;
break;
case 4003:
uiSide = AFX_IDW_DOCKBAR_RIGHT;
break;
case 4004:
uiSide = AFX_IDW_DOCKBAR_BOTTOM;
break;
}
OnMoveChildToBar();
_AffixmentSafeClearOuter();
m_pDockSite->DockControlBar( this, uiSide );
m_pDockSite->ShowControlBar( this, TRUE, FALSE );
m_pDockSite->RecalcLayout();
}
Now this code doesn’t do a lot of error checking or optimization, but it will serve its purpose of demonstrating the bug. Run the app and close all dynamic bars (even the auto-hidden persistent bars). Now, using the menu, open three of the dynamic bars. Dock them to the left, each one docking under the previous by dragging to the appropriate dock marker on the windows.
Now on the bottom most window, select Tabbed Document from the menu. It will become an MDI window. Right click its menu bar and select Dock to and pick Right. The window will dock to the right, only two issues now exist:
1) It docks on the outer most circle. Any attempts to dock to an inner circle will result in problem number 2 (below) immediately.
2) If you drag the dynamic bar off the application (or change the DockToSide method to dock to an inner circle), the other two windows still docked on the left stack on top of each other so that only one is visible, and lots of empty space below it.
This seemingly can only be reproduced with three or more windows. If you attempt to close the application after the aforementioned problem happens, it will ASSERT and crash and such. I have tried changing to the DockToSide code in various ways with various combinations of dock calls, to no avail. Is there a way for me to properly implement this feature and avoid the bug? Is there perhaps a way to change the Prof-UIS library to avoid the bug?
Any help greatly appreciated.
K.