Resizable Docking Window 2

of Dundas.

This development of this source code was partially sponsored by Dundas Software, and is also used to implement stacked docking dialog bars in these Dundas Software's MFC components - Ultimate Diagram and the HyperView scriptable forms environment.

Features

Resizable control bar, that can be resized both when docked and when floating.
Multiple sizing control bars can be docked on the same row/column.
Dynamic resizing when docked.
State persistence support (SaveState/LoadState).
Gripper with "hide bar" flat button.
No custom resources were used (bitmaps, cursors, strings, etc.), so the integration is easier and you have full control over the resources you eventually use in derived classes.
Easy to use: just derive your own control bar(s) from CSizingControlBar then add your child controls.

Environment: VC++ 5.0, 6.0; Win95/98 and NT 4.0; UNICODE enabled.

The functionality is somewhat like DevStudio's control bars. However, the look is not the same, as the main goal was to get an easy to use class. Personally, I like it how it is now, but feel free to send me your suggestions.

Instructions

Derive a class from CSizingControlBar (you have an example in mybar.h and mybar.cpp).
Add a member variable to CMainFrame (in mainfrm.h).

CMyBar m_wndMyBar;

Create the bar in CMainFrame::OnCreate(). Then set bar styles, enable it to dock... like any control bar.

if (!m_wndMyBar.Create(_T("My Bar"), this, CSize(200, 100),
    TRUE /*bHasGripper*/, AFX_IDW_CONTROLBAR_FIRST + 32))
{
    TRACE0("Failed to create mybar\n");
    return -1;      // fail to create
}

m_wndMyBar.SetBarStyle(m_wndMyBar.GetBarStyle() |
    CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

m_wndMyBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndMyBar, AFX_IDW_DOCKBAR_LEFT);

Remarks

This class is intended to be used as a base class. Do not simply add your code to the sizecbar.* files - instead create a new class derived from CSizingControlBar and put there what you need.

Window IDs: You can see above that the control bar is created with the ID AFX_IDW_CONTROLBAR_FIRST + 32. The usage of IDs in the range of AFX_IDW_CONTROLBAR_FIRST + 32 .. AFX_IDW_CONTROLBAR_LAST is required only if the bar will not be enabled for docking (that's is - it will stay fixed right under the frame's menu). But in this situation you won't be able to fully use the features of this class, so if you will enable it to dock (a reasonable guess :) then you can use any valid window ID.
Another place where the IDs are important is the saving/loading of the bar's state. You must use different IDs for each control bar that is enabled to dock, and this includes the other bars too. For example, if you have two toolbars, you can create the first one with the default ID (which is AFX_IDW_TOOLBAR = AFX_IDW_CONTROLBAR_FIRST), but the second one must have a different ID.

OnUpdateCmdUI: This member function is pure virtual in CControlBar (the base class of CSizingControlBar). Its purpose is to allow updating of controls at idle time (from here CCmdUI::DoUpdate() is called for the toolbars' buttons, dialogbars' controls, the panes of status bar, etc.).
However, I found it very useful to update the look of the "x" flat button (no timers needed). So, if you will use this function, don't forget to call the base class' member (see mybar.cpp).

Dynamic resizing: This feature allows redrawing of the bar during resizing. Also all the bars are repositioned and redrawn if necessary.
The SPI_GETDRAGFULLWINDOWS system parameter is queried for this (it is enabled by the "Show window contents while dragging" checkbox in Display Properties).

State persistence: The common MFC control bars' docking state is saved using CMainFrame::SaveBarState(). In addition to the info saved by this function, the CSizingControlBar class needs to save 3 sizes. This is done in CSizingControlBar::SaveState() function, so a m_wndMyBar.SaveState() call is required. Please note that the state storing code must be placed in CMainFrame::DestroyWindow(), not in OnDestroy(), because at the time WM_DESTROY message is received, the floating bars are already destroyed.
In CMainFrame::OnCreate(), the m_wndMyBar.LoadState() call must be placed before LoadBarState().
Alternatively, if you have multiple CSizingControlBar derived bars, you can call once the static member CSizingControlBar::GlobalSaveState() instead of calling each bar's SaveState(). The same for LoadState() - there is a CSizingControlBar::GlobalLoadState() function. See both samples here for more details.

Enjoy !

Updates since the first release:

  • (1)
  • The control bar color will change automatically if the user changes the system colors.
  • It is no longer necessary to override the RecalcLayout() member function of CMainFrame. The control bar will handle this internally.
  • Simplified the child controls size updating (see mybar.cpp).
  • Replaced IsHorz() member function with IsHorzDocked(). Also added IsVertDocked().
  • Restructured background and non-client painting so you can use memory DC painting in client area.
  • Made public the size member variables. In this way, the size of the control bar can be saved and/or changed anytime you want (see mainfrm.cpp).
  • Added a gripper. It can be disabled if you don't like it.
  • Added a string parameter for the control bar title in Create().
  • Modified Create() to avoid an ASSERT that prevented the code to run under Visual C++ 6.0 .
  • (2)
  • Added the dynamic resizing feature.
  • Another Create() fix for VC 6.0.
  • Moved OnUpdateCmdUI() to CMyBar sample derived class.
  • Enforced a maximum size for resizing.
  • (3)
  • Added multiple bars/row docking support.
  • Added the "x" - like button for hiding the bar.
  • Added state persistence support.
  • Made the client area smaller - now you can use GetClientRect() to get the new rectangle for child(ren) position in OnSize().
  • OnUpdateCmdUI() is back in CSizingControlBar. If you use it for updating controls, call the base class' member too.
  • Major rewrite, a few bugs fixed, etc.

Download demo projects - 65k

Download source - 12k



