Adding a Menu Item from Your Extension

This is the second post in the Writing your First Extension series. You can see the full article here: Writing Your First Extension.

Menu items are added via the IPN object provided at extension load time. You add menu items by providing an implementation of IMenuItems. Here is a very simple implementation supporting a single item:

class Menu : public extensions::IMenuItems
{
public:
    Menu()
    {
        memset(&item1, 0, sizeof(item1));
        item1.Handler = &MyExtensionFunc;
        item1.Title = L"Hello World";
        // item1.Type = extensions::miItem;
        // item1.UserData = 0;
    }

    /**
     * Get the number of MenuItem instances that can be retrieved.
     */
    virtual int GetItemCount() const
    {
        return 1;
    }

    /**
     * Get an individual MenuItem instance by index.
     */
    virtual extensions::MenuItem& GetItem(int index) const
    {
        if (index == 0)
            return const_cast<extensions ::menuitem&>(item1);
    }

private:
    extensions::MenuItem item1;
};

This very simple implementation adds a single menu item called "Hello World". When the item is selected, the MyExtensionFunc method will be executed by PN.

It might seem like a fair bit of code to add a menu item, but in the next SDK version I’ll provide a general-purpose helper to make this easy. The reason for the interface is to make it easy for you to provide sub-menus. MenuItem instances can contain child items by changing Type to miSubItem and filling in the SubItems member with another instance implementing IMenuItems.

The handler method looks like this:

void MyExtensionFunc(extensions::cookie_t /*cookie*/)
{
    g_PN->GetGlobalOutputWindow()->AddToolOutput("Hello World!");
    g_PN->ShowOutput();
}

Once you have your handler and IMenuItems implementation, you just need to tell PN about your items. In your init function you need something like this:

bool __stdcall pn_init_extension(int iface_version, extensions::IPN* pn)
{
    if(iface_version != PN_EXT_IFACE_VERSION)
        return false;

    g_PN = pn;

    Menu menu;
    pn->AddPluginMenuItems(&menu);

    return true;
}

Now you have Programmer’s Notepad presenting your commands in the menu and can handle their selection. Next time we’ll look at the other events PN lets you attach to.

Comments are closed.