Professional UI Solutions
Site Map   /  Register


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 Tech Support » How to make CExtControlBar child of CView? Collapse All
Subject Author Date
Offer Har Oct 10, 2008 - 9:38 AM


I need to make a control bar that is a child of a CView derived class, can this be done? how?



Technical Support Oct 11, 2008 - 10:36 AM

First of all, re-dockable control bars can be created inside a frame window only. Non-redockable control bars which are statically placed near a border of their parent window can be created inside any window type. For instance, you can see toolbars created inside the main dialog of ProfUIS_Controls sample application. You can create them exactly in the same way inside your view window. You should only invoke the CWnd::RepositionBars( 0, 0xFFFF, 0 ); code both after creation of all the bars and in the WM_SIZE message handler. This code is needed to place all the bars near the borders of your view window. You will also probably need to know the rectangular area in the center of your view window which is free of any bars. This area will be used in your view’s painting code. Here is how to compute it:

CWnd * pYourViewWindow = . . .
CRect rectFreeOfBarsAtCenter;
      pYourViewWindow->GetClientRect( &rectFreeOfBarsAtCenter );
      pYourViewWindow->RepositionBars( 0, 0xFFFF, 0, CWnd::reposQuery, &rectFreeOfBarsAtCenter, &rectFreeOfBarsAtCenter );
The CExtMenuControlBar, CExtToolControlBar, CExtStatusControlBar, CExtTabbedToolControlBar, CExtRibbonPage and CExtRibbonBar control bars can be created inside any window. The CExtControlBar, CExtDynamicControlBar and CExtPanelControlBar control bars are designed as re-dockable and you should not create them as static control bars because they even unable to occupy the entire available width in horizontal direction nor the entire available height in vertical direction.

If you need re-dockable control bars inside your view window, then you should create a CFrameWnd window with WS_CHILD style inside your view, create all the required control bars inside this frame window and implement a new view window for this frame to occupy its center area. This design is not often used, but we helped our customers to implement it several times. For instance, tehre was a customer project (an ActiveX control) for running inside Internet Explorer’s HTML pages and the entire area of this ActiveX control is covered by the CFrameWnd window created with WS_CHILD style. This frame contained redockable control bars: menu bar, toolbars, resizable control bars and status bar.

Offer Har Oct 13, 2008 - 9:24 AM

The control bar I have is a  CExtControlBar, as it is a dialog embedded in a control bar.

My scenario is that I have some specific views that I don’t want the control bar to get out of, as they are not relevant outside these views. How do you suggest I should implement this kind of architecture? This is a very storg requirement I have, because if these control bars will start ’travel’ between views or to the main frame ther UI will be un-maintainable.

Technical Support Oct 14, 2008 - 4:45 AM

If you need several windows inside one view and these windows do not need to be hidden/show nor re-arranged relatively to each other, you should use a splitter window (the CSplitterWnd class in MFC, the CExtSplitterWnd class in Prof-UIS). If you need the same but, one or more of the following is also required:

1) Some windows inside your view window should be optionally hidden/shown.
2) The user should be able to drag-n-drop windows to change their mutual position or their position should be changed programmatically.
3) The layout of windows inside your view window should be persistent. It should be saved/restored.

Then you should use child frame window inside your view window. It’s not difficult nor complicated as it sounds. Just create a CFrameWnd window using CWnd::Create() method and use your view window as the parent window. Then create inner content of this frame window like it’s small SDI frame based application without MFC’s document/view architecture applied. Of course, your view window should resize its child frame window when view becomes resized.

Please also note, the resizable control bars without caption work and look like panes inside MFC splitter window but you are able to show hide them programmatically and their parent frame window is able to save/restore layout of bars.

Offer Har Oct 15, 2008 - 6:47 AM

I’m implemented the child fraem as you suggested, but there are a couple of problems.:


1) When I drag the control-bar (move it around) I see the guide 4 handles, and the guide locations, but for some reason they leave some space on each size of the view as you can see in the screenshot below.

2) When I dock the control-bar, it acts like it is docking, but the control bar just disappear - is there any more initialization I need to perform?

3) The most problematic of all - I can still take the control-bar outside the view - my major requirement is that the control-bar will not leave the view, as the data in it is relevat only to that spefici view.


This what I did in OnInitialUpdate of my view:

    CRect rc;

    m_pChildFrm = new CFrameWnd;
    m_pChildFrm->Create(NULL, "RON", WS_CHILD, rc, this);