Comments

  • cSizingControlBar/"SHOW WINDOW CONTENTS WHILE DRAGGING" to cristip@dudas.com :->

    Posted by kenshee on 09/26/2005 11:32pm

    good day, nice work about resizing the form , do you have a translated version of you "SCBDEMO" to c#.net or vb.net? because i think you solved my problem, i saw your code in c++.net but i cant understand the code, coz im not a c++ programmer, can you please help me about creating my own "SHOW WINDOW CONTENTS WHILE DRAGGING" without using the systemparameterinfo because this affect the windows settings. it nice because it doesnt flicker when you are resizing the "MYAPPBAR" dialog. sorry for my poor english, tnx in advance....GOD BLESS.. pls email me for you reply batusai_hrd@yahoo.com, tnx, tnx, tnx

    Reply
  • HELP - cSizingControlBar/"SHOW WINDOW CONTENTS WHILE DRAGGING"

    Posted by kenshee on 09/26/2005 11:30pm

    good day, nice work about resizing the form , do you have a translated version of you "SCBDEMO" to c#.net or vb.net? because i think you solved my problem, i saw your code in c++.net but i cant understand the code, coz im not a c++ programmer, can you please help me about creating my own "SHOW WINDOW CONTENTS WHILE DRAGGING" without using the systemparameterinfo because this affect the windows settings. it nice because it doesnt flicker when you are resizing the "MYAPPBAR" dialog. sorry for my poor english, tnx in advance....GOD BLESS..

    Reply
  • dialog bar hiding problem

    Posted by mails_aphale on 06/25/2005 07:19am

    when dilaog bar is docked, it works fine ie. it gets shown & hidden properly. but if i keep it floating, instead of dialog bar, custom control in it gets shown/hidden. can somebody help me with that? it's urgent

    Reply
  • dialog bar hiding problem

    Posted by mails_aphale on 06/25/2005 07:17am

    when dilaog bar is docked, it works fine ie. it gets shown & hidden properly. but if i keep it floating, instead of dialog bar, custom control in it gets shown/hidden. can somebody help me with that? it's urgent

    Reply
  • How to resize on clicking on cross buton

    Posted by kamal on 12/22/2004 07:57am

    Hi Clicking on cross button i want to resize the controll bar instead of hiding it. how to do that

    Reply
  • How do I enable Add Variable button of the VC++ ClassWizard Window?

    Posted by Legacy on 12/29/2003 12:00am

    Originally posted by: Birbal Chaudhary

    Hello,
    I am fresh, begginer and willing to learn VC++. I am creating a project called "Controls". I have added some controls such as editbox, combobox, group box, buttons and check boxes and would like to add codes on the edit box and run ClassWizard and select the Member Variable tab bu the Add Variable button is disabled. So, what could be wrong and how can I enable it?

    Reply
  • Compile error under VS.Net 2003

    Posted by Legacy on 08/22/2003 12:00am

    Originally posted by: Justin

    "sizecbar.cpp(1296) : error C2065: 'afxChNil' : undeclared identifier"
    I change 'afxChNil' to NULL, it works, But I don't know if it will bring any negative effect. Is there any better way to solve this problem? Thanks.

    Reply
  • Very nice

    Posted by Legacy on 07/15/2003 12:00am

    Originally posted by: PathFinder

    Very nice work! I hope I could find it earlier.

    Reply
  • http://www.codejock.com

    Posted by Legacy on 06/08/2003 12:00am

    Originally posted by: The Best GUI Tools - VS.NET and Office XP/2003 Look!

    http://www.codejock.com

    Reply
  • How to intercept messages from the built in system menu from a floating window

    Posted by Legacy on 01/13/2003 12:00am

    Originally posted by: matt fassiotto

    This has been a very useful bit of code.  I've not had to modify the base class CSizingControlBar at all.  Of course, I've tailored the mybar class to our needs.  One thing I'm trying to figure out is how to intercept messages from the system menu that is built in to the Floating Window.  Using spy and debugging the mfc source I have determined that the class CMiniFrameWnd is receving these messages.  The frame gets created whenever I call ToggleDocking() which results in a floating window having a child of type CMiniFrameWnd .  The code below mimicks behavior similar to many apps like VC++ when turning docking off via a context menu.  I am trying to customize the system menu so I can close the document instead of hiding it. Here is some code that gets the system menu via the aforementioned frame, but I am baffled as to how one would receive the system messages in the parent class. 
    
    

    void mybar::HandleMenuEvent(UInt32 menuCmd)
    {
    ASSERT(m_pDockContext != NULL);
    if(!IsDockable()) //returns m_isDockable
    {
    EnableDocking(CBRS_ALIGN_ANY);
    m_isDockable = true;
    m_pDockContext->ToggleDocking();
    }
    else
    {
    EnableDocking(0);
    m_isDockable = false;

    m_pDockContext->ToggleDocking();

    CFrameWnd* theFrame = GetDockingFrame();

    if(theFrame)
    {
    CMenu* theMenu = theFrame->GetSystemMenu(FALSE);
    theMenu->AppendMenu(MF_BYPOSITION | MF_ENABLED | MF_STRING | MF_CHECKED ,eDocking,"Enable Docking");
    theMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
    theMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
    theMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
    theMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
    theMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
    theMenu->AppendMenu(MF_STRING|MF_ENABLED, SC_CLOSE, "Close");
    }
    }

    }

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: September 10, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild". This loop of continuous delivery and continuous feedback is …

  • Live Event Date: September 19, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT In response to the rising number of data breaches and the regulatory and legal impact that can occur as a result of these incidents, leading analysts at Forrester Research have developed five important design principles that will help security professionals reduce their attack surface and mitigate vulnerabilities. Check out this upcoming eSeminar and join Chris Sherman of Forrester Research to learn how to deal with the influx of new device …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds