MFC Application don't display toolbar outside Visual Studio - c++

I have a strange Problem with my MFC Application which i create with visual Studio 2015.
If i run the Application inside Visual Studio via Local Windows Debugger everything works as expected.
If i start the generated .exe File outside of Visual Studio the Toolbar and the Statusbar are not displayed in the Mainframe. I couldn't activate them via View Menu. So my application crashs when I use a Menu Point which writes text to the statusbar.
Did someone now whats the Problem??
Perhaps I didn't know which code i should display in the question feel free to ask for specific code sections in the comments. I will edit the question and provide the code.
This is the code in which the Tool- and Statusbar are created.
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
//TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
m_wndToolBar.LoadTCToolBar(16, IDB_TOOLICONS, IDB_TOOLICONS_HOT, IDB_TOOLICONS_DISABLED, RGB(255, 0, 255));
if (!m_wndStatusBar.Create(this))
{
//TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
m_wndStatusBar.SetIndicators(indicators, sizeof(indicators) / sizeof(UINT));
return 0;
}

I have solved the Problem with a simple Code rearranging in the OnCreate Method.
The Method now looks like this:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
//TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
m_wndToolBar.LoadTCToolBar(16, IDB_TOOLICONS, IDB_TOOLICONS_HOT, IDB_TOOLICONS_DISABLED, RGB(255, 0, 255));
if (!m_wndStatusBar.Create(this))
{
//TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
m_wndStatusBar.SetIndicators(indicators, sizeof(indicators) / sizeof(UINT));
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
I had to move the Lines
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
to the end of the Method. After that the Bars are displayed.

Related

How to adjust the size of a CDockablePane?

I am writing a SDI application on Visual Studio 2012. The MFC Wizard generated two CDockablePane-derived objects. The right-side CPropertiesWnd (CDockablePane-derived) object is named m_wndProperties. I embed in m_wndProperties a CPropertySheet object with a CPageNone (CPropertyPage-derived) object captioned "HELP" like this (I use the CPropertySheet class directly). However, the real size of the CPropertySheet object is bigger.
I have tried to adjust the size of the dialog related to the CPageNone object (named m_pageNone) in the Dialog Editor. This has no effect. In the MainFrm.cpp, the only lines relating to m_wndProperties I can find are:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
.....
m_wndProperties.EnableDocking(CBRS_ALIGN_RIGHT);
DockPane(&m_wndProperties);
.....
}
.....
BOOL CMainFrame::CreateDockingWindows()
{
.....
CString strPropertiesWnd;
bNameValid = strPropertiesWnd.LoadString(IDS_PROPERTIES_WND);
ASSERT(bNameValid);
if (!m_wndProperties.Create(strPropertiesWnd, this, CRect(0, 0, 200, 200), TRUE, ID_VIEW_PROPERTIESWND, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_RIGHT | CBRS_FLOAT_MULTI))
{
TRACE0("無法建立 [屬性] 視窗\n");
return FALSE; // 無法建立
}
.....
}
.....
void CMainFrame::SetDockingWindowIcons(BOOL bHiColorIcons)
{
.....
HICON hPropertiesBarIcon = (HICON) ::LoadImage(::AfxGetResourceHandle(), MAKEINTRESOURCE(bHiColorIcons ? IDI_PROPERTIES_WND_HC : IDI_PROPERTIES_WND), IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), 0);
m_wndProperties.SetIcon(hPropertiesBarIcon, FALSE);
}
And here is the AdjustLayout() in my PropertiesWnd.cpp:
void CPropertiesWnd::AdjustLayout()
{
if (GetSafeHwnd () == NULL || (AfxGetMainWnd() != NULL && AfxGetMainWnd()->IsIconic()))
{
return;
}
CRect rectClient;
GetClientRect(rectClient);
m_PropertySheet.SetWindowPos (NULL, rectClient.left, rectClient.top, rectClient.Width (), rectClient.Height (), SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
}
And in my PageNone.cpp, I only have three functions: the default constructor, the default destructor and DoDataExchange.
My question is how can I adjust the size of m_wndProperties or m_pageNone to fit each other? Thank you very much.
I have got this working in a different way (the code is too large to give in this answer, but the main points are:
a) don't do anything in CMainFrame::OnCreate()
b) in CMainFrame::CreateDockingWindows(), after m_wndProperties.Create(), add the following code
m_PropertySheet.Create(...);
CRect rc;
m_PropertySheet.GetRect(&rc);
m_wndProperties.SetMinSize(rc.Width(), rc,Height());
m_wndProperties.EnableDocking(CBRS_ALIGN_RIGHT);
DockPane(&m_wndProperties);
ShowPane(&m_wndProperties, TRUE, FALSE, TRUE);
Your code in AdjustLayout() is plausible right, but I think during startup it will be called too early. Because the default size will be read from CWinAppEx::LoadState(), which always read the previous size from the Registry. It can probably disabled with CWinAppEx::EnableLoadWindowPlacement(FALSE). not tested.
Post a User-Defined Message at the end of InitInstance(). Or just try with a timer in CMainFrame::Create() .. SetTimer(123,2000,NULL);
void CMainFrame::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 123)
{
m_wndProperties.SetWindowPos(this, 0, 0, 400, 200, SWP_NOZORDER | SWP_FRAMECHANGED);
RecalcLayout();
KillTimer(123);
}
CFrameWndEx::OnTimer(nIDEvent);
}

