Professional UI Solutions
Site Map   /  Register
 
 

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.

Forums » Prof-UIS General Discussion » Cannot Dock CExtToolControlBar together unless they are visible Collapse All
Subject Author Date
Dave Kymlicka Mar 14, 2005 - 9:32 PM

Your TabPages sample demonstrates how to dock toolbars next to each other using this technique:

DockControlBar(&m_wndToolBar);
RecalcLayout();
CRect wrAlredyDockedBar;
m_wndToolBar.GetWindowRect( &wrAlredyDockedBar );
wrAlredyDockedBar.OffsetRect( 1, 0 );
DockControlBar(&m_wndToolBar2,AFX_IDW_DOCKBAR_TOP,&wrAlredyDockedBar);
RecalcLayout();

However, this article describes a problem with this technique:
<http://www.datamekanix.com/articles/side-by-side/>
"The bars must be visible. If they are not, the RecalcLayout() call does not guarantee the bars’ window sizes and positions."

In our app, toolbar visibility is an issue: we permit user-configurable layouts which can be loaded from user-configurable file(s) at any time. Users can specify which toolbars are docked on which row, and also which toolbars are visible or not.

I am experiencing problems where I cannot dock toolbars together (on the same row) if I hide them all first. If I leave them visible, there’s no problem, all works great.

I’ve tried the solution posted at this site, but it doesn’t work with Prof-UIS, presumeably due to your different docking techniques.

In sample project: TabPages, I tried the following:
DockControlBar(&m_wndToolBar);
m_wndToolBar.DockControlBar(&m_wndToolBar2,true,false,this,true);
However, the resulting asserts don’t look good, and they still aren’t docked together.

