Switching a toolbar from Docked to Floating without restarting app?
-
So my app works using MFC toolbar creation without issue. If I set a flag, I can make it Dock or Float when the program is started using ``m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);``. The code that does it lives in the ``OnCreate`` which of course can only be called once. What I'm looking to do is use my property sheet to allow the user to select the mode of the toolbars ``Docked`` or ``Floating`` which requires a method outside of the ``OnCreate``. So I have two buttons for testing, one to destroy the ``toolbar`` (working) and create which "rebuilds" the toolbar.... I start off with the app in the ``Docked`` mode, then I test by destroying the toolbar and then rebuilding it. The rebuild is where my issue is. On the ``rebuild``, it is "adding" some blank space equivalent to the two toolbars (``Menu`` and ``Button``) and the toolbars ``float``....I can drag it out of where it was docked.....and the floating bar works.....but it "leaves behind" the a non functional version of the ``floating`` toolbar where it was once docked. If I double click the floating bar, it jumps back to its previously docked location. So I'm trying to figure out what is needed to correct my code that partially does what I want.....and fix the artifacts. The code to destroy:
int CMainFrame::OnToolBarDestroy()
{//if (!m\_wndToolBar) //{ // m\_wndOutput.AddStringStatusTab(\_T("Error: Icon toolbar is already removed, action cancelled")); // m\_wndOutput.AddStringDebugTab(\_T("Debug: MainFrame--Error: Icon toolbar is already removed, action cancelled")); // return -1; //} //m\_wndToolBar.Invalidate(); //m\_wndMenuBar.DestroyWindow(); //m\_wndToolBar.DestroyWindow(); //m\_wndToolBar.AdjustDockingLayout(); //RecalcLayout(); //OnToolBarCreate(); //return 0; //CRect rcClientOld; //CRect rcClientNew; //GetClientRect(rcClientOld); //RepositionBars(AFX\_IDW\_CONTROLBAR\_FIRST, AFX\_IDW\_CONTROLBAR\_LAST, 0, reposQuery, rcClientNew); //m\_wndToolBar.ShowPane(FALSE, FALSE, TRUE); // Hide toolbar //RecalcLayout(); CDockingManager myPane; myPane.RemovePaneFromDockManager(&m\_wndToolBar, TRUE, TRUE, TRUE, NULL); m\_wndToolBar.Invalidate(); m\_wndToolBar.DestroyWindow(); myPane.SaveState(); CPaneContainer myContainer; myContainer.RemoveNonValidPanes(); RecalcLayout(); return 0;
}
The code to rebuild the toolbar:
int CMainFrame::OnToolBarCreate()
{
if (m_wndToolBar)
{
m_wndOutput.AddStringStatusTab(_T("Error: Icon toolbar is al -
So my app works using MFC toolbar creation without issue. If I set a flag, I can make it Dock or Float when the program is started using ``m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);``. The code that does it lives in the ``OnCreate`` which of course can only be called once. What I'm looking to do is use my property sheet to allow the user to select the mode of the toolbars ``Docked`` or ``Floating`` which requires a method outside of the ``OnCreate``. So I have two buttons for testing, one to destroy the ``toolbar`` (working) and create which "rebuilds" the toolbar.... I start off with the app in the ``Docked`` mode, then I test by destroying the toolbar and then rebuilding it. The rebuild is where my issue is. On the ``rebuild``, it is "adding" some blank space equivalent to the two toolbars (``Menu`` and ``Button``) and the toolbars ``float``....I can drag it out of where it was docked.....and the floating bar works.....but it "leaves behind" the a non functional version of the ``floating`` toolbar where it was once docked. If I double click the floating bar, it jumps back to its previously docked location. So I'm trying to figure out what is needed to correct my code that partially does what I want.....and fix the artifacts. The code to destroy:
int CMainFrame::OnToolBarDestroy()
{//if (!m\_wndToolBar) //{ // m\_wndOutput.AddStringStatusTab(\_T("Error: Icon toolbar is already removed, action cancelled")); // m\_wndOutput.AddStringDebugTab(\_T("Debug: MainFrame--Error: Icon toolbar is already removed, action cancelled")); // return -1; //} //m\_wndToolBar.Invalidate(); //m\_wndMenuBar.DestroyWindow(); //m\_wndToolBar.DestroyWindow(); //m\_wndToolBar.AdjustDockingLayout(); //RecalcLayout(); //OnToolBarCreate(); //return 0; //CRect rcClientOld; //CRect rcClientNew; //GetClientRect(rcClientOld); //RepositionBars(AFX\_IDW\_CONTROLBAR\_FIRST, AFX\_IDW\_CONTROLBAR\_LAST, 0, reposQuery, rcClientNew); //m\_wndToolBar.ShowPane(FALSE, FALSE, TRUE); // Hide toolbar //RecalcLayout(); CDockingManager myPane; myPane.RemovePaneFromDockManager(&m\_wndToolBar, TRUE, TRUE, TRUE, NULL); m\_wndToolBar.Invalidate(); m\_wndToolBar.DestroyWindow(); myPane.SaveState(); CPaneContainer myContainer; myContainer.RemoveNonValidPanes(); RecalcLayout(); return 0;
}
The code to rebuild the toolbar:
int CMainFrame::OnToolBarCreate()
{
if (m_wndToolBar)
{
m_wndOutput.AddStringStatusTab(_T("Error: Icon toolbar is alHi, I haven't used the MFC classes in nearly a decade but maybe I can help you debug it.
kittmaster wrote:
but it "leaves behind" the a non functional version of the floating toolbar where it was once docked.
My instincts are telling me that the non-client area[^] has expanded down when your CControlBar was created. Can you check for this for me? You can get the non-client area by calling GetWindowRect [^] and subtracting the GetClientRect[^]. If I am correct then you will need to send the WM_NCCALCSIZE message[^] to reclaim your top client area. Best Wishes, -David Delaune
-
Hi, I haven't used the MFC classes in nearly a decade but maybe I can help you debug it.
kittmaster wrote:
but it "leaves behind" the a non functional version of the floating toolbar where it was once docked.
My instincts are telling me that the non-client area[^] has expanded down when your CControlBar was created. Can you check for this for me? You can get the non-client area by calling GetWindowRect [^] and subtracting the GetClientRect[^]. If I am correct then you will need to send the WM_NCCALCSIZE message[^] to reclaim your top client area. Best Wishes, -David Delaune
Hi David, Thanks for responding. I have added the code and executed it, you can see there is a difference result in the image: [http://kittmaster.com/imagedump/codeproject/Toolbar-Difference.png\](http://kittmaster.com/imagedump/codeproject/Toolbar-Difference.png) I'll look to see how to send the ``WM_NCCALCSIZE`` as I've never had to work with this aspect before. Hopefully this will help sort it out!
-
Hi David, Thanks for responding. I have added the code and executed it, you can see there is a difference result in the image: [http://kittmaster.com/imagedump/codeproject/Toolbar-Difference.png\](http://kittmaster.com/imagedump/codeproject/Toolbar-Difference.png) I'll look to see how to send the ``WM_NCCALCSIZE`` as I've never had to work with this aspect before. Hopefully this will help sort it out!
Well, Your Debug window is showing a 39 pixel difference on the Y axis, so the client area size has certainly changed. Go through the CControlBar documentation to make sure there isn't a built-in way to avoid the non-client area resizing. I don't remember off the top of my head. If not then maybe use a sledge hammer to fix it by sending a
WM_NCCALCSIZE
to resize it manually. Best Wishes, -David Delaune -
Well, Your Debug window is showing a 39 pixel difference on the Y axis, so the client area size has certainly changed. Go through the CControlBar documentation to make sure there isn't a built-in way to avoid the non-client area resizing. I don't remember off the top of my head. If not then maybe use a sledge hammer to fix it by sending a
WM_NCCALCSIZE
to resize it manually. Best Wishes, -David DelauneI added this line of code after the difference calculation:
AdjustWindowRectEx(&rect, m_wndToolBar.GetStyle(), FALSE, m_wndToolBar.GetExStyle());
It zeroed out the values but the same ghost blocks still remain. I can't find direct access to that variable you mentioned, any code example/tips you could point me to? Thanks, Chris
-
I added this line of code after the difference calculation:
AdjustWindowRectEx(&rect, m_wndToolBar.GetStyle(), FALSE, m_wndToolBar.GetExStyle());
It zeroed out the values but the same ghost blocks still remain. I can't find direct access to that variable you mentioned, any code example/tips you could point me to? Thanks, Chris
Yeah, So where did you get the idea to use the AdjustWindowRectEx function[^]? This will do nothing for your problem.
kittmaster wrote:
I can't find direct access to that variable you mentioned
I guess you are referring to the WM_NCCALCSIZE[^] window message. Strange that you would use incorrect nomenclatures. I might know a place where you can search for code samples[^]. Good Luck. -Direct Access Dave
-
Yeah, So where did you get the idea to use the AdjustWindowRectEx function[^]? This will do nothing for your problem.
kittmaster wrote:
I can't find direct access to that variable you mentioned
I guess you are referring to the WM_NCCALCSIZE[^] window message. Strange that you would use incorrect nomenclatures. I might know a place where you can search for code samples[^]. Good Luck. -Direct Access Dave
I found that via the class I was looking at and reading the class methods when we were looking at the rectangle offsets. I read it as it would recalc the rectangles of the toolbar and plant it, clearly I was incorrect as my result are as you mentioned...not working. I will look at the code samples you linked to. Thank you, Chris