How To Add A Second Toolbar Into Mainframe?

I would like to add a second toolbar in my main frame window to sit under the existing toolbar.
Reading the following tutorials:
http://forums.codeguru.com/showthread.php?495887-Add-a-toolbar-to-an-MFC-application
http://www.codersource.net/2010/01/30/mfc-tutorial-toolbars/
MFC Toolbar on Dialog?
I have come to a similar conclusion to this unanswered thread:
https://stackoverflow.com/questions/35736580/how-to-add-a-second-toolbar-to-an-mfc-application-so-that-the-toolbar-is-added-o
This is my code:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// create a view to occupy the client area of the frame
if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
{
TRACE0("Failed to create view window\n");
return -1;
}
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
m_wndStatusBar.SetPaneInfo(EWF_PANE_INDEX, ID_SEPARATOR, SBPS_NORMAL, EWF_PANE_WIDTH);
for (int i=0;i<5; i++) {
// Change Status Bar style to make it Owner-drawn
m_wndStatusBar.GetStatusBarCtrl().SetText("", i, SBT_OWNERDRAW);
}
CToolBar myToolBar;
if (!myToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!myToolBar.LoadToolBar(IDR_MAINFRAME_B))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
return 0;
}
I have added:
CToolBar myToolBar;
if (!myToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!myToolBar.LoadToolBar(IDR_MAINFRAME_B))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
At the bottom for my second toolbar but it does not appear when the app is opened and it compiles with no errors.
In comparison to the already supplied toolbar which is called from InitInstance() by pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE , NULL, NULL);
If I call this pFrame->LoadFrame with my second toolbar in the next line the app will not load all together.
How do I need to call my second toolbar?
Have I missed something completely?
You need to add CToolBar myToolBar as a member variable of your CMainFrame class, the same way as m_wndToolBar. Otherwise, it gets destroyed if you define it as a local variable after the OnCreate exits.

MFC Project Combination: How to add a SDI application without document class to a MDI application?should I use child window?[MFC]

