placing a plugin under the File Menu

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 31/07/2012 at 09:10, xxxxxxxx wrote:

Thanks for filling in the missing parts Yannick.
But I keep getting tripped up when trying to make the jump from:

  
if(dc && dc->GetString(MENURESOURCE_SUBTITLE)=="IDS_EDITOR_FILE")

To your code.
I never got the actual container for the File menu in my example. I only got as far as testing for it's name in the M_EDITOR list. And that's tripping me up.

Once I get the actual container for the IDS_EDITOR_FILE. I think I can put it all together.

-ScottA

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 31/07/2012 at 11:43, xxxxxxxx wrote:

Originally posted by xxxxxxxx

Thanks for filling in the missing parts Yannick.
But I keep getting tripped up when trying to make the jump from:

 
if(dc && dc->GetString(MENURESOURCE_SUBTITLE)=="IDS_EDITOR_FILE")

To your code.
I never got the actual container for the File menu in my example. I only got as far as testing for it's name in the M_EDITOR list. And that's tripping me up.

Once I get the actual container for the IDS_EDITOR_FILE. I think I can put it all together.

In your code dc is actually the menu container.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 31/07/2012 at 12:32, xxxxxxxx wrote:

Doh!
Got it figured out now... I hope.😂

Here's what my complete EnhanceMainMenu function looks like:

void EnhanceMainMenu(void)  
{  
  // do this only if necessary - otherwise the user will end up with dozens of menus!  
  
  BaseContainer *bc = GetMenuResource(String("M_EDITOR"));  //Gets the items under the M_EDITOR section  
  if (!bc) return;  
  
  LONG id;  
  GeData *last = NULL, *dat;  
  BrowseContainer browse(bc);                              //A built in function for iterating containers(Can't edit containers with it)  
  while (browse.GetNext(&id,&dat))                         //The browse function puts what it finds in the "dat" variable  
  {  
  if(id==MENURESOURCE_SUBMENU)                             //Gets the submenu items of M_EDITOR  
   {  
     BaseContainer *dc = dat->GetContainer();              //Gets the container that's inside of the dat variable  
  
     LONG sep = 0;  
   
     BrowseContainer browseFileMenu(dc);  
     while (browseFileMenu.GetNext(&id,&dat))  
     {  
       if(id==MENURESOURCE_SEPERATOR)  
       {  
          sep++;                                                            // Count number of seperators to insert our items after  
          if (sep==4)  
          {  
            GeData item;  
  
            item.SetString(String("PLUGIN_CMD_1000472"));                   // Set data with ActiveObject command plugin ID string  
            GeData *last = dc->InsDataAfter(MENURESOURCE_COMMAND,item,dat); // Add ActiveObject command to menu  
  
            item.SetLong(TRUE);                                             // Set data to TRUE to enable separator  
            dc->InsDataAfter(MENURESOURCE_SEPERATOR,item,last);             // Add separator item  
            break;  
          }  
       }  
     }        
   }  
  }     
}

Thanks for the help Yannick.
Does this give you what you need James?

-ScottA

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 01/08/2012 at 15:23, xxxxxxxx wrote:

Guys,
Thank you so much for all that you've done.  Unfortunately, I am on a freelance gig until tomorrow so I won't be able to completely apply this to my code until then.  I will update then when I put your code into mine.

You guys are an awesome help and a great resource.  Thank you!

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 01/08/2012 at 17:38, xxxxxxxx wrote:

For the sake of completeness.
Here's also an example of how to add your own custom menu to C4D.

//This code creates a new menu at the top of the C4D UI interface when C4D starts up  
//This method is found in the main.cpp file  
//NOTE: you also need to uncomment EnhanceMainMenu(); found in the Bool PluginMessage(LONG id, void *data) method's switch statement  
  
void EnhanceMainMenu(void)   
{  
  // do this only if necessary - otherwise the user will end up with dozens of menus!  
  
  BaseContainer *bc = GetMenuResource(String("M_EDITOR"));    //Gets the items under the M_EDITOR section  
  //BaseContainer *bc = GetMenuResource(String("M_CONSOLE")); //Gets the items under the M_CONSOLE section if desired  
  if (!bc) return;  
  
  GeData *last = SearchPluginMenuResource();                 //The last menu item in the plugins menu  
                                                             //This will be used later to tell the new menu where to be inserted, relative to the last plugins menu item  
  
  BaseContainer tempbc;                                      //Create an empty container to temporarily create and hold a new menu before transfering it to the container "bc"  
  tempbc.InsData(MENURESOURCE_SUBTITLE,String("MyMenu"));    //Adds a new M_EDITOR->sub menu item to the container using a string value  
  bc->InsDataAfter(MENURESOURCE_STRING,tempbc,last);         //Adds the menu item in the sc container to the original M_EDITOR conatiner(Adds a new menu)  
                                                             //The new menu is added after the last plugins menu item (to the right of the plugins menu)      
  UpdateMenus();                                             //Updates the menu changes  
  
  LONG id;  
  GeData *dat;  
  BrowseContainer browse(bc);                              //A built in function for iterating containers(Can't edit containers with it)   
  while (browse.GetNext(&id,&dat))                         //The browse function puts what it finds in the "dat" variable  
  {    
     BaseContainer *dc = dat->GetContainer();              //Gets the container that's inside of the dat variable  
     String names = dc->GetString(MENURESOURCE_SUBTITLE);  //Gets the names of all of the menus listed under the M_EDITOR parent menu  
     //GePrint(names);  
     if(names == "MyMenu")  
     {   
       GeData item;  
       item.SetString(String("PLUGIN_CMD_1000001"));                   //Adds our plugin into the item variable using our plugin's ID# string value  
       GeData *last = dc->InsDataAfter(MENURESOURCE_COMMAND,item,dat); //Adds the plugin to the C4D menu bar...Next to the plugins menu  
       dc->InsDataAfter(MENURESOURCE_SEPERATOR,item,last);             //Adds a separator to the menu after our new plugin entry  
       break;                                                          //No Need to loop anymore ...So break out of the loop  
     }  
  }  
  
}

