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 » how to manually resize a docked CExtControlBar Collapse All
Subject Author Date
Robert L May 14, 2007 - 12:16 PM

In our application, we need to be able to manually resize a docked CExtControlBar.

The standard MoveWindow function and SetWindowPos function have no effect on a docked CExtControlBar, or at least they didn’t have any effect in the tests that we did so far.

When a bar is docked by itself, we can use the SetInitDesiredSizeHorizontal and SetInitDesiredSizeVertical functions to set the bar’s initial size when it is docked, but this does not work when the bar is docked using the function:

virtual bool DockControlBar(
CExtControlBar * pBar,
bool bHorzBarHalfSplit,
bool bInnerHalfSplit = false,
CFrameWnd * pDockSite = NULL,
bool bRecalcLayout = true
);

We need to dock three bars at the right edge of the main frame’s window. We need to manually set the height of the top and bottom of these three bars, and set the middle bar to fill the remaining space.

Also, for some other bars, we need to set a minimum and maximum value to the CExtControlBar’s width and height, for when the user manually resizes the bar.

Can this be done using the CExtControlBars, or some other existing class? If not, would it be possible to add this feature to a future version of the ProfUIs library?

Technical Support Dec 8, 2007 - 12:36 PM

The universal way is to implement the CalcDynamicLayout() virtual method and return the required size.

Matthew Claus Dec 7, 2007 - 3:06 PM

Dear Technical Support!

We want to fix the minimum size of the docked windows. The technique with overwriting

virtual INT _CalcDesiredMinHW() const;
virtual INT _CalcDesiredMinVH() const;

is not exactly applicable to our case because of we are locked to version 264 for which we made some number of changes.

What should be the fix for CExtControlBar::_RowResizingUpdateState() for version 264? or, at least, what was the change for 280->281?

TIA,
GS, in behalf of Matt Claus

Robert L May 17, 2007 - 9:39 AM

I overrode these two methods of the CExtControlBar class, and this allowed me to set the minimum size of the bars, in pixels, when they are undocked.

However, when the bars are docked, the number returned by these functions does not determine the minimum size of the bars, either in pixels or in percentage of the available space. Returning different values in these functions causes the docked bars to have different minimum sizes, but I have not found any pattern to how the value returned by the function affects the minimum size of the bar.

Here are a few examples, for the minimum size of a bar docked by itself at the left or bottom of the main window:

returning 0 for the minimum width and 0 for the minimum height set the bar’s minimum width to be 0 and the minimum height to be 0

returning 200 for the minimum width and 0 for the minimum height set the bar’s minimum width to be 200 and the minimum height to be 200

returning 0 for the minimum width and 200 for the minimum height set the bar’s minimum width to be 200 and the minimum height to be 400

returning 200 for the minimum width and 200 for the minimum height set the bar’s minimum width to be 400 and the minimum height to be 400

Passing different values to the functions SetInitDesiredSizeFloating, SetInitDesiredSizeHorizontal, and SetInitDesiredSizeVertical does not affect these results. Commenting out the calls to these functions also does not affect these results.



Also, I still need a way to set the bar’s maximum width and height, when docked or undocked.

Technical Support May 18, 2007 - 11:11 AM

We confirm what you reported. Thank you. We declared the following class in MainFrm.h in the SDI sample:

class CMyBar : public CExtControlBar
{
public:
      virtual INT _CalcDesiredMinHW() const
      {
            return 100;
      }
      virtual INT _CalcDesiredMinVH() const
      {
            return 100;
      }
};
and we used it for the bar with color picker in the main frame window:
      CMyBar        m_wndResizableBar2;