I'am now working with a MDI MFC app and want to add a console/command-line function to the app. The only function I want to take from QuickWin(see below) is to use its text area and the process function which captures input. If I can add it to a popup dialog or a dock bar, it will be great!
And I got the src-code of a SDI Applization without Document Class like this(link:http://www.codeproject.com/.../QuickWin-...):
My Question is: can I add the app into my MDI app, and how to deal with source or head files like:
MainFrm.cpp/MainFrm.h and class like: CQuickWinApp/CQuickView?(If I can pop up a child window to implement the function, better:))
In QuickWin's mainframe, it has something to do with client area, which is difficule to deal with:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// create splitter without views
m_wndSplitter.CreateStatic(this, 2, 1);
CCreateContext Context;
Context.m_pNewViewClass = RUNTIME_CLASS(CQuickView);
Context.m_pCurrentDoc = NULL;
Context.m_pNewDocTemplate = NULL;
Context.m_pLastView = NULL;
Context.m_pCurrentFrame = this;
// Create the Stdio QuickView
m_pStdioView = (CQuickView*)CreateView(&Context, AFX_IDW_PANE_FIRST);
if (m_pStdioView == NULL)
{
TRACE("Failed to create QuickWin Stdio View\n");
return FALSE; // fail to create
}
// Create the Stderr QuickView
m_pStderrView = (CQuickView*)CreateView(&Context, AFX_IDW_PANE_FIRST);
if (m_pStderrView == NULL)
{
TRACE("Failed to create QuickWin Stderr View\n");
return FALSE; // fail to create
}
m_pStderrView->SetReadOnly(TRUE);
ShowSplitter(theApp.m_bShowSplitter);
return TRUE;
}
in My MDI app:
The MDI app has 3 doctemplates:
//BCGPVisualStudioGUIDemo.cpp
m_pDocTemplateCpp = new CMultiDocTemplate(
IDR_BCGDEVTYPE_CPP,
RUNTIME_CLASS(CBCGPVisualStudioGUIDemoDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CBCGPVisualStudioGUIDemoView));
AddDocTemplate (m_pDocTemplateCpp);
m_pDocTemplateWeb = new CMultiDocTemplate(
IDR_BCGDEVTYPE_WEB,
RUNTIME_CLASS(CBCGPVisualStudioGUIDemoDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CBCGPVisualStudioGUIDemoView));
AddDocTemplate (m_pDocTemplateWeb);
m_pStartDocTemplate = new CMultiDocTemplate(
IDR_BCGDEVTYPE0,
RUNTIME_CLASS(CNetworkMapEditorDemoDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CNetworkMapEditorDemoView));
AddDocTemplate(m_pStartDocTemplate);
The app also has some dock bars:
//MainFrm.cpp
//------------------
// Create config bar:
//------------------
if (!m_wndClassView.Create (_T("config"), this, CRect (0, 0, 200, 200),
TRUE,
ID_VIEW_CLASS,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI))
{
TRACE0("Failed to create Class View bar\n");
return FALSE; // fail to create
}
//------------------
// Create output bar:
//------------------
if (!m_wndOutputView.Create (_T("output"), this, CRect (0, 0, 200, 100),
TRUE,
ID_VIEW_OUTPUT,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_BOTTOM | CBRS_FLOAT_MULTI))
{
TRACE0("Failed to create output bar\n");
return FALSE; // fail to create
}
//------------------
// Create help bar:
//------------------
if (!m_wndDynamicHelpView.Create (_T("help"), this, CRect (0, 0, 200, 200),
TRUE,
ID_VIEW_DYNAMICHELP,
WS_CHILD | WS_VISIBLE | CBRS_RIGHT | CBRS_FLOAT_MULTI))
{
TRACE0("Failed to create Dynamic Help Bar\n");
return FALSE; // fail to create
}
//------------------
// Create watch bar:
//------------------
if (!m_wndWatchBar.Create (_T("watch"), this, CRect (0, 0, 300, 100),
TRUE,
ID_VIEW_WATCH,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_BOTTOM | CBRS_FLOAT_MULTI))
{
TRACE0("Failed to create watch bar\n");
return FALSE; // fail to create
}
//------------------
// Create property bar:
//------------------
if (!m_wndPropertiesBar.Create (_T("property"), this, CRect (0, 0, 300, 200),
TRUE,
ID_VIEW_PROPERTIES,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_RIGHT | CBRS_FLOAT_MULTI))
{
TRACE0("Failed to create Properties Bar\n");
return FALSE; // fail to create
}
Can I add the QuickWin app's text function into my app's dock bar or into a doctemplate or just a popup window?
All you need to integrate the functionality of QuickWin into your application are 3 textboxes (one for stdin, stdout and stderr) and the following classes from the Quickwin project:
CRedirect
CRedir
CParamDlg (only optical fluff, not essential)
The CRedirect-class manages the creation of the new process as well as the redirection of stdin/stdout/stderr (in combination with CRedir).
You have to modify CRedir::OnChildWrite and -Started and -Terminate to fit your needs. These methods actually write the content to the view/textbox/whatever. It is helpful to look at CMainFrame::OnCopyData and CQuickView::Append on how this can be done.

MFC docking windows and where they dock