Any suggestions on how to reliably dock toolbars together, regardless of their visibility? As you can imagine, making them all visible first, then docking, then hiding.... it’s not a pretty thing to look at. :-(

Technical Support Mar 15, 2005 - 6:17 AM

Dear Dave,

First of all, to specify initial positions of the toolbars (CExtToolControlBar), please use the CFrameWnd::DockControlBar() method rather than CExtControlBar::DockControlBar(). This is also true for the menu bar (CExtMenuControlBar) and panel control bars (CExtPanelControlBar).

Let’s assume you have two toolbars (m_wndToolBar1 and m_wndToolBar2 toolbars which you want to dock into one row and either of them may be initially invisible.


  1. Both control bars are initially visible:
    CRect wrAlredyDockedBar;
    DockControlBar( &m_wndToolBar1 );
    RecalcLayout();
    m_wndToolBar1.GetWindowRect(
       &wrAlredyDockedBar
    );
    wrAlredyDockedBar.OffsetRect( 1, 0 );
    DockControlBar(
       &m_wndToolBar2,
       AFX_IDW_DOCKBAR_TOP,
       &wrAlredyDockedBar
    );
  2. The second control bar is invisible:
    CRect wrAlredyDockedBar;
    DockControlBar( &m_wndToolBar2 );
    RecalcLayout();
    m_wndToolBar2.GetWindowRect(
       &wrAlredyDockedBar 
    );
    DockControlBar(
       &m_wndToolBar1,
       AFX_IDW_DOCKBAR_TOP,
       &wrAlredyDockedBar
    );
    ShowControlBar(
       &m_wndToolBar2,
       FALSE,
       FALSE
    );
    You may have noticed that we docked it in the reverse order. This is required in order to place m_wndToolBar2 after m_wndToolBar1.
  3. The first control bar is invisible:
    CRect wrAlredyDockedBar;
    DockControlBar( &m_wndToolBar1 );
    RecalcLayout();
    m_wndToolBar1.GetWindowRect(
       &wrAlredyDockedBar
    );
    DockControlBar(
       &m_wndToolBar2,
       AFX_IDW_DOCKBAR_TOP,
       &wrAlredyDockedBar
    );
    ShowControlBar(
       &m_wndToolBar1,
       FALSE,
       FALSE
    );
  4. Both control bars are invisible:
    CRect wrAlredyDockedBar;
    DockControlBar( &m_wndToolBar1 );
    RecalcLayout();
    m_wndToolBar1.GetWindowRect(
       &wrAlredyDockedBar
    );
    wrAlredyDockedBar.OffsetRect( 1, 0 );
    DockControlBar(
       &m_wndToolBar2,
       AFX_IDW_DOCKBAR_TOP,
       &wrAlredyDockedBar
    );
    ShowControlBar(
       &m_wndToolBar1,
       FALSE,
       FALSE
    );
    ShowControlBar(
       &m_wndToolBar2,
       FALSE,
       FALSE
    );


Dave Kymlicka Mar 28, 2005 - 8:12 PM

Allow me to clarify: your toolbar docking technique doesn’t work correctly if you hide the toolbars BEFORE you dock them.
I have tried your recommendation, and can verify that the problem still exists.

I can duplicate this problem in your ’TabPages’ sample project. Try hiding the toolbars before you dock them, and you’ll see what I mean.

CMainFrame::OnCreate()
{
........

    DockControlBar(&m_wndMenuBar);

ShowControlBar( &m_wndToolBar, FALSE, FALSE );    // <--- ADD THIS
ShowControlBar( &m_wndToolBar2, FALSE, FALSE ); // <--- ADD THIS

    DockControlBar(&m_wndToolBar);
    RecalcLayout();
    CRect wrAlredyDockedBar;
    m_wndToolBar.GetWindowRect( &wrAlredyDockedBar );
    wrAlredyDockedBar.OffsetRect( 1, 0 );
    DockControlBar(&m_wndToolBar2,AFX_IDW_DOCKBAR_TOP,&wrAlredyDockedBar);
    RecalcLayout();

ShowControlBar( &m_wndToolBar, TRUE, TRUE ); // <--- ADD THIS
ShowControlBar( &m_wndToolBar2, TRUE, TRUE ); // <--- ADD THIS
........

}

The toolbars are definitely not docked the way you intended.

Technical Support Mar 29, 2005 - 7:35 AM

If a control bar has been created but not yet docked, its parent window is the main frame. When you dock it, its parent window changes to the dock bar which is CDockBar in MFC and CExtDockBar in Prof-UIS. That means when the control bar is not initially docked, it resides in the temporary state and you should not operate with it. So, do not call the CFrameWnd::ShowControlBar() method for the control bars that are not completely initialized. Instead, you can create invisible control bars with the CExtControlBar::Create() method. Use all default control bar styles but WS_VISIBLE.

Dave Kymlicka Mar 29, 2005 - 9:33 AM

I can still verify that the problem exists, even after docking the toolbar first.


DockControlBar(&m_wndMenuBar);
DockControlBar(&m_wndToolBar);    // <--- I’ve added this, per your instructions
DockControlBar(&m_wndToolBar2); // <--- I’ve added this, per your instructions
RecalcLayout();

ShowControlBar( &m_wndToolBar, FALSE, FALSE );
ShowControlBar( &m_wndToolBar2, FALSE, FALSE );

// Rearrange toolbars
DockControlBar(&m_wndToolBar);
RecalcLayout();
CRect wrAlredyDockedBar;
m_wndToolBar.GetWindowRect( &wrAlredyDockedBar );
wrAlredyDockedBar.OffsetRect( 1, 0 );
DockControlBar(&m_wndToolBar2,AFX_IDW_DOCKBAR_TOP,&wrAlredyDockedBar);
RecalcLayout();

ShowControlBar( &m_wndToolBar, TRUE, TRUE );
ShowControlBar( &m_wndToolBar2, TRUE, TRUE );


You will see that you get different results, the toolbars do not dock as you intended.
Comment-out the lines that hide the toolbars, and all works fine.

As I’ve explained earlier, I have to re-arrange toolbars at any time in our app, so this isn’t a problem isolated to CMainFrame::Oncreate().

It’s quite simple: if I hide the toolbars first (YES, they have been docked already, SEVERAL TIMES), then they do NOT dock correctly. If I make all toolbars visible FIRST, then execute the SAME DOCKING CODE, they dock perfectly.

So, the SAME code that performs the toolbar docking behaves DIFFERENTLY, if you hide the toolbars first.

Technical Support Mar 29, 2005 - 12:02 PM

Both containers for docked toolbars, which are CExtDockOuterBar in Prof-UIS and the CDockBar in MFC, operate with a layout of visible toolbars only. Your try to make dock bars work with invisible toolbars. So, what actually goes on under the hood? Although an invisible toolbar belongs to the array of toolbars inside a dock bar, it cannot operate with its size and compute how it affects the layout of other toolbars. This is true both for Prof-UIS and MFC toolbars. But Prof-UIS dock bars and toolbars are more complex because they support its own persistent affixment algorithm. Each toolbar is able to keep its desired position. Its real position may be affected by other toolbars but when it is possible each toolbar restores its location maximum closest to the desired location controlled by the persistent affixment algorithm. This algorithm is based on the affixment weight values assigned to each toolbar. The toolbar with the maximum affixment weight has the maximum chance to be located at its desired position. As you can see, both affixment weight values and desired toolbar locations are really persistent after the application restarts. This docking complexity does not allow Prof-UIS dock bars to operate with invisible control bars. Besides, we do not mention other details like a varying toolbar size with hidden buttons inside the toolbar’s chevron button and temporary allocated rows or columns with toolbars when the width/height of the main frame window is too small to keep several toolbars in their original single row/ column.

Dave Kymlicka Mar 29, 2005 - 12:37 PM

Let’s see if I understand you correctly:

1. You have read the web article I mention earlier, and agree with its technical diagnosis: docking hidden toolbars is unpredictable because RecalcLayout() does not function well on hidden toolbars.

2. You also agree with their proposed solution, but only with MFC dock bars. You are stating that ProfUIS dock bars and/or docking techniques/algorithms are too complex to implement a similar solution as mentioned in the article.

3. As a result of 1 & 2, I therefore have no solution or workaround to be able to dock hidden toolbars with ProfUIS.

Is this what you are saying?

Technical Support Mar 30, 2005 - 12:46 AM

Yes, it is. You should not try to dock invisible control bars. We would like to emphasize that you can successfully dock any number of visible control bars and then hide them. This should bring the desired results.