Click here to Skip to main content
15,867,906 members
Articles / Desktop Programming / MFC
Article

How to verify the bar state info

Rate me:
Please Sign up or sign in to vote.
4.97/5 (16 votes)
20 Jan 2000 123.1K   38   14
Verify the bar state info in the application profile before calling LoadBarState()

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


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralTo avoid warning 4311 Pin
pnugoodman20-Nov-06 19:56
pnugoodman20-Nov-06 19:56 
GeneralFantastic Pin
-Dy28-Nov-02 5:18
-Dy28-Nov-02 5:18 
QuestionHow to save position of 2 dockable toolbars? Pin
melwyn12-Feb-02 23:07
melwyn12-Feb-02 23:07 
Hi,
My application has 2 dockable toolbars. How do i save and retrieve their positions?
SaveBarState() and LoadBarState() work fine if the application has only 1 dockable toolbar.
Thanks.
AnswerRe: How to save position of 2 dockable toolbars? Pin
melwyn13-Feb-02 18:47
melwyn13-Feb-02 18:47 
GeneralRe: How to save position of 2 dockable toolbars? Pin
Jim Crafton1-Apr-02 5:58
Jim Crafton1-Apr-02 5:58 
GeneralRe: How to save position of 2 dockable toolbars? Pin
Jim Crafton1-Apr-02 6:31
Jim Crafton1-Apr-02 6:31 
GeneralRe: How to save position of 2 dockable toolbars? Pin
andrewtruckle20-Apr-06 21:20
andrewtruckle20-Apr-06 21:20 
GeneralRe: How to save position of 2 dockable toolbars? Pin
Rick York14-Jul-06 8:57
mveRick York14-Jul-06 8:57 
GeneralLoading and Saving Toolbars Pin
26-Feb-01 11:49
suss26-Feb-01 11:49 
GeneralUndocumented AddControlBar Pin
Martin Richter3-Jul-00 22:49
sussMartin Richter3-Jul-00 22:49 
GeneralCDockstate Pin
Member 620925-Jan-00 0:18
Member 620925-Jan-00 0:18 
GeneralCDockState Pin
Member 620924-Jan-00 0:02
Member 620924-Jan-00 0:02 
GeneralCDockState Pin
Uwe Keim21-Jan-00 1:46
sitebuilderUwe Keim21-Jan-00 1:46 
GeneralCDockState will do it as well Pin
Cristi Posea21-Jan-00 2:16
Cristi Posea21-Jan-00 2:16 

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

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