-ScottA

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 02/08/2012 at 01:03, xxxxxxxx wrote:

Also, here's the complete code for the EnhanceMainMenu() version adding items in the File menu (based on Scott's code, I posted part of the code above) :

void EnhanceMainMenu(void)
{
    BaseContainer *bc = GetMenuResource(String("M_EDITOR"));
    if (!bc) return;
  
    LONG id;
    GeData *fileMenu = NULL, *dat;
    BrowseContainer browse(bc);
    while (browse.GetNext(&id,&dat))
    {
        if(id==MENURESOURCE_SUBMENU) // Filter submenus
        {
            BaseContainer *dc = dat->GetContainer();
            String subtitle = dc->GetString(MENURESOURCE_SUBTITLE);
            if(dc && dc->GetString(MENURESOURCE_SUBTITLE)=="IDS_EDITOR_FILE") // Search for File submenu
            {
                fileMenu = dat;
                break;
            }
        }
    }
  
    if (!fileMenu) return;
  
    LONG sep = 0;
  
    bc = fileMenu->GetContainer();
    BrowseContainer browseFileMenu(bc);
    while (browseFileMenu.GetNext(&id,&dat))
    {
        if(id==MENURESOURCE_SEPERATOR)
        {
            sep++; // Count number of seperator to insert our items after
            if (sep==4)
            {
                GeData item;
                
                item.SetString(String("PLUGIN_CMD_1000472")); // Set data with ActiveObject command plugin ID string
                GeData *last = bc->InsDataAfter(MENURESOURCE_COMMAND,item,dat); // Add ActiveObject command to menu
  
                item.SetLong(TRUE); // Set data to TRUE to enable separator
                bc->InsDataAfter(MENURESOURCE_SEPERATOR,item,last); // Add separator item
  
                break;
            }
        }
    }
}

The function adds "C++ SDK - Active Object Dialog" command and a separator to the File menu.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 07/08/2012 at 09:41, xxxxxxxx wrote:

Ok guys, I apologize for the lateness of this reply.  I had some freelance gigs that just finished up so I have roughly a couple of days to get back to this plugin dev before I go back to another gig!

A C4D professional's work is never done 🙂

I just wanted to thank everyone for these posts!  I got it working perfectly.

I did however have to go to the SDK examples and pull out the portion of the code for the function PluginMessage.  I've attached that code below for completeness of this thread (hopefully this one will get indexed correctly for future devs)

THANKS AGAIN EVERYONE!

Bool PluginMessage(LONG id, void *data) {
  switch (id)
  {
      case C4DPL_BUILDMENU:
          //react to this message to dynamically enhance the menu
          EnhanceMainMenu();
          break;
  }
 
  return FALSE;
  }

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 08/11/2012 at 14:38, xxxxxxxx wrote:

Hi, I'm late to the party, but I was experimenting around with this and I had a couple questions.   I found the resource files with the names of the different menus, so I can put the entries in different ones.  I was wondering if there's a way to put a new entry is  this menu, in the bottom right, I think it's the context menu?  And if there's a way to put an entry in it, is there a way to know what property you had selected when the plugin is opened?

Thanks,
Dan

Also,  is it better to post in old threads that are about a topic or start a new one?

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 08/11/2012 at 21:10, xxxxxxxx wrote:

Originally posted by xxxxxxxx

Hi, I'm late to the party, but I was experimenting around with this and I had a couple questions.   I found the resource files with the names of the different menus, so I can put the entries in different ones.  I was wondering if there's a way to put a new entry is  this menu, in the bottom right, I think it's the context menu?  And if there's a way to put an entry in it, is there a way to know what property you had selected when the plugin is opened?

Thanks,
Dan

Also,  is it better to post in old threads that are about a topic or start a new one?

This is really a different question so it should be a new thread (context menus are not related to the main menus).

No.  You can modify the right-mouse-button context menus only when creating your own plugin that displays in the Attributes Manager (Object, Tag, Tool, Material, etc.) or in the TreeView or GeUserArea of a GeDialog of the plugin.  In the former case, you can only define actions on existing menu options (such as Edit Entry)

You can't modify the r-m-b context menu of existing features of Cinema 4D, especially the Editor View context menu (unfortunately).

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 12/11/2012 at 16:08, xxxxxxxx wrote:

Thanks Robert, I didn't realize that the main menus and context menu's were different, although it makes sense now.

Dan