Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision Both sides next revision
developer:sdksamples:insertpluginmenu [2015/09/14]
developer:sdksamples:insertpluginmenu [2020/08/14]
127.0.0.1 external edit
Line 1: Line 1:
 +====== Add a Custom Menu to Rhino's Menu ======
 +====== C++ ======
 +> **Summary:** //Demonstrates how to add a custom menu to Rhino's menu using the Rhino SDK//
 +
 +=====Question=====
 +I am trying to add a submenu to Rhino's **File** menu. I have been fiddling around with the Insert­Plug­In­Menu­To­Rhino­Menu() and ­Insert­Plug­In­Item­To­Rhino­Menu() functions but I do not seem to be getting anywhere. Insert­Plug­In­Menu­To­Rhino­Menu() adds a menu into the Rhino's main menu bar. Insert­Plug­In­Item­To­RhinoMenu() adds a menu item anywhere in the Rhino menu. I believe I want a little of both.
 +
 +=====Answer=====
 +To insert a menu item, or a submenu, into Rhino's menu, do the following:
 +
 +  - Use CRhinoApp::FindMenuItem to search through Rhino's menu structure for an existing menu item that's where you want to insert your menu item.
 +  - Use CRhinoPlugIn::InsertPlugInItemToRhinoMenu to insert your menu into Rhino's menu.
 +
 +=====Example=====
 +The following example command demonstrates how to add and remove a custom menu from Rhino's menu.
 +
 +
 +<code c++>
 +////////////////////////////////////////////////////////////////
 +// cmdMyMenu.cpp
 +
 +#include "StdAfx.h"
 +#include "MyTestPlugIn.h"
 +#include "Resource.h"
 +
 +////////////////////////////////////////////////////////////////
 +////////////////////////////////////////////////////////////////
 +//
 +// BEGIN MyMenu command
 +//
 +
 +class CCommandMyMenu : public CRhinoCommand
 +{
 +public:
 +  CCommandMyMenu() {}
 +  ~CCommandMyMenu() {}
 +  UUID CommandUUID()
 +  {
 +    static const GUID MyMenuCommand_UUID =
 +    { <TODO: add your command uuid here> };
 +    return MyMenuCommand_UUID;
 +  }
 +  const wchar_t* EnglishCommandName() { return L"MyMenu"; }
 +  const wchar_t* LocalCommandName() { return L"MyMenu"; }
 +  CRhinoCommand::result RunCommand( const CRhinoCommandContext& );
 +
 +  BOOL LoadMyMenu();
 +  BOOL UnloadMyMenu();
 +
 +private:
 +  CMenu m_menu;
 +};
 +
 +// The one and only CCommandMyMenu object
 +static class CCommandMyMenu theMyMenuCommand;
 +
 +CRhinoCommand::result CCommandMyMenu::RunCommand( const CRhinoCommandContext& context )
 +{
 +  bool bVisible = ( m_menu.GetSafeHmenu() ) ? true : false;
 +
 +  ON_wString prompt;
 +  prompt.Format( L"%s is %s. New value", 
 +    EnglishCommandName(), 
 +    bVisible ? L"visible" : L"hidden" 
 +    );
 +
 +  CRhinoGetOption go;
 +  go.SetCommandPrompt( prompt );
 +  int s_opt = go.AddCommandOption( RHCMDOPTNAME(L"Show") );
 +  int h_opt = go.AddCommandOption( RHCMDOPTNAME(L"Hide") );
 +  int t_opt = go.AddCommandOption( RHCMDOPTNAME(L"Toggle") );
 +  go.GetOption();
 +  if( go.CommandResult() != success )
 +    return go.CommandResult();
 +
 +  const CRhinoCommandOption* opt = go.Option();
 +  if( 0 == opt )
 +    return failure;
 +
 +  if( opt->m_option_index == s_opt )
 +  {
 +    if( false == bVisible )
 +      LoadMyMenu();
 +  }
 +  else if( opt->m_option_index == h_opt )
 +  {
 +    if( true == bVisible )
 +      UnloadMyMenu();
 +  }
 +  else
 +  {
 +    if( true == bVisible )
 +      UnloadMyMenu();
 +    else
 +      LoadMyMenu();
 +  }
 +
 +  return success;
 +}
 +
 +BOOL CCommandMyMenu::LoadMyMenu()
 +{
 +  // Switch the module state so resources are read 
 +  // from our plug-in (DLL), not Rhino.
 +  AFX_MANAGE_STATE( AfxGetStaticModuleState() );
 +
 +  // Try to load our menu resource from our plug-in.
 +  // Note, m_my_menu is a CMenu member variable.
 +  if( 0 == m_menu.GetSafeHmenu() )
 +  {
 +    if( !m_menu.LoadMenu(IDR_MY_MENU) )
 +      return FALSE;
 +  }
 +
 +  // Find a location in Rhino's menu to insert our
 +  // menu item. For this example, we will insert our
 +  // menu on the "Tools" menu just below the "Commands"
 +  // item.
 +  HMENU hParent = 0;
 +  int index = 0;
 +  //if( !RhinoApp().FindRhinoMenuItem(L"&File::&Print...Ctrl+P", hParent, index) )
 +  if( !RhinoApp().FindRhinoMenuItem(L"Too&ls::&Commands", hParent, index) )
 +  {
 +    m_menu.DestroyMenu();
 +    return FALSE;
 +  }
 +
 +  // Create and initialize a MENUITEMINFO struct.
 +  MENUITEMINFO mi;
 +  memset( &mi, 0, sizeof(mi) );
 +  mi.cbSize = sizeof(mi);
 +
 +  // Fill in our menu info
 +  mi.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU;
 +  mi.wID = MF_POPUP;
 +  mi.fType = MFT_STRING;
 +
 +  ON_wString wstr = L"MyMenu";
 +  mi.dwTypeData = wstr.Array();
 +
 +  mi.fState = MFS_ENABLED;
 +  mi.hSubMenu = m_menu.GetSafeHmenu();
 +  mi.hSubMenu = ::GetSubMenu( mi.hSubMenu, 0 );
 +  mi.wID = IDR_MY_MENU;
 +
 +  // Add our menu to Rhino's menu
 +  BOOL rc = MyTestPlugIn().InsertPlugInItemToRhinoMenu( hParent, index + 1, &mi );
 +  if( !rc )
 +    m_menu.DestroyMenu();
 +
 +  return rc;
 +}
 +
 +BOOL CCommandMyMenu::UnloadMyMenu()
 +{
 +  BOOL rc = FALSE;
 +
 +  // Find our menu item in Rhino's menu.
 +  HMENU hParent = 0;
 +  int index = 0;
 +  if( RhinoApp().FindRhinoMenuItem(L"Too&ls::MyMenu", hParent, index) )
 +  {
 +    // Remove our menu item.
 +    if( ::RemoveMenu(hParent, index, MF_BYPOSITION) )
 +    {
 +      // Redraw Rhino's menu bar.
 +      DrawMenuBar( RhinoApp().MainWnd() );
 +      m_menu.DestroyMenu();
 +      rc = TRUE;
 +    }
 +  }
 +
 +  return rc;
 +}
 +
 +//
 +// END MyMenu command
 +//
 +////////////////////////////////////////////////////////////////
 +////////////////////////////////////////////////////////////////
 +
 +</code>
 +
 +
 +{{tag>Developer cplusplus}}