KEVOS® Knowledge Library · SolidWorks API Add-in Development
Command Manager, Menus and Toolbars
How an add-in publishes its commands into the SolidWorks interface — callback routing, command groups, item definitions, enable methods and the teardown that keeps the host clean.
- Doc № KL-ENG-COMP-004
- Engineering › Computers
- Part 04 of 10
- 7 min read
- Updated 2026-08-04
01Executive summary
There are two ways to put a command into the SolidWorks interface. The older route creates a menu item, then a toolbar, then a toolbar command, as three separate operations that must be kept consistent by hand. The Command Manager route defines the command once inside a group and then exposes it as a menu item, a toolbar button, or both, by setting two boolean properties.
For anything other than menus assembled dynamically at runtime, the Command Manager is the correct choice. One manager per add-in serves any number of groups, and each group behaves as its own menu and its own toolbar.
02Callback routing comes first
A command is only useful if SolidWorks knows where to send the click. That routing is established once, during connect, and must be in place before any command capable of raising a callback is created.
public bool ConnectToSW(object ThisSW, int Cookie)
{
_sw = (ISldWorks)ThisSW;
_cookie = Cookie;
// 1. Tell SolidWorks which object receives callbacks.
_sw.SetAddinCallbackInfo(0, this, _cookie);
// 2. Acquire the Command Manager for this add-in.
_cmdMgr = _sw.GetCommandManager(_cookie);
// 3. Only now build the commands.
BuildCommands();
return true;
}
The callback is supplied as a string when the command item is created, and resolved against the routing target when the user clicks. A mistyped name therefore compiles cleanly, registers cleanly, and fails only at the moment a user tries to use the feature. Hold callback names in constants and use the same constant in both places.
03Creating a command group
Items live inside groups. Each group presents as one top-level menu and one toolbar, so the number of groups you create is a user-interface decision, not a technical constraint.
CommandGroup CreateCommandGroup(
int UserID,
string Title,
string ToolTip,
string Hint,
int Position
)
- UserID
- An integer unique within your add-in's Command Manager. It is the handle you will pass back to remove the group at disconnect, so keep it as a constant rather than a literal.
- Title
- The text of the top-level menu and the name of the toolbar.
- ToolTip
- The hover text shown beside the pointer.
- Hint
- The longer text shown in the SolidWorks status bar.
- Position
- Zero-based position of the group within the main SolidWorks menu bar.
04Defining command items
int AddCommandItem2(
string Name,
int Position,
string HintString,
string ToolTip,
int ImageListIndex,
string CallbackFunction,
string EnableMethod,
int UserID,
int MenuTBOption
)
- Name
- The label shown on the menu entry and toolbar button.
- Position
- Zero-based position of the item within its group.
- HintString / ToolTip
- Status-bar text and hover text, matching the group's own parameters.
- ImageListIndex
- Zero-based index into the image list supplied for the group. Leave at zero until you introduce icons.
- CallbackFunction
- The name of a public method on the routing target, invoked when the item is clicked.
- EnableMethod
- Optional. The name of a method consulted before the item is displayed, returning a value in the range zero to four that governs whether the item is shown and whether it is enabled.
- UserID
- Unique identifier for the item. May be passed as zero where you do not need to address the item individually.
- MenuTBOption
- A bit mask combining the command item type values, deciding whether the item appears in the menu, on the toolbar, or both.
private const int GroupId = 1;
private const string CbShowPage = "OnShowPage";
private const string EnShowPage = "CanShowPage";
private void BuildCommands()
{
ICommandGroup group = _cmdMgr.CreateCommandGroup(
GroupId,
"KEVOS Tools",
"KEVOS add-in commands",
"Model information and reporting tools",
3);
group.AddCommandItem2(
"Model information",
0,
"Show information about the active model",
"Model information",
0,
CbShowPage,
EnShowPage,
0,
(int)(swCommandItemType_e.swMenuItem |
swCommandItemType_e.swToolbarItem));
group.HasMenu = true;
group.HasToolbar = true;
group.Activate();
}
// Invoked by SolidWorks when the item is clicked.
public void OnShowPage()
{
// Work goes here.
}
// Consulted before the item is displayed.
public int CanShowPage()
{
return _sw.ActiveDoc == null ? 0 : 1;
}
The item-level option decides where an item may appear; the group-level properties decide whether a menu or toolbar is produced at all. Setting the group's toolbar property to false suppresses toolbar buttons even for items that requested them.
05Enable methods
An enable method is consulted immediately before the item is drawn, which makes it the correct place to express command availability rules. It is also a performance-sensitive path: it runs every time the menu is opened.
| Concern | Guidance |
|---|---|
| Cost | Keep the body to cheap checks — is a document open, is it the right type, is something selected. Do not traverse the model. |
| Determinism | The same state must always give the same answer, or commands will appear to flicker between enabled and disabled. |
| Failure | Never let an enable method throw. An exception here executes inside the host while it is drawing its own menu. |
| Feedback | Disabling a command silently is not an explanation. Where a command is unavailable for a non-obvious reason, say so in the status-bar hint. |
06Removing commands on disconnect
Command groups are owned by the host, not by your assembly. If they are not removed when the add-in unloads, they remain in the menus and toolbars with no code behind them.
public bool DisconnectFromSW()
{
RemoveCommands();
_cmdMgr = null;
_sw = null;
GC.Collect();
GC.WaitForPendingFinalizers();
return true;
}
private void RemoveCommands()
{
if (_cmdMgr != null)
_cmdMgr.RemoveCommandGroup(GroupId);
}
The value passed to remove the group must be the value used to create it. Where those are two separate literals in two separate methods, they eventually diverge — and the resulting orphaned toolbar is difficult to trace back to its cause. One constant.
07Command design in practice
Group by task, not by implementation
Users navigate by what they are trying to do. A group named for a workflow is easier to find than one named for the module that happens to contain the code.
Keep callbacks thin
A callback should validate, delegate and return. Putting the work itself in a separate method keeps it testable and keeps the callback's failure surface small.
Name callbacks distinctively
Because resolution is by name at runtime, callback method names should be unlikely to collide with anything else on the routing target.
Reserve identifier ranges
Allocate a documented range of group and item identifiers per functional area. It costs nothing now and prevents collisions when the add-in grows.
08Quick reference
- Order of operations
- Route callbacks, acquire the Command Manager, create the group, add items, set group properties, activate.
- One manager
- A single Command Manager serves any number of groups.
- Group identity
- Unique integer per group, held as a constant, reused for removal.
- Item placement
- Bit mask of the command item type values decides menu, toolbar or both.
- Enable method
- Returns a value in the range zero to four; consulted before display.
- Teardown
- Remove every group during disconnect, before releasing the manager.
09Where this leads
Continue in this pathway
- Part 01Add-in architecture and the integration model
- Part 02Development environment and project configuration
- Part 03COM registration and add-in discovery
- Part 04Command Manager, menus and toolbars
- Part 05Property Manager Pages and the control model
- Part 06Event and notification architecture
- Part 07Add-in, stand-alone or hybrid
- Part 08Planning, structure and debugging discipline
- Part 09Deployment methods and installer engineering
- Part 10Licensing, distribution and commercialisation