I have created (generated) a MDI project with tabbed documents with
VS2008 Pro.
Visual Studio generates an application with the File/Class view
window, properties window, output window and the first MDI document/
view.
I want to control the sides on which the windows dock. I thought this
was done in BOOL CMainFrame::CreateDockingWindows() , i changed the
CBRS_TOP to CBRS_BOTTOM and CBRS_RIGHT to CBRS_LEFT , but the windows
still come out the same in the client area. It makes no difference
what is use for a window style attribute of CBRS_xxxx. Where and how
can i control where in the client area these windows dock ?
I changed then in :
BOOL CMainFrame::CreateDockingWindows()
{
BOOL bNameValid;
// Create class view
CString strClassView;
bNameValid = strClassView.LoadString(IDS_CLASS_VIEW);
ASSERT(bNameValid);
if (!m_wndClassView.Create(strClassView, this, CRect(0, 0, 200, 200), TRUE,ID_VIEW_CLASSVIEW, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI))
{
TRACE0("Failed to create Class View window\n");
return FALSE; // failed to create
}
// Create file view
CString strFileView;
bNameValid = strFileView.LoadString(IDS_FILE_VIEW);
ASSERT(bNameValid);
if (!m_wndFileView.Create(strFileView, this, CRect(0, 0, 200, 200),TRUE, ID_VIEW_FILEVIEW, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
WS_CLIPCHILDREN | CBRS_LEFT| CBRS_FLOAT_MULTI))
{
TRACE0("Failed to create File View window\n");
return FALSE; // failed to create
}
// Create output window
CString strOutputWnd;
bNameValid = strOutputWnd.LoadString(IDS_OUTPUT_WND);
ASSERT(bNameValid);
if (!m_wndOutput.Create(strOutputWnd, this, CRect(0, 0, 100, 100),
TRUE, ID_VIEW_OUTPUTWND, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
WS_CLIPCHILDREN | CBRS_BOTTOM | CBRS_FLOAT_MULTI))
{
TRACE0("Failed to create Output window\n");
return FALSE; // failed to create
}
// Create properties window
CString strPropertiesWnd;
bNameValid = strPropertiesWnd.LoadString(IDS_PROPERTIES_WND);
ASSERT(bNameValid);
if (!m_wndProperties.Create(strPropertiesWnd, this, CRect(0, 0, 200, 200), TRUE, ID_VIEW_PROPERTIESWND, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |CBRS_RIGHT | CBRS_FLOAT_MULTI))
{
TRACE0("Failed to create Properties window\n");
return FALSE; // failed to create
}
SetDockingWindowIcons(theApp.m_bHiColorIcons);
return TRUE;
}
Could someone please help explain to me how to control the sides where
these windows dock?
Thanks.
IIRC, CBRS_TOP etc. are for where they can dock, not for where they are docked when you start the application. That is saved in the registry, basically it will show up where it was when the application was shut down the last time.
In the past (this was not with the Feature Pack docking framework) if you wanted to dock on startup to a specific side you had to set the side where you wanted the toolbar to be docked as the only one allowed (e.g. on the right), create the toolbar, dock it (there was a SetDocked() or something like that) and then modify the allowed dock sides to the directions you wanted to allow. I'm not sure if that behavior persists in the current version but I think it does, as that was something build on low level docking toolbar functionality which the feature pack stuff just builds on.
Not a real answer but hopefully it'll set you on your way...

CMFCToolbar layout not restored properly between sessions