This helped us find out what was wrong. You can fix this problem by updating the source code for the CExtControlBar::_RowResizingUpdateState() virtual method:
void CExtControlBar::_RowResizingUpdateState()
{
      ASSERT( m_bRowResizing );
      ASSERT_VALID( m_pDockSite );
CRect rcDockSite;
      m_pDockSite->GetWindowRect( &rcDockSite );
CSize sizeDockMax = rcDockSite.Size() - CSize( _CalcDesiredMinHW(), _CalcDesiredMinVH() );
      if( sizeDockMax.cx <= 0 || sizeDockMax.cy <= 0 )
            return;
CPoint ptCursorScreen( 0, 0 );
      ::GetCursorPos( &ptCursorScreen );
      if( ptCursorScreen.x < g_rcHelperRowResizingLimits.left )
            ptCursorScreen.x = g_rcHelperRowResizingLimits.left;
      if( ptCursorScreen.x > g_rcHelperRowResizingLimits.right )
            ptCursorScreen.x = g_rcHelperRowResizingLimits.right;
      if( ptCursorScreen.y < g_rcHelperRowResizingLimits.top )
            ptCursorScreen.y = g_rcHelperRowResizingLimits.top;
      if( ptCursorScreen.y > g_rcHelperRowResizingLimits.bottom )
            ptCursorScreen.y = g_rcHelperRowResizingLimits.bottom;
CPoint ptCursor( ptCursorScreen );
CRect rcBarWnd;
      GetWindowRect( &rcBarWnd );
CPoint ptDevOffset = -rcBarWnd.TopLeft();
      ptCursor += ptDevOffset;
CRect rcRowResize = _RectRowResizeGet();
CRect rcRowRecalc = _RectRowRecalcGet();
CRect rcRowRecalcUp = _RectRowRecalcUpGet();
bool bHorz = IsDockedHorizontally();
      if( bHorz )
      {
            INT nMin1 = _CalcDesiredMinVH();
            bool bTop = IsDockedAtTop();
            INT nMin2 = bTop
                  ? (ptCursor.y + rcRowResize.Height()/2)
                  : (m_sizeDockedH.cy - ptCursor.y + rcRowResize.Height()/2)
                  ;
            m_nMetricOffset = max( nMin1, nMin2 );
            if( m_nMetricOffset > sizeDockMax.cy )
                  m_nMetricOffset = sizeDockMax.cy;
            if( m_nMetricOffset == m_sizeDockedH.cy )
                  return;
      }
      else
      {
            INT nMin1 = _CalcDesiredMinHW();
            bool bLeft = IsDockedAtLeft();
            INT nMin2 = bLeft
                  ? (ptCursor.x + rcRowResize.Width()/2)
                  : (m_sizeDockedV.cx - ptCursor.x + rcRowResize.Width()/2 )
                  ;
            m_nMetricOffset = max( nMin1, nMin2 );
            if( m_nMetricOffset > sizeDockMax.cx )
                  m_nMetricOffset = sizeDockMax.cx;
            if( m_nMetricOffset == m_sizeDockedV.cx )
                  return;
      }
bool bShowContent = _IsShowContentWhenRowResizing();
      if( bShowContent )
      {
            ExtControlBarVector_t vBars;
            _GetRowExtBars( vBars );
            INT nCountOfBars = (INT)vBars.GetSize();
            ASSERT( nCountOfBars > 0 );
            LONG nDiff = 0;
            for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
            {
                  CExtControlBar * pBar = vBars[ nBar ];
                  ASSERT_VALID( pBar );
                  if( pBar->IsFixedMode() )
                        continue;
                  if( bHorz )
                  {
                        if( nDiff == 0 )
                              nDiff = pBar->m_sizeDockedH.cy - m_nMetricOffset;
                        pBar->m_sizeDockedH.cy = m_nMetricOffset;
                  }
                  else
                  {
                        if( nDiff == 0 )
                              nDiff = pBar->m_sizeDockedV.cx - m_nMetricOffset;
                        pBar->m_sizeDockedV.cx = m_nMetricOffset;
                  }
            }
            m_pDockSite->RecalcLayout();
            ASSERT_VALID( m_pDockBar );
            if( m_pDockBar->IsKindOf( RUNTIME_CLASS( CExtDockBar ) ) )
                  ((CExtDockBar *)m_pDockBar)->OnDynamicLayoutUpdate();
            CExtPaintManager::stat_PassPaintMessages();
            _OnControlBarPositionChange_InRowImpl( this, __ECBPC_ROW_RESIZING, false, false );
            return;
      }
      _DrawResizingTracker( true );
      m_nTrackerOffset = bHorz ? ptCursorScreen.y : ptCursorScreen.x;
      _OnControlBarPositionChange_InRowImpl( this, __ECBPC_ROW_RESIZING, false, false );
      _DrawResizingTracker( false );
}

Robert L May 16, 2007 - 11:54 AM

Yes, the solution you described allows me to manually set the control bar’s initial sizes and positions. Thanks for the help. However, I still need a way to prevent the user from setting the control bar’s width and height below a specific minimum size or above a specific maximum size. Is this possible in the current version of ProfUIs? Does it require creating a subclass of CExtControlBar?

Technical Support May 16, 2007 - 12:09 PM

You should override the following two methods of the CExtControlBar class:

virtual INT _CalcDesiredMinHW() const;
virtual INT _CalcDesiredMinVH() const;
The _CalcDesiredMinHW() virtual method calculates the minimum width and the _CalcDesiredMinVH() does the same for the height.

Technical Support May 15, 2007 - 11:51 AM

The CExtControlBar::DockControlBar() method is obsolete and supported for compatibility issues with older Prof-UIS versions only. Please use the CExtControlBar::DockControlBarInnerOuter() and CExtControlBar::DockControlBarLTRB() methods instead. The CExtControlBar::DockControlBarInnerOuter() method allows you to dock the first control bar into a new row/column of control bars. The width/height of this bar can be set by invoking one of the CExtControlBar::SetInitDesired***() methods. The CExtControlBar::DockControlBarLTRB() method allows you to dock one control relatively to already docked one and specify how much space it should take up.

There is an alternative approach to specifying the initial position of a control bar:
1) Run your application.
2) Specify the desired initial positions of all control bars.
3) Exit the application.
4) Now you have the UI state saved either in the registry or in a file.
5) Include the above data in the installer of your application.