<!-- Article Starts -->
If you use
SaveBarState() to remember the positions of the control bars, you may run into this while developing your app - if you change the bar IDs, or simply remove a bar (it is no longer created in
CMainFrame::OnCreate()), your app will crash.
Why? Because in the
LoadBarState() internals, there is a portion of code which retrieves the bar ID, calls
CMainFrame::GetControlBar() and if the pointer returned is NULL (there is no controlbar created with this ID) it will assert. In Release builds, the
ASSERT line is not compiled, so it goes further and tries to update the
m_nMRUWidth member of the bar, causing a protection error. Nasty.
Well, since you are a MFC veteran, you already know how to fix this:
- Open the registry, and delete the whole key storing your app's profile.
- Or, open your favorite text editor, and remove the profile section from the .ini file.
- Or, simpler, comment the
LoadBarState() call in
CMainFrame::OnCreate(), run the app (allowing the
SaveBarState() to update the profile), then uncomment it back.
What about this? - You already shipped to billions of customers the CoolApp 1.0 with 2 toolbars. Now it's time for an upgrade - you will deliver CoolApp 2.0, which has only one big toolbar, or you changed the toolbar IDs. The new version will crash on a billion computers because of old profile settings, and you get a billion calls for tech support. Uh-oh!
But I have this super install package which verifies the existing profile or builds a brand new one, you'll say. Congratulations, and keep up the good work! This article is not for you, but you may read it anyway.
- Create a new member function in
CMainFrame, like this:
BOOL VerifyBarState(LPCTSTR lpszProfileName);
- Add the function body to
BOOL CMainFrame::VerifyBarState(LPCTSTR lpszProfileName)
for (int i = 0; i < state.m_arrBarInfo.GetSize(); i++)
CControlBarInfo* pInfo = (CControlBarInfo*)state.m_arrBarInfo[i];
ASSERT(pInfo != NULL);
int nDockedCount = pInfo->m_arrBarID.GetSize();
if (nDockedCount > 0)
for (int j = 0; j < nDockedCount; j++)
UINT nID = (UINT) pInfo->m_arrBarID[j];
if (nID == 0) continue; if (nID > 0xFFFF)
nID &= 0xFFFF; if (GetControlBar(nID) == NULL)
if (!pInfo->m_bFloating) if (GetControlBar(pInfo->m_nBarID) == NULL)
return FALSE; }
- Finally, change the
LoadBarState() call in this way:
Optionally, you can add an
else branch, in which you clean up or remove the profile settings.
See also www.datamekanix.com for more control bars tips&tricks.