I'm having a problem with the CMFCToolbar class where the positions of the toolbars are not being restored properly between sessions.
Here is a screen shot of how the toolbars are arranged before the app is closed:
(source: achavis.net)
Here is a screen shot of how the toolbars are restored when the app is launched again:
(source: achavis.net)
Notice the large gap that appears above the first toolbar and the second toolbar is now to the right of the main toolbar instead of beneath it.
I was having problems with my app, so I generated this test app using the App Wizard, then I added the second toolbar manually.
I would like to know if this is because there is something I am doing wrong, or if it is just due to the buggy nature of the feature pack code.
Here is the code from my CMainFrame class which sets up the toolbars:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWndEx::OnCreate(lpCreateStruct) == -1)
return -1;
BOOL bNameValid;
// set the visual manager used to draw all user interface elements
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007));
// set the visual style to be used the by the visual manager
CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_LunaBlue);
if (!m_wndMenuBar.Create(this))
{
TRACE0("Failed to create menubar\n");
return -1; // fail to create
}
m_wndMenuBar.SetPaneStyle(m_wndMenuBar.GetPaneStyle() | CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS | CBRS_FLYBY);
// prevent the menu bar from taking the focus on activation
CMFCPopupMenu::SetForceMenuFocus(FALSE);
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(theApp.m_bHiColorIcons ? IDR_MAINFRAME_256 : IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
CString strToolBarName;
bNameValid = strToolBarName.LoadString(IDS_TOOLBAR_STANDARD);
ASSERT(bNameValid);
m_wndToolBar.SetWindowText(strToolBarName);
m_wndToolBar.EnableTextLabels();
if (!m_wndToolBar2.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar2.LoadToolBar(IDR_TOOLBAR))
{
TRACE0("Failed to create toolbar2\n");
return -1; // fail to create
}
CString strCustomize("Toolbar2");
m_wndToolBar2.EnableCustomizeButton(TRUE, ID_VIEW_CUSTOMIZE, strCustomize);
// Allow user-defined toolbars operations:
InitUserToolbars(NULL, uiFirstUserToolBarId, uiLastUserToolBarId);
if (!m_wndStatusBar.Create(this))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
// TODO: Delete these five lines if you don't want the toolbar and menubar to be dockable
m_wndMenuBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndToolBar2.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_wndMenuBar);
DockPane(&m_wndToolBar);
DockPane(&m_wndToolBar2);
// enable Visual Studio 2005 style docking window behavior
CDockingManager::SetDockingMode(DT_SMART);
// enable Visual Studio 2005 style docking window auto-hide behavior
EnableAutoHidePanes(CBRS_ALIGN_ANY);
// Load menu item image (not placed on any standard toolbars):
CMFCToolBar::AddToolBarForImageCollection(IDR_MENU_IMAGES, theApp.m_bHiColorIcons ? IDB_MENU_IMAGES_24 : 0);
// create docking windows
if (!CreateDockingWindows())
{
TRACE0("Failed to create docking windows\n");
return -1;
}
m_wndFileView.EnableDocking(CBRS_ALIGN_ANY);
m_wndClassView.EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_wndFileView);
CDockablePane* pTabbedBar = NULL;
m_wndClassView.AttachToTabWnd(&m_wndFileView, DM_SHOW, TRUE, &pTabbedBar);
m_wndOutput.EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_wndOutput);
// Enable toolbar and docking window menu replacement
EnablePaneMenu(TRUE, ID_VIEW_CUSTOMIZE, strCustomize, ID_VIEW_TOOLBAR);
// enable quick (Alt+drag) toolbar customization
CMFCToolBar::EnableQuickCustomization();
if (CMFCToolBar::GetUserImages() == NULL)
{
// load user-defined toolbar images
if (m_UserImages.Load(_T(".\\UserImages.bmp")))
{
m_UserImages.SetImageSize(CSize(16, 16), FALSE);
CMFCToolBar::SetUserImages(&m_UserImages);
}
}
// enable menu personalization (most-recently used commands)
// TODO: define your own basic commands, ensuring that each pulldown menu has at least one basic command.
CList<UINT, UINT> lstBasicCommands;
lstBasicCommands.AddTail(ID_FILE_NEW);
lstBasicCommands.AddTail(ID_FILE_OPEN);
lstBasicCommands.AddTail(ID_FILE_SAVE);
lstBasicCommands.AddTail(ID_FILE_PRINT);
lstBasicCommands.AddTail(ID_APP_EXIT);
lstBasicCommands.AddTail(ID_EDIT_CUT);
lstBasicCommands.AddTail(ID_EDIT_PASTE);
lstBasicCommands.AddTail(ID_EDIT_UNDO);
lstBasicCommands.AddTail(ID_APP_ABOUT);
lstBasicCommands.AddTail(ID_VIEW_STATUS_BAR);
lstBasicCommands.AddTail(ID_VIEW_TOOLBAR);
lstBasicCommands.AddTail(ID_SORTING_SORTALPHABETIC);
lstBasicCommands.AddTail(ID_SORTING_SORTBYTYPE);
lstBasicCommands.AddTail(ID_SORTING_SORTBYACCESS);
lstBasicCommands.AddTail(ID_SORTING_GROUPBYTYPE);
CMFCToolBar::SetBasicCommands(lstBasicCommands);
return 0;
}
This problem was resolved by creating the toolbars with explicit IDs as opposed to relying on the default parameter as in the above code.
Because the registry key that the toolbar's state is saved to is based on the ID, the second toolbar was saving its state on top of the first toolbar.
Here are the code changes that resolved the problem:
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC, CRect(1,1,1,1), IDR_MAINFRAME) ||
!m_wndToolBar.LoadToolBar(theApp.m_bHiColorIcons ? IDR_MAINFRAME_256 : IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
...
if (!m_wndToolBar2.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC, CRect(1,1,1,1), IDR_TOOLBAR) ||
!m_wndToolBar2.LoadToolBar(IDR_TOOLBAR))
{
TRACE0("Failed to create toolbar2\n");
return -1; // fail to create
}