Click here to Skip to main content
Click here to Skip to main content

How to verify the bar state info

, 20 Jan 2000
Rate this:
Please Sign up or sign in to vote.
Verify the bar state info in the application profile before calling LoadBarState()
<!-- Article Starts -->

The Problem

If you use CFrameWnd's LoadBarState()/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:

  1. Open the registry, and delete the whole key storing your app's profile.
  2. Or, open your favorite text editor, and remove the profile section from the .ini file.
  3. 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.

The Solution

  1. Create a new member function in CMainFrame, like this:

        BOOL VerifyBarState(LPCTSTR lpszProfileName);
    
  2. Add the function body to mainfrm.cpp:

    BOOL CMainFrame::VerifyBarState(LPCTSTR lpszProfileName)
    {
        CDockState state;
        state.LoadState(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)
            {
                // dockbar
                for (int j = 0; j < nDockedCount; j++)
                {
                    UINT nID = (UINT) pInfo->m_arrBarID[j];
                    if (nID == 0) continue; // row separator
                    if (nID > 0xFFFF)
                        nID &= 0xFFFF; // placeholder - get the ID
                    if (GetControlBar(nID) == NULL)
                        return FALSE;
                }
            }
            
            if (!pInfo->m_bFloating) // floating dockbars can be created later
                if (GetControlBar(pInfo->m_nBarID) == NULL)
                    return FALSE; // invalid bar ID
        }
    
        return TRUE;
    }
    
  3. Finally, change the LoadBarState() call in this way:

        if (VerifyBarState(_T("MyApp")))
            LoadBarState(_T("MyApp"));
    

    Optionally, you can add an else branch, in which you clean up or remove the profile settings.

Have fun!

See also www.datamekanix.com for more control bars tips&tricks.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Cristi Posea

United States United States
No Biography provided

Comments and Discussions

 
GeneralUndocumented AddControlBar PinsussMartin Richter3-Jul-00 23:49 
GeneralCDockstate PinsussDerek Graham25-Jan-00 1:18 
GeneralCDockState PinsussDerek Graham24-Jan-00 1:02 
GeneralCDockState PinsussUwe Keim21-Jan-00 2:46 
I'm using the CDockState class from MFC to load my settings.
 
Wouldn't it be even more cooler to derive a class and extend the CDockState::LoadState() member function to call your function before actually loading?
GeneralCDockState will do it as well PinsussCristi Posea21-Jan-00 3:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141223.1 | Last Updated 21 Jan 2000
Article Copyright 2000 by Cristi Posea
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid