Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Dynamic context menus....

Dynamic context menus....

Scheduled Pinned Locked Moved C / C++ / MFC
debugginghelpquestionannouncementlearning
4 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    RedZenBird
    wrote on last edited by
    #1

    This one is just kicking me hard......Maybe someone can help......I'm trying to get completely dynamic context menus to work.....What's strange is these approaches work in debug mode, but never work in release mode....The way it fails in release mode is that the menu is not displayed, and the result is always zero. What gives? The following snippettes work in debug mode, but NOT in release mode: // snip #1 CMenu oMenu; ASSERT( oMenu.CreatePopupMenu() ); // i have a collection of menu command items that I add to the // dynamic menu here // CONTEXT_COMMANDS_ITER oMenuCommandsIter; for ( oMenuCommandsIter = poCommands->begin(); oMenuCommandsIter != poCommands->end(); oMenuCommandsIter++ ) { oMenu.AppendMenu( MF_STRING, (*oMenuCommandsIter).first, (*oMenuCommandsIter).second.c_str() ); } ClientToScreen( &oPoint ); DWORD dwResult; dwResult = oMenu.TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, oPoint.x, oPoint.y, this ); // end snip #1 // snip #2 CMenu oMenu; CMenu oPopup; ASSERT( oMenu.CreateMenu() ); ASSERT( oPopup.CreatePopupMenu() ); oMenu.AppendMenu( MF_STRING, 0, "Ignored" ); oMenu.AppendMenu( MF_POPUP, (UINT)oPopup.m_hMenu, "Ignored" ); // i have a collection of menu command items that I add to the // dynamic menu here // CONTEXT_COMMANDS_ITER oMenuCommandsIter; for ( oMenuCommandsIter = poCommands->begin(); oMenuCommandsIter != poCommands->end(); oMenuCommandsIter++ ) { oPopup.AppendMenu( MF_STRING, (*oMenuCommandsIter).first, (*oMenuCommandsIter).second.c_str() ); } ClientToScreen( &oPoint ); DWORD dwResult; dwResult = oPopup.TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, oPoint.x, oPoint.y, this ); // end snip #2 The following approach works in debug and release mode, but I don't like it because it creates a dependancy on the resource fork. CMenu oMenu; VERIFY( oMenu.LoadMenu( IDR_MENU_HIGHLIGHTS ) ); CMenu* poPopup = oMenu.GetSubMenu( 0 ); ASSERT( poPopup != NULL );

    R M 2 Replies Last reply
    0
    • R RedZenBird

      This one is just kicking me hard......Maybe someone can help......I'm trying to get completely dynamic context menus to work.....What's strange is these approaches work in debug mode, but never work in release mode....The way it fails in release mode is that the menu is not displayed, and the result is always zero. What gives? The following snippettes work in debug mode, but NOT in release mode: // snip #1 CMenu oMenu; ASSERT( oMenu.CreatePopupMenu() ); // i have a collection of menu command items that I add to the // dynamic menu here // CONTEXT_COMMANDS_ITER oMenuCommandsIter; for ( oMenuCommandsIter = poCommands->begin(); oMenuCommandsIter != poCommands->end(); oMenuCommandsIter++ ) { oMenu.AppendMenu( MF_STRING, (*oMenuCommandsIter).first, (*oMenuCommandsIter).second.c_str() ); } ClientToScreen( &oPoint ); DWORD dwResult; dwResult = oMenu.TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, oPoint.x, oPoint.y, this ); // end snip #1 // snip #2 CMenu oMenu; CMenu oPopup; ASSERT( oMenu.CreateMenu() ); ASSERT( oPopup.CreatePopupMenu() ); oMenu.AppendMenu( MF_STRING, 0, "Ignored" ); oMenu.AppendMenu( MF_POPUP, (UINT)oPopup.m_hMenu, "Ignored" ); // i have a collection of menu command items that I add to the // dynamic menu here // CONTEXT_COMMANDS_ITER oMenuCommandsIter; for ( oMenuCommandsIter = poCommands->begin(); oMenuCommandsIter != poCommands->end(); oMenuCommandsIter++ ) { oPopup.AppendMenu( MF_STRING, (*oMenuCommandsIter).first, (*oMenuCommandsIter).second.c_str() ); } ClientToScreen( &oPoint ); DWORD dwResult; dwResult = oPopup.TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, oPoint.x, oPoint.y, this ); // end snip #2 The following approach works in debug and release mode, but I don't like it because it creates a dependancy on the resource fork. CMenu oMenu; VERIFY( oMenu.LoadMenu( IDR_MENU_HIGHLIGHTS ) ); CMenu* poPopup = oMenu.GetSubMenu( 0 ); ASSERT( poPopup != NULL );

      R Offline
      R Offline
      RedZenBird
      wrote on last edited by
      #2

      Just in case anyone is at all curious...here is the fix. The trouble seems to be that even though a popup menu is created, it must be stored in a containing menu object, and then refetched from that container.....very wierd..... // first create the popup menu // CMenu oPopup; VERIFY( oPopup.CreatePopupMenu() ); // now add all the commands to it from the command/prompt list //

      CONTEXT_COMMANDS_ITER oMenuCommandsIter;
      for ( oMenuCommandsIter = poCommands->begin();
      oMenuCommandsIter != poCommands->end();
      oMenuCommandsIter++ )
      {
      oPopup.AppendMenu( MF_STRING,
      (*oMenuCommandsIter).first,
      (*oMenuCommandsIter).second.c_str() );
      }

      // create the container menu and insert the popup into it // // see: MSDN: Q75254 // PRB: TrackPopupMenu() on LoadMenuIndirect() Menu Causes UAE // CMenu oMenu; VERIFY( oMenu.CreateMenu() ); oMenu.InsertMenu( 0, MF_POPUP, (UINT)oPopup.m_hMenu, "Ignored" ); // now have to pull the popup menu back out of the containing menu // I know its strange, but this is how it works...... // CMenu* poPopup = oMenu.GetSubMenu( 0 ); ASSERT( poPopup != NULL ); ClientToScreen( &oPoint );

      DWORD dwResult = poPopup->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON |
      TPM_NONOTIFY | TPM_RETURNCMD,
      oPoint.x,
      oPoint.y,
      this );

      ASSERT( oMenu.DestroyMenu() ); ASSERT( oPopup.DestroyMenu() ); Just trying to keep the forces of entropy at bay

      1 Reply Last reply
      0
      • R RedZenBird

        This one is just kicking me hard......Maybe someone can help......I'm trying to get completely dynamic context menus to work.....What's strange is these approaches work in debug mode, but never work in release mode....The way it fails in release mode is that the menu is not displayed, and the result is always zero. What gives? The following snippettes work in debug mode, but NOT in release mode: // snip #1 CMenu oMenu; ASSERT( oMenu.CreatePopupMenu() ); // i have a collection of menu command items that I add to the // dynamic menu here // CONTEXT_COMMANDS_ITER oMenuCommandsIter; for ( oMenuCommandsIter = poCommands->begin(); oMenuCommandsIter != poCommands->end(); oMenuCommandsIter++ ) { oMenu.AppendMenu( MF_STRING, (*oMenuCommandsIter).first, (*oMenuCommandsIter).second.c_str() ); } ClientToScreen( &oPoint ); DWORD dwResult; dwResult = oMenu.TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, oPoint.x, oPoint.y, this ); // end snip #1 // snip #2 CMenu oMenu; CMenu oPopup; ASSERT( oMenu.CreateMenu() ); ASSERT( oPopup.CreatePopupMenu() ); oMenu.AppendMenu( MF_STRING, 0, "Ignored" ); oMenu.AppendMenu( MF_POPUP, (UINT)oPopup.m_hMenu, "Ignored" ); // i have a collection of menu command items that I add to the // dynamic menu here // CONTEXT_COMMANDS_ITER oMenuCommandsIter; for ( oMenuCommandsIter = poCommands->begin(); oMenuCommandsIter != poCommands->end(); oMenuCommandsIter++ ) { oPopup.AppendMenu( MF_STRING, (*oMenuCommandsIter).first, (*oMenuCommandsIter).second.c_str() ); } ClientToScreen( &oPoint ); DWORD dwResult; dwResult = oPopup.TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, oPoint.x, oPoint.y, this ); // end snip #2 The following approach works in debug and release mode, but I don't like it because it creates a dependancy on the resource fork. CMenu oMenu; VERIFY( oMenu.LoadMenu( IDR_MENU_HIGHLIGHTS ) ); CMenu* poPopup = oMenu.GetSubMenu( 0 ); ASSERT( poPopup != NULL );

        M Offline
        M Offline
        Member 96
        wrote on last edited by
        #3

        Hello, didn't read it too closely, but I think your looking at the wrong area for the problem completely: In snip 1 there is a problem with your ASSERT statement. In a release build the ASSERT statement is going to translate to nothing so CreatePopupMenu will never get called. ASSERTs are only compiled into the executable in a debug build. VERIFY on the other hand which you used in the final example *is* compiled into the release code and will do the check but if it's a release version it will never report an error as it only reports an error in debug builds. This means that any code inside an ASSERT is basically gone when you do a release build, any code inside a VERIFY is still there and will execute but will not report an error no matter what the result of the check. What you should do instead of this: RedZenBird wrote: CMenu oMenu; ASSERT( oMenu.CreatePopupMenu() ); Is something like this: CMenu oMenu; BOOL BResult=FALSE; BResult=oMenu.CreatePopupMenu(); ASSERT(BResult);//For debug builds only That way your function executes debug or release. If it was release code and you thought there was any chance of that function failing you would want to add some form of error handling based on the BResult status after calling CreatePopupMenu().

        R 1 Reply Last reply
        0
        • M Member 96

          Hello, didn't read it too closely, but I think your looking at the wrong area for the problem completely: In snip 1 there is a problem with your ASSERT statement. In a release build the ASSERT statement is going to translate to nothing so CreatePopupMenu will never get called. ASSERTs are only compiled into the executable in a debug build. VERIFY on the other hand which you used in the final example *is* compiled into the release code and will do the check but if it's a release version it will never report an error as it only reports an error in debug builds. This means that any code inside an ASSERT is basically gone when you do a release build, any code inside a VERIFY is still there and will execute but will not report an error no matter what the result of the check. What you should do instead of this: RedZenBird wrote: CMenu oMenu; ASSERT( oMenu.CreatePopupMenu() ); Is something like this: CMenu oMenu; BOOL BResult=FALSE; BResult=oMenu.CreatePopupMenu(); ASSERT(BResult);//For debug builds only That way your function executes debug or release. If it was release code and you thought there was any chance of that function failing you would want to add some form of error handling based on the BResult status after calling CreatePopupMenu().

          R Offline
          R Offline
          RedZenBird
          wrote on last edited by
          #4

          You are right...So, I was driving the train all around the mountain and not even seeing the track in front of me.....gads!!!! Once again proving: "Preoccupation clouds the mind" ..... Thank you for the feedback nonetheless Just trying to keep the forces of entropy at bay

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups