Solved

Menu manipulation causes crashing

Posted on 2002-06-26
14
432 Views
Last Modified: 2012-06-21
I have a menu that needs to change depending on the state of the application.  At startup and at certain triggers thereafter, a function is called that modifies the menu by loading it fresh from the resources then removing items that are inapplicable.

The code is such:

void CMainFrame::changeMenu(MENU_STATE menuState)
{
            HMENU hMenu = ::LoadMenu(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
            myFrame->m_pDoc->setMenuHandle(hMenu);

            CMenu *menu = new CMenu();
            menu->Attach(hMenu);

            CString menuText;

            //loop through the menu, examining the text of each top level menu item.
            for(int i=0; i<menu->GetMenuItemCount(); i++)
            {
      menu->GetMenuString(i, menuText, MF_BYPOSITION);

      if( (menuState == WORKING) || (menuState == OFFSITE) )
     {
              if( (!menuText.Compare("Solo")) ||
                   (!menuText.Compare("Group")) )
             {
           menu->RemoveMenu(i, MF_BYPOSITION);
           i--; // Make sure you don't skip the new item in a deleted index.
             }
      }

      if( (menuState == WORKING_OFFSITE) &&
              (!menuText.Compare("&Site Approved")) )
      {
                        menu->RemoveMenu(i, MF_BYPOSITION);
               i--;
      }
          }

          menu->Detach();
          delete menu;
          OnUpdateFrameMenu(NULL);
          DrawMenuBar();
 }

The document associated with the setMenuHandle() call has GetDefaultMenu() overridden to return the handle pointed to by a member variable, which is set with the setMenuHandle call.

The problem is that it crashes at different points throughout this function, the second time the function is hit each time the application is run.  Actually sometimes it doesn't crash at all, but usually it does and never the first time through.  When it crashes, even though I'm running it in debug it doesn't give me the debug info, but opens a different devstudio instead.

Always a different crash spot, and no obvious junk in any of the variables before a crash.  Seems like a memory management thing to me, what am I doing wrong?
0
Comment
Question by:appleby
  • 6
  • 3
  • 3
  • +1
14 Comments
 
LVL 3

Expert Comment

by:CoolBreeze
ID: 7112770
don't know if this helps

but menu is a pointer, you should use
delete[] menu
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7112861
I don't think you should be loading the menu at all.  It has been loaded already.  Normal usage is GetMenu ( a amenber function of your CMainFrame).  That returns a CMenu* which you can use to modify your menu.

See the example code for CWnd::GetMenu in MSDN.

void CMainFrame::changeMenu(MENU_STATE menuState)
{
     CMenu* pMnu= GetMenu();
     CString sMnuText;

     //loop through the menu, examining the text of each top level menu item.
     for( int i=0; i<pMnu->GetMenuItemCount(); i++ )  {
          pMnu->GetMenuString(i, sMnuText, MF_BYPOSITION);
          if( (menuState == WORKING) || (menuState == OFFSITE) ) {
               if( (sMnuText != "Solo") || (sMnuText != "Group") ) {
                    pMnu->RemoveMenu( i, MF_BYPOSITION );
                    i--; // Make sure you don't skip the new item in a deleted index.
               }
          }
          if( (menuState == WORKING_OFFSITE) && (sMnuText == "&Site Approved") )  {
               pMnu->RemoveMenu( i, MF_BYPOSITION );
               i--;
          }
     }
     OnUpdateFrameMenu(NULL);
     DrawMenuBar();
}

=-=-=-=-=-=-
(I did not test this code)
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7112864
Also, it is more in the spirit of Windows U/I guidelines to disable menu items rather than delete them.  Otherwise the user can get lost "Where is that option!" and keeps looking in all the menus thinking he's just a dolt and forgot.  But a disabled item is a clue that the option exists but is not available.

-- Dan
0
 

Author Comment

by:appleby
ID: 7113596
DanRollins - I had tried just using GetMenu(), but it gives me the menu in its current state, which means it already has some items removed.  I need to have it start fresh with all items again, which is why I am reloading it.  I realize it is not standard to remove items, for the reason you mention.  But for this application it does make sense.

CoolBreeze - thanks for the tip, though it doesn't fix my problem.  :)
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7114837
I can't be sure, but I believe that your techique of reloading is at the root of the problem.

I suggest that you create two complete menus in the resource file... one for each situation.  The MSDN help for CMenu::LoafMenau shows the exact sequence for doing this:

void CMainFrame::OnReplaceMenu()
{
   // Load the new menu.
   m_NewMenu.LoadMenu(IDR_SHORT_MENU);
   ASSERT(m_NewMenu);

   // Remove and destroy the old menu
   SetMenu(NULL);
   ::DestroyMenu(m_hMenuDefault);

   // Add the new menu
   SetMenu(&m_NewMenu);

   // Assign default menu
   m_hMenuDefault = m_NewMenu.GetSafeHmenu();  // or m_NewMenu.m_hMenu;
}

-- Dan
0
 

Author Comment

by:appleby
ID: 7114961
I agree, but have tried several different ways and all result in the same trouble.  Including the example you show above.  (Where did you find this, by the way, it is not in the MSDN help for CMenu::LoadMenu that I have in version 6.0, nor is it in the online MSDN help for CMenu::LoadMenu.)  It is quite close to what I was already doing, but some things in different order, etc.

I am probably going to move in a different direction, whether it be maintaining separate resources or doing manual adds to the menu (right now we are deleting but not adding).  I am going to leave this question open for a while because I'd still like input if anyone has some other ideas as to why this is not working.
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 200 total points
ID: 7115260
If you used that exact technique, then the problem is elsewhere -- it is unrelated to menus or the error is in your function named OnUpdateFrameMenu.

Here's once ref to that:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/_mfc_cmenu.3a3a.loadmenu.asp

-- Dan
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:appleby
ID: 7116284
Ok, that is possible.  There is some other code implemented in this app that modifies the default menu for the document.  I thought I was bypassing that but it looks like it may be still affecting things, or there may be other code I'm unaware of that is making changes.  I'll check it out.  (This is an unbelievably huge bunch of legacy code that I'm trying to make some updates to...it's hard to tell what might be out there that could be affecting things.)
0
 
LVL 8

Expert Comment

by:fl0yd
ID: 7118749
One easy question: Why is this in the c++-programming-topic? I really can't believe you guys. About 80% of all questions in this section are win/mfc-related. If it's that hard for you to tell the difference between a language and an API you may want to stop performing your code-pollution-carreer altogether before doing any more harm. Sorry, but I really wasn't able to call it programming.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7119058
fl0yd,
If you look carefully on the box, the name of the program is "Visual C++" -- I just checked.  The letter C, followed by two addition symbols (++), specify the name of the programming language.

>>About 80% of all questions in this section are win/mfc-related...
That is correct.  Good observation!

Is there any reason to pollute this thread with irrelevancies?  

-- Dan
0
 
LVL 8

Expert Comment

by:fl0yd
ID: 7119334
> Is there any reason to pollute this thread with
> irrelevancies?

Are you really ignorant enough to not see that this is exactly why I was posting this comment? Give me a break, you are a programmer - at least that's what you call yourself - and should be able to use some sort of neurons to comprehend, don't you?

> If you look carefully on the box, the name of the
> program is "Visual C++" -- I just checked

That is if you are a wiener like yourself. If I look at my box it says "Microsoft Developer Studio". And forgive me my enduring ignorance, what the hell does c++ have to do with Microsoft? I don't get it. Before you come up with some obscure answer to this, please, would you kindly explain to me what those "MFC"- and "windows programming"-sections were meant for.
0
 
LVL 3

Expert Comment

by:CoolBreeze
ID: 7119535
can't help but to comment
eighty percent may be win/mfc related, but the problem is a memory leak and that may be related to C++. tell me, is it winapi or the C++ code that is likely to give you the leak?

i say his asking in here is justified. you don't just put some question under the windows programming topic just because your code contains eighty percent windows stuff, it's the question.
0
 
LVL 8

Expert Comment

by:fl0yd
ID: 7119758
Oh crap, sorry, but I didn't find the time to look for a term that might have been less direct. The problem is certainly not a memory leak; at least I have *NEVER* *EVER* come across a memory leak that would cause my application to crash. Be honest, have you CoolBreeze?
Unrelated to the problem itself it *IS* winapi that is a lot more likely to cause a leak. It's as obvious as the fact that every opening bracket needs to be matched by a closing bracket, that every new calls for a matching delete. With win32-coding it isn't quite as obvious. Forgetting a call to CloseHandle(), Release(), DeleteObject() and the like is a very common error. So CoolBreeze, let's assume I made this mistake in an application I was developing with Delphi. Is it c++ or winapi that is likely to give me a leak?
The point being: This problem has nothing to do with an error related to c++. Just ask yourself the following question: If you translated the code into a different programming language would the problem still exist? If you can answer this question with a plain 'yes' then putting it in this section is probably not what you want to do. Your, excuse me, stupid point that it is written in c++ justifies blaming the language clearly shows your lack of insight and experience. I can just hear you in an argument with your boss: "No, I didn't make the mistake. I wrote the app in c++ and thus the problem is within the language. Sorry, you gotta blame Bjarne and the committee". If you were right, then there would be absolutely no need for an MFC-section. Expanding on your rather progressive idea. Why not do away with all of them and put all question in a section named 'machine code'?
I can't even believe I took your comment seriously. You were probably just joking and I didn't get it.

.f *sadly shakes his head in desperation*
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7120530
fl0yd and CoolBreeze,
Let's take this OFF-TOPIC discussion into the Expert Input area where it belongs.  There are plenty of things to discuss, but this is the wrong place to do so.  I have opened a new question here:

         http:Q.20317998.html
-- Dan
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now