# Defining New Plugin Commands

This guide discusses Rhino commands and how define new commands using C/C++.

## Overview

Rhino plugins can contain any number of commands. Commands are created by deriving a new class from CRhinoCommand. See rhinoSdkCommand.h for details on the CRhinoCommand class.

Command classes must return a unique UUID. If you try to use a UUID that is already in use, then your command will not work. Use the GUIDGEN.EXE that comes with Visual Studio to create unique UUIDs.

Command classes must return a unique command name. If you try to use a command name that is already in use, then your command will not work.

Only ONE instance of a command class can be created. This is why you should put the definition of your command classes in .cpp files.

## Rhino Command Generator

The Rhino Command Generator wizard is a standalone application that will generate new skeleton CRhinoCommand-derived class. The generated source code is copied to the Windows clipboard so you can easily paste it into your source files.

To use this tool in Visual Studio 2017:

1. Launch Visual Studio 2017.
2. Navigate to Tools > External Tools….
3. Use the Add button to add the RhinoCommandGenerator.exe file to the list. The file can be found in the following location: C:\Program Files\Rhino 6.0 SDK\Wizards\Command

Once the tool is installed, you can create a new command by selecting Tools > Rhino Command. If you add the command declaration to a new .cpp file, be sure to #include "stdafx.h" at the top.

## Sample

The following sample code demonstrates a simple command class that essentially does nothing:

// Do NOT put the definition of class CCommandTest in a header
// file. There is only ONE instance of a CCommandTest class
// and that instance is the static theTestCommand that appears
// immediately below the class definition.

class CCommandTest : public CRhinoCommand
{
public:
// The one and only instance of CCommandTest is created below.
// No copy constructor or operator= is required.
// Values of member variables persist for the duration of the application.

// CCommandTest::CCommandTest()
// is called exactly once when static theTestCommand is created.
CCommandTest() = default;

// CCommandTest::~CCommandTest()
// is called exactly once when static theTestCommand is destroyed.
// The destructor should not make any calls to the Rhino SDK.
// If your command has persistent settings, then override
~CCommandTest() = default;

// Returns a unique UUID for this command.
// If you try to use an id that is already being used, then
// your command will not work. Use GUIDGEN.EXE to make unique UUID.
UUID CommandUUID() override
{
// {F502C783-C0CE-4118-8869-EFB0CB34CCCB}
static const GUID TestCommand_UUID =
{ 0xF502C783, 0xC0CE, 0x4118, { 0x88, 0x69, 0xEF, 0xB0, 0xCB, 0x34, 0xCC, 0xCB } };
return TestCommand_UUID;
}

// Returns the English command name.
// If you want to provide a localized command name, then override
// CRhinoCommand::LocalCommandName.
const wchar_t* EnglishCommandName() override { return L"Test"; }

// Rhino calls RunCommand to run the command.
CRhinoCommand::result RunCommand(const CRhinoCommandContext& context) override;
};

// The one and only CCommandTest object
// Do NOT create any other instance of a CCommandTest class.
static class CCommandTest theTestCommand;

CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context)
{
// CCommandTest::RunCommand() is called when the user
// runs the "Test".

// TODO: Add command code here.

// Rhino command that display a dialog box interface should also support
// a command-line, or scriptable interface.

ON_wString str;
str.Format(L"The \"%s\" command is under construction.\n", EnglishCommandName());
if (context.IsInteractive())
RhinoMessageBox(str, TestPlugIn().PlugInName(), MB_OK);
else
RhinoApp().Print(str);

// TODO: Return one of the following values:
//   CRhinoCommand::success:  The command worked.
//   CRhinoCommand::failure:  The command failed because of invalid input, inability
//                            to compute the desired result, or some other reason.
//   CRhinoCommand::cancel:   The user interactively canceled the command
//                            (by pressing ESCAPE, clicking a CANCEL button, etc.)
//                            in a Get operation, dialog, time consuming computation, etc.

return CRhinoCommand::success;
}