This is the spacing problem:



Technical Support Oct 16, 2008 - 12:37 PM

1) Please check the styles with which your child frame window is created and all its chain of parent windows. We guess one or more windows have un-needed borders provided by WS_EX_CLIENTEDGE, WS_EX_STATICEDGE and/or WS_EX_DLGMODALFRAME extended window styles.

2) Please make sure that the child frame window and all its parent chain of windows have WS_CLIPSIBLINGS|WS_CLIPCHILDREN window styles. We suspect the control bar is simply over-painted by some window(s).

3) There are two types of control-bar drag-n-dropping algorithms: Visual Studio .NET like and Visual Studio 2005/2008 like. In the first case the target dropping areas are shown using prediction frames and the drag-n-dropped control bar does not become floating until you drop it. In the second case the docking markers (also known as guide diamonds) are used and drag-n-dropped control bar really becomes floating during drag-n-dropping. You can override the CExtControlBar::FloatControlBar() virtual method and do not invoke the parent class method in it. Such resizable control bars will not become floating. But this approach is not very friendly to the Visual Studio 2005/2008 like drag-n-dropping algorithm based on docking markers. So, probably you will need to turn on the Visual Studio .NET like drag-n-dropping algorithm for your bars.

Offer Har Oct 24, 2008 - 7:07 AM

About 2 - This does not work... I tried adding WS_CLIPSIBLINGS|WS_CLIPCHILDREN everywhere I could and it did nothing. I have a feeling that something conceptual is not working there. Did you check that this is even possible?

This is the code to create the child view in my view’s OnInitialUpdate function:

void CMyView::OnInitialUpdate() {     CBaseView::OnInitialUpdate();     CRect rc;     GetClientRect(rc);     m_pChildFrm = new CFrameWnd;     m_pChildFrm->Create(NULL, "RON", WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, rc, this);     m_pChildFrm->EnableDocking(CBRS_ALIGN_ANY);     ModifyStyle(0, WS_CLIPSIBLINGS|WS_CLIPCHILDREN);     // Enable control bars in the frame window to be re-dockable     if(!CExtControlBar::FrameEnableDocking(m_pChildFrm))     {         TRACE0("CExtControlBar::FrameEnableDocking Failed\n");         ASSERT( FALSE );     }     // Enable auto-hide feature for re sizable control bars     if(!CExtControlBar::FrameInjectAutoHideAreas(m_pChildFrm))     {         TRACE0("CExtControlBar::FrameInjectAutoHideAreas Failed\n");         ASSERT( FALSE );     }


Please let me know what is missing, or if possible send me a sample application demontsting this feature.



Technical Support Oct 27, 2008 - 2:23 PM

The MDI child frame windows are also kind of child frame windows. They are the same type of windows like we advised you to create. You can see both resizable control bars and toolbars inside child frames in the MDI_InnerOuterBars sample application and there are no un-needed borders there. Is there any reason why you are creating control bars outside your child frame class? We recommend you to code it as small SDI frame based project: create control bars in its OnCreate() handler method.

Offer Har Oct 27, 2008 - 2:47 PM

What do you mean by "creating control bars outside your child frame class"?

The motivation for all this task is to bave a control bar that is inside a view, cannot leave it and dock inside it.

I have an MDI application, and I have control-bars that must not leave the view.

Did I miss anything?

Offer Har Oct 24, 2008 - 6:57 AM

About 1- I have added


In PreCreateWindow of my child frame, and the same problem still happens. Please check what can cause all these problems.

Offer Har Oct 24, 2008 - 5:37 AM

About 2- what do you mean? I create the view and child frame ’by the book’... what do I need to change there?

Offer Har Oct 24, 2008 - 5:36 AM

About 3 - You did not answer to my point - I want the bar to by a child of the view / child frame, hence, will be be able to be dragged out of the view at all.

Offer Har Oct 14, 2008 - 1:51 PM

Thanks for the detailed explanation - I do need the more complex scenario, so I will try that out.

One thing that is not clear to me - currently my view draws stuff into the view using OnDraw - in this architecure change will this have any effect on the drawing?



Technical Support Oct 16, 2008 - 12:33 PM

The OnDraw() method always knows whether it’s invoked for painting or for printing due to the CDC::IsPrinting() method. But in the real world, applications can use exactly the same code for painting and printing only in the case of some simple graphic documents.