Virtools Interface SDK

  1. Overview
  2. Creating a Virtools Dev Interface Plugin with the AppWizard in Microsoft Visual Studio .Net 2003
  3. Filling the PluginInfo structure to define a Virtools Interface Plugin
  4. Graphic User Interface
  5. Plugin Callback
  6. Plugin Communication with Virtools Dev
  7. Plugin Menu
  8. Plugin Customizable Keyboard Shortcuts
  9. VIControls
  10. CKControls

Overview

What is the Virtools Interface SDK?

In a nutshell, the Virtools interface is now open to the integration of external plugins (DLLs), a.k.a. Managers.

In previous versions of Dev, new proprietary functionalities required coding Building Blocks to be able to edit parameters within Dev's interface. The Virtools Interface SDK now makes it possible to create user interfaces in Dev - via the creation of plugins or Managers - for your proprietary technology. For example, develop your own manager to edit 3D objects directly within Dev's interface. An AppWizard even provides you with a jump start.

New Managers (e.g. external dlls) are coded using the Virtools Interface SDK and win32 or Windows MFC (Microsoft Foundation Classes). In the example above (creating a Manager to manipulate objects), you would create an interface using Windows MFC and the Virtools Interface SDK, while the Virtools SDK (cK2, VXMath,...) would be used to manipulate the objects themselves.

What can we do with the Virtools Interface SDK?

Here are some of the Virtools Interface SDK's possible applications:

  • Create an editor or manager whose interface is plugged into the Virtools graphic user interface.
  • Add personalized menus in main menu of Virtools.
  • Create a plugin (with or without an interface) that react to certain events in Virtools
  • Create another source control plugin (if you do not wish to use Dev's NXN Alienbrain source control feature.)
The Virtools Interface SDK is used to create Plugins with a user interface within Virtools Dev's own interface. The plugin can be an editor, like an animation editor, or can be a manager, like the Action Manager. What type of plugin you create is up to you.

Using Virtools Interface SDK

The following chapters explain how to use the Virtools Interface SDK and should be read in sequential order.
  1. Creating a Virtools Dev Interface Plugin with the AppWizard in Microsoft Visual Studio .Net 2003
  2. Filling the PluginInfo structure to define a Virtools Interface Plugin
  3. Graphic User Interface
  4. Plugin Callback
  5. Plugin Communication with Virtools Dev
  6. Plugin Menu
  7. Plugin Customizable Keyboard Shortcuts
  8. VIControls
  9. CKControls

Next: Creating a Virtools Dev Interface Plugin with the AppWizard in Microsoft Visual Studio .Net 2003

Comments


Creating a Virtools Interface Plugin in Visual C++ 6.0

  1. Overview
  2. Creating a Virtools Dev Interface Plugin with the AppWizard in Microsoft Visual Studio .Net 2003
  3. Filling the PluginInfo structure to define a Virtools Interface Plugin
  4. Graphic User Interface
  5. Plugin Callback
  6. Plugin Communication with Virtools Dev
  7. Plugin Menu
  8. Plugin Customizable Keyboard Shortcuts
  9. VIControls
  10. CKControls

Creating a Virtools Dev Interface Plugin with the AppWizard in Microsoft Visual Studio .Net 2003

Requisite SDK Files

  • CK2Win32 & VxMath: Main Virtools SDKs to access and manipulate Virtools Dev's current composition.
  • VIControls: SDK for overridden Windows basic controls, such as as classes derived from CButton, and new Windows controls with a Virtools Dev look and feel.
  • CKControls: SDK for Windows controls specialized for CK2Win32 SDK data, such as dialog to edit several CKParameters, a list control and a tree control with a Virtools Dev look and feel, etc.
  • DLLEditor: The main Virtools Interface SDK to build Virtools Interface Plugins/Managers.

All SDK headers should be in: Virtools_Dev_directory/SDK/includes/
All SDK libraries should be in: Virtools_Dev_directory/SDK/lib/

Virtools Interface SDK

The Virtools Interface SDK consists of the following files:

  • VEP_PluginInfo.h: Contains essential data for Virtools Dev to load a plugin dynamically. According to the plugin type, you should fill the EditorInfo member structure (if m_PluginType==EDITOR), or the VersionControl structure (if m_PluginType==VERSIONCONTROL), or no other file (if m_PluginType==NOINTERFACE).
  • VEP_EditorInfo.h: For plugins of type Editor, it contains essential data for Virtools Dev to build the plugin editor's interface dynamically.
  • VEP_EditorDlg.h: Base dialog classes for the editor's toolbar and main interface.
  • VEP_PluginInterface.h: Contains many functions used to communicate with Virtools Dev. A Virtools Interface Plugin programmer can get to the global instance pointer of a Plugin Interface from the plugin callback or from the editor or toolbar dialog code.
  • VEP_VersionControl.h: Contains the function pointers needed for a source control plugin. If your plugin is of type VERSIONCONTROL then you should fill the m_VersionControl member of the PluginInfo structure; otherwise, if there is an available source control plugin such as the NXN alienbrain plugin, you will be able to access to the current instance of the VersionControl structure used by Virtools Dev from the PluginInterface instance.
  • CUIKNotifications.h: List of notifications used by Virtools Dev when something changes in the composition or the interface.
  • CUIKEntitySet.h: Array of object description (of class CUIKCKObjectDescription), used during drag & drop operations.
  • CUIKCKObjectDescription.h: Generic description of an object (may be a CK object, a filename, a bitmap, etc.)
  • VEP_KeyboardShorcutManager.h: Keyboard shortcut manager whose instance can be gotten from the PluginInterface instance.
  • VEP_DLLEditorLibDefines.h: Definitions and macros for Virtools Interface Plugins.
  • VEP_All.h: Generic header that contains almost all other header, used by the StdAfx.h of Virtools Interface Plugins.

Class Diagram

Below is a Class diagram that shows the Virtools Interface SDK Classes:

Dynamic Process Diagram

The diagram below shows how those classes (above) interact with the dynamic processes of the Dev.

The App Wizard for Microsoft Visual Studio .Net 2003

The Virtools Interface SDK (dll) App Wizard allows you to easily create a basic Virtool Manager/Plugin Project. In order for this App Wizard to be available, copy the content of the SDK/Utils/Wizard to C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7 (or the equivalent path if you installed Microsoft Visual Studio .Net 2003 elsewhere). IMPORTANT: This AppWizard has been made specifically for Microsoft Visual Studio .Net 2003 and will not work with other versions, such as Microsoft Visual C++ 6.0.

In Microsoft Visual Studio .Net 2003, open the File->Add Project->New Project... menu
Choose Virtools Interface Plugin Template from the Visual C++ Projects Project Type:

Then click on "ok." You will get the following dialog:

    • Plugin Type:
      • EDITOR: Default value, to create a plugin with an interface in Virtools Dev, that may be opened from the Editors menu in Virtools Dev menu (unless the editor is indestructible, in which case the editor will always be present). Editor always have an editor dialog, and optionally, may have a toolbar dialog.
      • NOINTERFACE: To create a plugin without a user interface in Virtools Dev.
      • VERSIONCONTROL: To create a version control plugin for Virtools Dev. (Note: a NXN alienbrain plugin for Virtools Dev already exists).
    • Plugin Name: Specify the plugin name here.
    • Callback: Check this to have a callback in your plugin. This callback will be called by Virtools Dev on specific occurrences, that are : on plugin load, and unload, when the composition name changes, and when an interface notification is sent. (see VEP_PluginInfo.h) Note that you may receive interface notifications only if you check the Get Notifications checkbox.
    • Get Notifications: Available only if Callback is checked. Check to get Virtools Dev notification messages in your callback. Notifications are various messages sent when something has changed in the composition or interface.
    • Menu: Check this to have a personalized menu added in Virtools Dev interface. Sample code will be added to your plugin code.
    • Keyboard Shortcuts: Check this to have sample code added that shows you how to have customizable keyboard shortcut.
    • Include Directories: Specify your Virtools SDK include directory here.
    • Library Directories: Specify your Virtools SDK library directory here.
    • Virtools Dev Directory: Specify your Virtools Dev directory here.
    • Editor: Automatically checked when the plugin type is EDITOR.
      • Name: Specify the name of your editor here.
      • GUID: Unique guid of your editor, press the Generate button next to the guid to generate another. You may edit it in the code later.
      • Unique: Check this to specify that your editor can have only one occurrence (at most) in the Virtools Dev interface. If unchecked, the user will be able to open several instances of the editor in Virtools Dev - from the Editors pulldown menu of Virtools Dev, or by drag and drop of the tab of this editor with the Shift key down.
      • Icon: The editor will have an icon that will be visible in Virtools Dev left to its tab name.
      • Permanent: The editor will be a permanent editor in Virtools Dev and will not be able to be closed. (e.g. 3D Layout, Schematic, Level View, etc.)
      • Menu: Adds sample code to have a custom contextual popup menu on the editor's tab name in Virtools Dev interface, when the editor is opened.
      • Tooltip: Adds sample code to have tooltips in the plugin Editor Dialog code.
      • Fixed Size: By default the editor opens in the bottom pane of the screen (like the Level View or Schematic). You should check this if you want the editor to have a predetermined size, so that scrollbars will automatically be added when the available room is too small. The size can be changed dynamically: for Virtools Dev to take the change into account, you must call DLLEditorDlg::UpdateEditorSize() (see VEP_DLLEditorDlg.h).
        • Width: Specify the width of the editor here.
        • Height: Specify the height of the editor here.
    • Toolbar: Check this so that the editor will have a toolbar. Available only when the plugin type is EDITOR.
      • Default Height: The editor toolbar will have the default height (21 pixels). Uncheck to have a custom height.
        • Height edit: Available only when Default Height is unchecked. Specify custom height here.
      • Close Button: The editor will have a close button.
      • Auto Draw Toolbar: The toolbar border will be automatically draw (in white when the editor is active, grey otherwise)
      • Tooltip: Adds sample code to have tooltips in the plugin Toolbar Dialog code.

Files Generated by the AppWizard

If we created a project named Test, of type Editor, and with all options checked, here is the list of files that would be created:

  • Test.dsp: The project file
  • StdAfx.cpp & StdAfx.h: The files that will generate the precompiled header which includes all SDKs.
  • icon1.ico: The editor's icon.
  • Test.rc & resource.h: Resource files that contains the templates for the editor and the toolbar dialogs.
  • res\TestEditor.rc2: Secondary resource file.
  • TestEditor.def: Exported functions declaration.
  • TestEditor.cpp & TestEditor.h: DLL main entry, filling of the PluginInfo structure that contains all necessary information for Virtools Dev to construct the editor.
  • TestEditorDlg.cpp & TestEditorDlg.h: Editor dialog.
  • TestToolbarDlg.cpp & TestToolbarDlg.h: Editor's toolbar dialog
  • TestCallback.cpp & TestCallback.h: Plugin callback for Virtools Dev. It is used to register the plugin menu, keyboard shortcuts and variables, and to catch the PluginInterface class instance that allows communication with virtools.
  • TestMenu.cpp & TestMenu.h: Sample code for a plugin menu present in Virtools Dev main menu.
  • TestKeyboardShortcuts.cpp & TestKeyboardShortcuts.h: Sample code for customizable keyboard shortcuts. These shortcuts may be edited by a Virtools Dev user within the interface, and are saved when Virtools Dev is closed.

Note about Virtools Dev Interface SDK namespace

All classes and structures defined in the Virtools Interface SDK are enclosed within the VirtoolsExternalPlugin namespace.

The line:

using namespace VirtoolsExternalPlugin;

is already defined in the precompiled header of Virtools Interface Plugins, so you will not have to specify VirtoolsExternalPlugin:: when using those classes and structures as variables (unless there is an ambiguity).

Sample Projects

In the Virtools_SDK\Samples\Virtools Interface SDK (where Virtools_SDK is the SDK folder), the following sample projects are provided to help you examine how plugins are coded:

  • TestEditor: An empty project created with the AppWizard (with all options).
  • Shader Editor: This project is create the Shader Editor - the user interface for the Shader Manager.

Next: Filling the PluginInfo structure to define a Virtools Interface Plugin


Filling the PluginInfo structure

  1. Overview
  2. Creating a Virtools Dev Interface Plugin with the AppWizard in Microsoft Visual Studio .Net 2003
  3. Filling the PluginInfo structure to define a Virtools Interface Plugin
  4. Graphic User Interface
  5. Plugin Callback
  6. Plugin Communication with Virtools Dev
  7. Plugin Menu
  8. Plugin Customizable Keyboard Shortcuts
  9. VIControls
  10. CKControls

Filling the PluginInfo structure to define a Virtools Interface Plugin/Manager

Continuing from our previous example of creating an AppWizard project named Test (of type Editor with all options checked), the following files are covered in this chapter:

  • Files related to the Virtools Interface Plugin SDK header: VEP_PluginInfo.h , VEP_EditorInfo.h , VEP_VersionControlInfo.h.
  • Main DLL files related to the Plugin sample: TestEditor.cpp , TestEditor.h and TestEditor.def.

Plugin exported functions

In a Virtools Interface Plugin, two functions have to be exported (the code should be in the TestEditor.cpp and TestEditor.def files:

  • GetVirtoolsPluginInfoCount: Returns the number of plugins in the DLL.
  • GetVirtoolsPluginInfo(int n): Returns the adress of the PluginInfo structure that describes the nth plugin present in the DLL.

    Sample code in TestEditor.cpp:

//TestEditor.cpp
//sample with one plugin
[...]

//The Plugin Info structure that must be filled for Virtools Dev to load effectively the plugin
PluginInfo g_PluginInfo0;

//Returns the number of plugin contained in this dll
//this function must be exported (have a .def file with its name or use __declspec( dllexport )
int GetVirtoolsPluginInfoCount()
{
    return 1;
}

//returns the ptr of the (index)th plugininfo structure of this dll
//this function must be exported (have a .def file with its name or use __declspec( dllexport )
PluginInfo* GetVirtoolsPluginInfo(int index)
{
    switch(index)
    {
    case 0:
        return &g_PluginInfo0;
    }
    return NULL;
}

Sample code in TestEditor.def:

EXPORTS
    GetVirtoolsPluginInfoCount
    GetVirtoolsPluginInfo

Then override the InitInstance function of your DLL to fill the PluginInfo structure g_PluginInfo0, which contains the plugin's description.

PluginInfo structure members

In the main DLL file, here TestEditor.cpp, the CTestEditorApp::InitInstance() function is used to fill a static PluginInterface structure. This structure contains the basic plugin's informations.

  • m_PluginType: Available values are:
    • PT_UNKNOWN: Plugin with no graphic interface (not very usefull yet. May be a plugin that just react to Virtools Dev notifications to alter the current composition)
    • PT_VERSIONCONTROL: Source control plugin such as Microsoft Visual Source Safe and NXN Alien Brain source control management, but integrated in Virtools Dev. There is already an NXN alienbrain plugin with Virtools Dev 3.0.
    • PT_EDITOR: The basic plugin with an interface available in Virtools Dev
    • PTF_RECEIVENOTIFICATION: This is a flag and may be added to the plugin type if you want your plugin to receive Virtools Dev notifications.
  • m_Name: Plugin name.
  • m_PluginCallback: Plugin callback, this is a function pointer that Virtools Dev will use to send messages to the plugin. Available reasons for these messagess are:
    • CR_LOAD: The plugin has just been loaded
    • CR_UNLOAD: The plugin will be unloaded
    • CR_NEWCOMPOSITIONNAME: The current composition name has changed, means that the user has loaded another composition, or that he has saved the current composition with a new name.
    • CR_NOTIFICATION: A notification has just occured in Virtools Dev and is sent to the plugin if the plugin requested it.
  • m_EditorInfo: Structure used to store essential data for Virtools Dev to build dynamically the editor's interface.
  • m_VersionControl: Structure used to store essential functions pointers for a source control management.

According to the plugin type, you must then fill the:

  • m_EditorInfo structure if the plugin type is PT_EDITOR
  • m_VersionControl structure if the plugin type is PT_VERSIONCONTROL
  • nothing if the plugin type is PT_UNKNOWN (plugin without interface)

EditorInfo structure members for plugins of type EDITOR (VEP_EditorInfo.h)

The EditorInfo structure is used to describe how the editor will be in Virtools Dev interface.

  • m_Guid: A unique guid.
  • m_EditorName: The editor's name.
  • m_CreateEditorDlgFunc: Callback to create the main dialog of the editor.
  • m_CreateToolbarDlgFunc: Callback to create the toolbar dialog of the editor.
  • m_bUnique: Equivalent to the Unique field in the AppWizard.
  • m_bIndestructible: Equivalent to the Permanent field in the AppWizard: the editor will be permanent, that is present when Virtools Dev is launched, and that cannot be closed.
  • m_bManageScrollbar: Equivalent to the Fixed Size field in the AppWizard. If set to TRUE then the editor will use a fixed size defined by the 2 following fields m_Width and m_Height. Virtools Dev will then automatically add scrollbars when needed.
  • m_Width: Width of the editor if m_bManageScrollbar is set to TRUE.
  • m_Height: Height of the editor if m_bManageScrollbar is set to TRUE.
  • m_ToolbarHeight: Toolbar height, 21 pixels by default. If set to 0 then the default value of 21 is used.
  • m_IconList: Image list of the editor. It is mainly used to store the editor's icon. If you do not want any icon, just set this variable to NULL.
  • m_IconIndex: Index of editor's icon in its image list. The icon will be shown left the editor name in its tab in Virtools Dev interface.

VersionControlInfo structure members for plugins of type VERSIONCONTROL (VEP_VersionControlInfo.h)

The VersionControlInfo structure is used to store all functions needed for a source control manager. Only one source control plugin can be active within Virtools Dev. If there is an active source control plugin, then other Virtools Plugin may use it for their own needs.

A Source Control plugin based on NXN alienbrain technology is already provided with Virtools Dev 3.0 (with the Virtools_Dev_directory/InterfacePlugins/VersionControl.dll file).
Note: Only one source control plugin should present. If there is more than one source control plugins, only the last plugin (in alphabetical order) will be taken into account; however, we recommend removing all unused source control plugin (dlls).

  • m_Start: To call after loading DLL.
  • m_Stop: To call before unloading DLL.
  • m_IsEnabled: Is source control plugin active?
  • m_Enable: Enable/disable source control plugin.
  • m_OnPreOpen: Callback that should be called before opening file.
  • m_OnPostOpen: Callback that should be called after opening file.
  • m_OnPreSave: Callback that should be called before saving file.
  • m_OnPostSave: Callback that should be called after saving file.
  • m_OnPreClose: Callback that should be called before closing file.
  • m_CheckOut: Check out item.
  • m_CheckIn: Check in item.
  • m_Import: Import item and add it in source control database.
  • m_GetLatestVersion: Get latest version of item.
  • m_UndoCheckOut: Undo check out item.
  • m_AddToSourceControl: Add item to source control.
  • m_RemoveFromSourceControl: Remove item from source control.
  • m_LoadFileFromSourceControl: Load file from source control.
  • m_IsNodeInDatabase: Is item in source control database?
  • m_ShowDatabaseExplorer: Show database explorer.
  • m_EditSettings: Edit source control settings.
    m_ShowHistory: Show history of file if mapped in source control.
    m_ShowDifferences: Show difference of file with previous version (not available yet).
    m_ShowProperties: Show file properties if mapped in source control.
  • m_AddSourceControlMenuTo: Add to a CMenu* some commands according to file state (i.e. if the file is checked out, then this should add to the CMenu the commands Check In and Undo Check Out).
  • m_MenuCallback: Callback to use after a call to m_AddSourceControlMenuTo.
  • m_GetImageList: Returns image list with source control icons (file/folder/project, checked out or not, synchronised with database or not)
Next: Plugin's Graphic User Interface


Graphic User Interface

  1. Overview
  2. Creating a Virtools Dev Interface Plugin with the AppWizard in Microsoft Visual Studio .Net 2003
  3. Filling the PluginInfo structure to define a Virtools Interface Plugin
  4. Graphic User Interface
  5. Plugin Callback
  6. Plugin Communication with Virtools Dev
  7. Plugin Menu
  8. Plugin Customizable Keyboard Shortcuts
  9. VIControls
  10. CKControls

Graphic User Interface (editor and toolbar dialogs)

Continuing from our previous example of creating an AppWizard project named Test (of type Editor with all options checked), the following files are covered in this chapter:

  • Files related to the Virtools Interface Plugin SDK header: VEP_DllEditorDlg.h.
  • Related files in Plugin sample: TestEditorDlg.cpp , TestEditorDlg.h , TestToolbarDlg.cpp , TestToolbarDlg.h.

A Virtools Plugin of type Editor is composed of 2 dialogs: one for the editor and one for the toolbar (optional). These dialogs use MFC resource template. The Editor Dialog class derives from the DllEditorDlg class included in the Virtools Virtools Interface SDK, the Toolbar Dialog derives from the DllToolbarDlg class. Both of these classes are derived from CDialog. So programming a plugin Editor for Virtools Dev derives mainly to programming 2 MFC dialogs and using communication tools with Virtools Dev. Communication mainly consists of notifications messages and the use of a PluginInterface class.

  • Notifications are messages that flow within Virtools Dev. They happen when something changes in the current composition or in the interface, and can be caught by Virtools Interface Plugins. They are defined by an ID, two parameters of type DWORD and a context (CKScene*, see Virtools SDK, CK2Win32). The way the two DWORD parameters are used depends on the notifications and is described in CUIKNotifications.h of the Virtools Virtools Interface SDK.
  • The PluginInterface class contains a list of tool functions used for:
    • Virtools Dev interface manipulations.
    • Getting information from Virtools Dev interface.

      The global instance of the PluginInterface class, stored by Virtools Dev, is available for the DLL Editor and toolbar dialogs when the OnInterfaceInit() callback is called, and each time the Plugin Callback is called (member PluginInfo::m_PluginCallback)

Dialog Interface overview:

DllEditorDlg and DllToolbarDlg derive from the class DllDialogInterface, whose member functions are:

  • OnInterfaceInit(): Called by Virtools Dev when both editor and toolbar of the plugin have been created and initialized.
  • OnInterfaceEnd(): Called when the win32 message WM_DESTROY is caught, just before the dialog is deleted.
  • OnActivate(..): Called by Virtools Dev when editor is activated or deactivated; that is, when the editor gets or loses the focus. The editor's border becomes white when activated, and grey when deactivated.
  • CanDrop(..): Called by Virtools Dev when something is dragged over the editor/toolbar. This is used to set the cursor if the dragged selection is to be taken into account.
  • OnDrop(..): Called by Virtools Dev when something is dropped on the editor/toolbar.
  • DropExit(): Called by Virtools Dev during a drag & drop when the mouse leaves the editor/toolbar.
  • ObserveNotification(..): Use this function to tell Virtools Dev's interface you want to wait for a specific notification. Note that you should specify which notification you are waiting for in the OnInterfaceInit() callback.
  • SendNotification(..): To send a notification that Virtools Dev or any plugin may take into account.
  • ReceiveNotification(..): Called by Virtools Dev when a notification is sent that the plugin is waiting for. To wait for a notification, use the ObserveNotification() function.
  • GetInterface(): Gets the instance of the PluginInterface class, which is used to communicate with Virtools Dev.
  • GetOwner(): Gets the owner of the editor and is only needed for PluginInterface::ObserveNotification() and PluginInterface::SendNotification().
  • GetCKContext(): Returns the pointer to the current CKContext (see Virtools SDK, CK2Win32).
  • GetFlags(): Gets the dialog flags. Existent flags are DllDialogInterface::NONE, DllDialogInterface::ACTIVE and DllToolbarDlg::DRAWTOOLBAR. Values greater than 2 are available for Virtools plugin programmers.
  • ModifyFlags(): To modify the editor or toolbar dialog flags.

Important: the GetInterface(), GetOwner() and GetCKContext() will return NULL until the OnInterfaceInit() callback is called.

For further information, such as function parameters, you should read the header VEP_DllEditorDlg.h.

Toolbar Dialog overview:

  • ActivateClosebutton(..): To show or hide a Close button at the right of the toolbar.
  • GetEditorDlg(): Returns the pointer to the editor dialog.

Editor Dialog overview:

  • Close(): Closes the Editor. It will not work if the plugin has been set as Permanent in the AppWizard (EditorInfo::m_bIndestructible set to 1).
  • OnCustomMenu(CMenu*,..): Called by Virtools Dev when the user right-clicks on the editor tab's name, to complete the popup menu with custom commands.
  • OnCustomMenu(int commandID): Called by Virtools when the user chooses a custom command created by the OnCustomMenu(CMenu*,..).
  • UpdateEditorSize(): When the EditorInfo::m_Width and/or EditorInfo::m_Height changes, you must call this function for Virtools Dev to take the changes into account. (Note that it is only useful for editors with Fixed Size.)
  • SaveData(CKInterfaceObjectManager*): Called by Virtools Dev when user saves the composition; this callback is for the editor to save custom data related to the composition. The CKInterfaceObjectManager class ( see Virtools SDK, CK2Win32) can store one or several CKStateChunks, which is a class for easily creating buffers.
  • LoadData(CKInterfaceObjectManager*): Called by Virtools Dev when the user loads a new composition; data saved on the SaveData() callback can be retrieved .
  • GetToolbarDlg(): Returns the pointer to the editor's toolbar dialog.
Next: Plugin Callback


Plugin Callback

  1. Overview
  2. Creating a Virtools Dev Interface Plugin with the AppWizard in Microsoft Visual Studio .Net 2003
  3. Filling the PluginInfo structure to define a Virtools Interface Plugin
  4. Graphic User Interface
  5. Plugin Callback
  6. Plugin Communication with Virtools Dev
  7. Plugin Menu
  8. Plugin Customizable Keyboard Shortcuts
  9. VIControls
  10. CKControls

Plugin Callback

Continuing from our previous example of creating an AppWizard project named Test (of type Editor with all options checked), the following files are covered in this chapter:

  • Files Related to Virtools Interface Plugin SDK header: VEP_PluginInfo.h.
  • Related files in Plugin sample: TestCallback.cpp, TestCallback.h.

Overview

The Plugin callback - whose address must be stored in PluginInfo::m_PluginCallback in order to work - is used to know when:

  • The plugin is loaded.
  • The plugin is unloaded.
  • The current composition's name changes.
  • A notification happens.

The Plugin callback has two parameters:

  • A reason, i.e. the kind of event that just happened. Reasons are defined in the CALLBACK_REASON enum in the declaration of the PluginInfo structure.
  • A pointer to the global instance of the PluginInterface class. This is a way to get the pointer to the global instance of the PluginInterface structure.

Receiving notifications

To receive Virtools Dev notifications, the member PluginInfo::m_PluginType must have the flag PTF_RECEIVENOTIFICATION in addition to the plugin type.

TestCallback.cpp

#include "stdafx.h"
#include "TestCallback.h"

#include "TestKeyboardShortcuts.h"

#include "TestVariable.h"

#include "TestMenu.h"

//static plugin interface that allow direct communication with Virtools Dev
PluginInterface* s_Plugininterface = NULL;

//main plugin callback for Virtools Dev
void PluginCallback(PluginInfo::CALLBACK_REASON reason,PluginInterface* plugininterface)
{
  switch(reason)
  {
  case PluginInfo::CR_LOAD:
  {
    s_Plugininterface = plugininterface; //Gets the PluginInterface instance
    InitMenu();                          //Create Plugin Menu
    UpdateMenu();                        //Fill Plugin Menu
    RegisterKeyboardShortcutCategory();  //Register Keyboard Shortcut Category
    RegisterKeyboardShortcuts();         //Register keyboard shortcuts
  }break;
  case PluginInfo::CR_UNLOAD:
  {
    RemoveMenu();                        //Remove Plugin Menu
    UnregisterKeyboardShortcutCategory();//Unregister Keyboard Shortcut Category
    s_Plugininterface	= NULL;
  }break;
  case PluginInfo::CR_NEWCOMPOSITIONNAME:
  {
    //on new/loaded composition
  }break;
  case PluginInfo::CR_NOTIFICATION:
  {
    //on notification
  }break;
  }
}

In the following sample, we checked all available options. When the plugin is loaded, we store the PluginInterface pointer, initialize the plugin menu, and register the keyboard shortcuts.

The programmer can add necessary operations in response to those callbacks.

Next: Plugin Communication with Virtools Dev


Plugin Communication with Virtools Dev

  1. Overview
  2. Creating a Virtools Dev Interface Plugin with the AppWizard in Microsoft Visual Studio .Net 2003
  3. Filling the PluginInfo structure to define a Virtools Interface Plugin
  4. Graphic User Interface
  5. Plugin Callback
  6. Plugin Communication with Virtools Dev
  7. Plugin Menu
  8. Plugin Customizable Keyboard Shortcuts
  9. VIControls
  10. CKControls

Communication with Virtools Dev

Plugin Interface

Continuing from our previous example of creating an AppWizard project named Test (of type Editor with all options checked), the following files are covered in this chapter:
  • Files related Virtools Interface Plugin SDK header: VEP_PluginInterface.h.
  • Related files in Plugin sample: TestCallback.cpp , TestEditorDlg.cpp , TestToolbarDlg.cpp.

Get the PluginInterface instance

The class PluginInterface is used to communicate with the Virtools Dev interface. There is only one available instance that may be used by the Plugin Callback or from the Editor or Toolbar Dialogs.

  • Get PluginInterface pointer from Plugin Callback: Save the PluginInterface pointer, send as 2nd parameter in a static variable (in the sample file TestCallback.cpp).
    //TestCallback.cpp
PluginInterface* s_Plugininterface=NULL;

void PluginCallback(PluginInfo::CALLBACK_REASON reason,PluginInterface* plugininterface)
{
  switch(reason)
  {
  case PluginInfo::CR_LOAD:
    {
    s_Plugininterface=plugininterface;
    //...
    }break;
  }
  //...
}
  • Get PluginInterface pointer from the Editor or Toolbar dialog: call DllEditorDlg::GetInterface() or DllToolbarDlg::GetInterface() (in the sample files TestEditorDlg.cpp or TestToolbarDlg.cpp). This function returns a valid result only after the OnInterfaceInit() callback is called(),otherwise GetInterface() returns NULL.

Overview

The PluginInterface class contains a list of tool functions used for:

    • Rendering functions
    • Manipulation of selection in 3DEditor
    • Launch object setups/know if an object is edited
    • Status Bar tools functions
    • CK centralized functions for copy and deletion (you should use them instead of using directly CK in order to Virtools Interface being aware of your action
    • An interface parameter pool: for better memory management, and instead of creating your own CKParameters, just ask for a parameter and free it when you want, or even forget about it, it will be deleted when you leave Virtools
    • Virtools Directories
    • Project Modified Flags Access
    • Drag and Drop
    • User menu added to Virtools main menu with user menu callback
    • Virtools Load and Save functionalities
    • Exiting function
    • last notification send by Virtools Interface
    • A CKContext for CK access (see Virtools SDK, CK2Win32)
    • A VersionControlInfo structure if a version control plugin is loaded and available. Thus you can use Version Control in your plugin as well.

Read VEP_PluginInterface.h for the full list of available functions.

Notifications

Continuing from our previous example of creating an AppWizard project named Test (of type Editor with all options checked), the following files are covered in this chapter:
  • Files related Virtools Interface Plugin SDK header: CUIKNotifications.h.
  • Related files in Plugin sample: TestCallback.cpp , TestEditorDlg.cpp , TestToolbarDlg.cpp.

Reminder: Notifications are messages that flow within Virtools Dev. They happen when something changes in the current composition or in the interface, and can be used by Virtools Interface Plugins. They are defined by an ID, two parameters of type DWORD and a context (CKScene*, see Virtools SDK, CK2Win32). The way the two DWORD parameters are used depends on the notifications and is described in CUIKNotifications.h of the Virtools Virtools Interface SDK.

Notifications can be sent and received with the editor or toolbar dialogs, or sent with the PluginInterface class:

HRESULT PluginInterface:: SendNotification(void* owner,
  UINT MsgID,
  DWORD Param1=0,
  DWORD Param2=0,
  CKScene* Context=NULL);
Read the file CuikNotifications.h to have the full commented list of notifications.

Next: Plugin Menu


Plugin Menu

  1. Overview
  2. Creating a Virtools Dev Interface Plugin with the AppWizard in Microsoft Visual Studio .Net 2003
  3. Filling the PluginInfo structure to define a Virtools Interface Plugin
  4. Graphic User Interface
  5. Plugin Callback
  6. Plugin Communication with Virtools Dev
  7. Plugin Menu
  8. Plugin Customizable Keyboard Shortcuts
  9. VIControls
  10. CKControls

Plugin Menu

Continuing from our previous example of creating an AppWizard project named Test (of type Editor with all options checked), the following files are covered in this chapter:
  • File related Virtools Interface Plugin SDK header: VEP_PluginInterface.h.
  • Related files in Plugin sample: TestMenu.cpp, TestMenu.h, TestCallback.cpp, TestEditorDlg.cpp, TestEditorDlg.h.

OverView

There are two sorts of Plugin Menus:

  1. A custom plugin menu can be added to Virtools Dev main pulldon menu.
  2. A custom plugin menu can be added when the user right-clicks on the editor's tab name, when the editor is present in Virtools Dev interface.

1) Custom Plugin Menu in Virtools Dev main menu

There are two places where you may create and show the plugin menu

  1. When the plugin is loaded. You then must have a Plugin Callback: the menu must be added on the PluginInfo::CPR_LOAD reason, and removed on the PluginInfo::CPR_UNLOAD reason.
    //PluginCallback.cpp
// [...]
//
void PluginCallback(PluginInfo::CALLBACK_REASON reason,PluginInterface* plugininterface)
{
  switch(reason)
  {
  case PluginInfo::CR_LOAD:
  {
    s_Plugininterface = plugininterface;
    InitMenu();                          //Create Plugin Menu
    UpdateMenu();                        //Fill Plugin Menu
    //[...]
  }break;
  case PluginInfo::CR_UNLOAD:
  {
    RemoveMenu();                        //Remove Plugin Menu
    //[...]
    s_Plugininterface= NULL;
  }break;
  //[...]
}
    The functions InitMenu(), UpdateMenu() and RemoveMenu() are use on load and unload callbacks.
    //TestMenu.cpp
//[...]
//declaration of menu callback (for InitMenu function)
void PluginMenuCallback(int commandID);

//static main menu
CMenu* s_MainMenu = NULL;

#define PLUGINMENU_MAXENTRIES 20	//put there the max entries your menu may use

//adds the menu to Virtools Dev main menu
void InitMenu()
{
  if (!s_Plugininterface)
    return;
  s_MainMenu = s_Plugininterface->AddPluginMenu(
                     STR_MAINMENUNAME,                   //menu name
                     PLUGINMENU_MAXENTRIES,              //max command ids that may be used
                     NULL,                               //HWND that will receive WM_COMMAND
                     (VoidFunc1Param)PluginMenuCallback  //direct callback ptr
                     );
}

//removes the menu from Virtools Dev main menu
void RemoveMenu()
{
  if (!s_Plugininterface || !s_MainMenu)
    return
  ;s_Plugininterface->RemovePluginMenu(s_MainMenu);
}

//up to user.
//(May be called on new composition notification for instance)
//Note that first commandID can be 0
//but last command ID must be lesser thanPLUGINMENU_MAXENTRIES
void
UpdateMenu()
  {s_Plugininterface->ClearPluginMenu(s_MainMenu);             //clear menu
  s_Plugininterface->AddPluginMenuItem(s_MainMenu,0,"item0"); //add simple item sample
  s_Plugininterface->AddPluginMenuItem(s_MainMenu,1,"item1"); //add simple item sample
  s_Plugininterface->AddPluginMenuItem(s_MainMenu,-1,NULL,TRUE); //add separator sample
  CMenu* sub0 = s_Plugininterface->AddPluginMenuItem(s_MainMenu,-1,"SubMenu0",FALSE,TRUE); //sub menu sample
  CMenu* sub1 = s_Plugininterface->AddPluginMenuItem(s_MainMenu,-1,"SubMenu1",FALSE,TRUE); //sub menu sample
  s_Plugininterface->AddPluginMenuItem(sub0,2,"item2");    //add simple item to sub menu sample
  s_Plugininterface->AddPluginMenuItem(sub0,3,"item3");    //add simple item to sub menu sample
  s_Plugininterface->AddPluginMenuItem(sub1,4,"item4");    //add simple item to sub menu sample
  s_Plugininterface->AddPluginMenuItem(sub1,5,"item5");    //add simple item to sub menu sample

  s_Plugininterface->UpdatePluginMenu(s_MainMenu);
  //update menu,always needed when you finished to update the menu
  //unless you want the menu not to have Virtools Dev main menu color scheme.
}

//fill with your command IDs and your actions
void PluginMenuCallback(int commandID)
{
  switch(commandID)
  {
    //do your stuff here
  }
}
    The PluginInterface instance is used to add Menu Items.

  2. When the Virtools Dev user chooses to open the plugin editor from Virtools Dev interface, from the Editors pulldown menu (in this case, to be consistent, the menu should be removed when the editor is closed since this menu was created when the editor was opened ). This case supposes that you will have a graphic user interface for your plugin.
    You should then add the custom menu in the WM_INITDIALOG message or OnInterfaceInit() callback of your editor dialog, and remove it on the WM_DESTROY message or OnInterfaceEnd() callback.
    Note: the WM_INITDIALOG message happens before the DllDialogInterface::OnInterfaceInit() is called, so the DllDialogInterface::GetInterface() will return NULL : you should then use the PluginInterface pointer given in the plugin callback if you really want to build the menu on WM_INITDIALOG instead of the OnInterfaceInit() callback.
Building the Plugin Menu:

You must use PluginInterface class functions dedicated to building a plugin menu:

//PluginInterface.h
class PluginInterface
{
[...]
///////////////////////////////////////////////////////////////////////////////
//MENU MODIFICATION & USER MENU CALLBACK

CMenu*  AddPluginMenu(LPCTSTR name,int maxIDs,HWND callbackHWND,VoidFunc1Param callback=NULL);
void    RemovePluginMenu(CMenu* menu);
void    ClearPluginMenu(CMenu* menu);

CMenu*  AddPluginMenuItem(CMenu* menu,int commandID,LPCTSTR name,BOOL sep=FALSE,BOOL sub=FALSE);
void    RemovePluginMenuItem(CMenu* menu,int commandID,BOOL bypos=FALSE);

void    UpdatePluginMenu(CMenu* menu);
Here is the purpose of these functions:
  • AddPluginMenu: Adds an entry to Virtools Dev main menu. Plugin menus will be placed between the Options and Help menus.
    • LPCTSTR name: Name of the menu.
    • int maxIDS: Maximum number of commands you plan to use.
    • HWND callbackHWND: If you set a valid window handle here, the window will receive as a WM_COMMAND message when the user chooses a menu command from the plugin menu, the wParam of the WindowProc will be the commandID.
    • VoidFunc1Param callback: Callback that will be called by Virtools Dev when the user chooses a menu command from the plugin menu. This callback must looks like void menucallback(int commandID).
    • return value CMenu: The CMenu created.
  • RemovePluginMenu: Removes the plugin menu.
    • CMenu* menu: The plugin CMenu to remove from Virtools Dev main menu.
  • ClearPluginMenu: Clears the plugin menu.
    • CMenu* menu: The plugin CMenu to be cleared.
  • AddPluginMenuItem: Adds an item to a plugin menu or plugin submenu.
    • CMenu* menu: The CMenu returned by AddPluginMenu or any of its submenu.
    • int commandID: The command's ID that will be send in callbacks.
    • LPCTSTR name: The command's name .
    • BOOL sep: Set to TRUE if you want to add a separator. The commandID parameter is then ignored.
    • BOOL sub: Set to TRUE if you want to add a sub menu. The commandID parameter is then ignored.
    • return value CMenu*: The created sub menu if sub was set to TRUE.
  • RemovePluginMenuItem: Removes a plugin menu (or any of its submenu) item.
    • CMenu* menu: The CMenu returned by AddPluginMenu or any of its submenu.
    • int commandID: The commandID that refers to the menu item to remove (or the position of the item, if the next parameter bypos is set to TRUE)
    • BOOL bypos: If set to TRUE then the previous commandID will be used as a position and not as a commandID.
  • UpdatePluginMenu: You should call this function each time you modify a plugin menu in order to keep the Virtools Dev interface style for menus.
    • CMenu* menu: The CMenu returned by AddPluginMenu.

2) Custom Editor Plugin contextual popup menu

To have a custom contextual menu, you need to override the two virtual functions OnCustomMenu in the TestEditorDlg class

Building the Plugin Menu:

  • virtual void OnCustomMenu(CMenu* menu,int startingCommandID,int endingCommandID);
    This function is used to build the Menu. The CMenu documentation is in the MSDN documentation. startingCommandID and endingCommandID are the min and max available ids you can use.
  • virtual void OnCustomMenu(int commandID);
    This is the callback function, called when the Virtools Dev user selects a command from the custom editor menu.

TestEditorDlg.h

class ActionEditorDlg : public DllEditorDlg
{
public:
  virtual void 	OnCustomMenu(CMenu* menu,int startingCommandID,int endingCommandID);
  virtual void	OnCustomMenu(int commandID);
  //[...]
}

TestEditorDlg.cpp

//this callback is used to fill the contextual popup menu
void TestEditorDlg::OnCustomMenu(CMenu* menu,int startingCommandID,int
endingCommandID)
  {menu->AppendMenu(0,0 /*base ID*/  + startingCommandID,"Sample Command
  1");menu->AppendMenu(0,1 /*base ID*/ + startingCommandID,"Sample Command 2");
  }

//this callback is called by Virtools Dev when the Virtools Dev user
//selects a command from the custom contextual plugin menu
void TestEditorDlg::OnCustomMenu(int commandID)
{
  switch(commandID)
  {
    case 0:
      AfxMessageBox("sample command 1 called");
      break;
    case 1:
      AfxMessageBox("sample command 2 called");
      break;
  }
}

This code is automatically added if you checked the Menu checkbox in the Editor group in the Virtools Interface Plugin AppWizard.

The 1st callback is used to fill the contextual menu; startingCommandID must be used in addition to the base command id, and endingCommandID is the last available id you can use. The 2nd callback is called when the user selects a command from your custom contextual menu; the parameter commandID is the base id, that is, without the startingCommandID component.

Next: Plugin Customizable Keyboard Shortcuts


Plugin - Customizable Keyboard

  1. Overview
  2. Creating a Virtools Dev Interface Plugin with the AppWizard in Microsoft Visual Studio .Net 2003
  3. Filling the PluginInfo structure to define a Virtools Interface Plugin
  4. Graphic User Interface
  5. Plugin Callback
  6. Plugin Communication with Virtools Dev
  7. Plugin Menu
  8. Plugin Customizable Keyboard Shortcuts
  9. VIControls
  10. CKControls

Using customizable Keyboard Shortcuts

Continuing from our previous example of creating an AppWizard project named Test (of type Editor with all options checked), the following files are covered in this chapter:
  • Files related to the Virtools Interface Plugin SDK header: VEP_KeyboardShortcutManager.h.
  • Related files in Plugin sample: TestCallback.cpp , TestKeyboardShortcuts.cpp , TestKeyboardShortcuts.h.

OverView

There is a Keyboard Shortcut Manager in Virtools Dev that centralizes customizable keyboard shortcuts: those can be edited by the user*, and are loaded and saved at each Virtools Dev session. The manager provides an easy way to create popup menus from those keyboard shortcuts too.

Keyboard shortcuts are sorted by categories. A keyboard shortcut consist of a name, a key with possible modifiers (control, alt, shift), and a command identifier, which should be the button identifier that activate the same command.

NOTE: keyboard shortcuts that you register may be edited (if you allow it and if you provide a way to launch the Edit Keyboard Shortcuts dialog), since it is not yet directly available in Virtools. For now, only the Action Manager, present in Virtools Dev 3+, opens this dialog when the user double-click in the keyboard shortcut column of Action Manager's list.

  1. The Keyboard Shortcut Manager
  2. Register Keyboard Shortcut Category
  3. Register Keyboard Shortcuts
  4. Using Keyboard Shortcuts
  5. Edit Keyboard Shortcuts
  6. Use Keyboard Shortcut Manager to create a menu

The Keyboard Shortcut Manager

The Keyboard Shortcut Manager header file is VEP_KeyboardShortcutManager.h. It is the entry point to use keyboard shortcuts in the plugin code. You must use the PluginInterface instance to get the Keyboard Shortcut Manager.

PluginInterface* s_Plugininterface=NULL;//get it for instance in the plugin callback
[...]
KeyboardShortcutManager* ksm = s_Plugininterface->GetKeyboardShortcutManager();

The Keyboard Shortcut Manager functionalities are:

  • Register/unregister keyboard shortcut category, to sort keyboard shortcuts.
  • Register/unregister keyboard shortcuts in/from a category.
  • Activate or deactivate a keyboard shortcut category
  • Limit the possible keyboard shortcuts for a category.
  • Test if a key is a keyboard shortcut or not.
  • Create a string with a command name and its keyboard shortcut name to build a popup menu.

Register the Keyboard Shortcut Category

Keyboard Shortcut Categories are used to sort the keyboard shortcuts. You cannot register Keyboard Shortcuts without a category. To create and register a new category,

typedef const char* (*KSGetNameFunc)(int commandID);
typedef void (*KSCallbackFunc)(int commandID);

int KeyboardShortcutManager::RegisterCategory(
  const char* catname,
  void* owner=NULL,
  DWORD flags=0,
  HWND hwnd=NULL,
  KSCategory::KSCallbackFunc callback=NULL,
  KSCategory::KSGetNameFunc getnamefunc=NULL
);
  • Return Value: The current index of the created category. Note that this index may change so do not use it to reference the category; refer to a category by its name or owner.
  • catname: The category name.
  • owner: Value only used as a reference. Usually category are referenced by their name, so this parameter is set to NULL, but you may want to use this variable as reference instead.
  • flags:
    • LOCAL: Default - category is used for local keyboard shortcuts. Local means that the editor (or one of its children windows) must have the focus. There is no callback for keyboard shortcuts of this category, the programmer will have to call a test function of the manager in the overridden PreTranslateMessage of the editor dialog.
    • GLOBAL: Category is used for global keyboard shortcuts. Global means that keyboard shortcuts will be taken into account whatever the focused window is. When a global keyboard shortcut is activated, then the category callback is called by Virtools Dev interface.
    • FIXED: If set, the keyboard shortcuts belonging to that category cannot be edited in Virtools Dev interface.
    • ACTIVE: If set, then the category is active. If not active, then keyboard shortcuts press will not be detected. It is not set by default, you will have to add this flag in the function KeyboardShortcutManager::RegisterCategory(...), or to use KeyboardShortcutManager::ActivateCategory(...) later, after the category registration.
    • HIDDEN: the category will be visible in Edit Keyboard Shortcuts dialog.
  • hwnd: Only used with GLOBAL categories - when a global keyboard shortcut is activated, the hwnd receives a WM_COMMAND message with the command ID linked to the keyboard shortcut in the wParam parameter.
  • callback: Only used with GLOBAL categories - when a global keyboard shortcut is activated, this callback is called with the command ID linked to the keyboard shortcut as parameter.
  • getnamefunc: You can provide a callback which gives a name for each command identifier. This is useful as it allows to use less memory for keyboard shortcuts name, since name are duplicated in keyboard shortcut structure otherwise.

Allowed and forbidden keys in a category:

int SetAllowedKey   (const char* catname,KSKEY &key,BOOL add=TRUE);
int SetNotAllowedKey(const char* catname,KSKEY &key,BOOL add=TRUE);

These 2 functions are used to specify which keyboard shortcuts are allowed or not allowed in a category. For each category, there is an "allowed key list" and a "not allowed key list", which are empty and thus not used for filtering by default. SetAllowedKey adds a key in the allowed key list for the category, and SetNotAllowedKey adds a key in the not allowed key list. When a Virtools Dev user tries to edit a keyboard shortcut, the key must belong to the allowed key list (if not empty) and not belong to the not allowed key list (if not empty) to be validated.

  • return value: 1 if successful, 0 otherwise.
  • catname: Category name.
  • key: Key to add, a KSKEY structure.
    • key: Virtual key code such as the wParam on WM_KEYDOWN.
    • flag: 0 or combination of the following values
      • KS_CONTROL: Uses the control key.
      • KS_ALT: Uses the alt key.
      • KS_SHIFT: Uses the shift key.
  • add: If set to TRUE, then adds the key to the list; otherwise, removes the specified key from the list.
//Callback use by category to get the keyboard shortcut's command name
//specified as parameter in the category registration function
const char* GetCommandName(int commandID)
{
  switch(commandID)
  {
  case 1:
    return "Command 1";
  case 2:
    return "Command 2";
  }
}

//function used to get the command menu name from its commandID
const char* GetMenuName(int commandID,XString &name)
{
  name="";
  const char* cstr	= GetCommandName(commandID);
  if (!cstr)
    return NULL;
  name=cstr;
  //the PluginInterface instance has been caught in the plugin callback on CPR_LOAD.
  KeyboardShortcutManager* ksm = g_Plugininterface->GetKeyboardShortcutManager();
  if
    (ksm)ksm->GetKSName(KS_ACTIONEDITORCATEGORY,commandID,name,FALSE,TRUE);
  return name.CStr();
}

//sample code to create a menu using the Keyboard Shortcut Manager
//in a member function of class TestEditorDlg, file TestEditorDlg.cpp
  CKVIPopupMenu menu;
  menu.Attach(this)
  m_ActionMenu.AddItem(GetMenuName(commandID),commandID);//add the command to menu
  POINT p;
  GetCursorPos(&p);
  m_ActionMenu.Show(p.x,p.y);

Register Keyboard Shortcuts

Keyboard shortcuts can be added to a category.

enum CHECK_KEYBOARD_SHORTCUT{
  CHECK_NOTHING   = 0x00000000,
  CHECK_NAME      = 0x00000001,
  CHECK_KEY       = 0x00000002,
  CHECK_COMMANDID = 0x00000004,
  CHECK_ALLOWED   = 0x00000008,
  CHECK_ALL       = 0x0000000f,
};

class KSKEY
{
public:
  enum {
    NONE        = 0x00000000,
    FIXED       = 0x00000001,
    EDITED      = 0x00000002,
    KS_CONTROL  = 0x00000004,
    KS_ALT      = 0x00000008,
    KS_SHIFT    = 0x00000010,
    KS_MODIFIER = 0x0000001c,
  }KSTYPE;
  DWORD key;
  DWORD flags;

//[...]
};

class KS : public KSKEY
{
public:
  XString name;      //functionality name
  int     commandID; //functionnaly command identifier

//[...]
};

int RegisterKS(
  const char* catname,
  KS& ks,
  CHECK_KEYBOARD_SHORTCUT check=CHECK_ALL
);
  • return value: 1 if successful, 0 if failed.
  • catname: Category name in which you want to add the keyboard shortcut.
  • ks: A KS structure that describes the keyboard shortcut you want to add.
    • key: The virtual key code (such as the one received with WM_KEYDOWN in the wParam)
    • flag: Can be a combination of the following values:
      • FIXED: The keyboard shortcut cannot be modified by edition.
      • EDITED: Reserved for internal use; the keyboard shortcut is being edited.
      • KS_CONTROL: The keyboard shortcut uses the control key.
      • KS_ALT: The keyboard shortcut uses the alt key.
      • KS_SHIFT: The keyboard shortcut uses the shift key.
      • KS_MODIFIER: Combination of control + alt + shift.
    • commandID: Command identifier, should be the wParam received with the message WM_COMMAND or the button id that activates the command linked to the keyboard shortcut.
    • name: Name of the command linked to the keyboard shortcut. Note that you should use the getnamefunc parameter while registering the keyboard shortcut category instead of filling this member.
  • check: Check none, some or all of the KS structure members. If there is a conflict, the keyboard shortcut will not be added. It can be a combination of the following values:
  • CHECK_NOTHING: No check is done when adding the keyboard shortcut to the category.
  • CHECK_NAME: Check name with keyboard shortcuts already present in category.
  • CHECK_KEY: Check key with keyboard shortcuts already present in category.
  • CHECK_COMMANDID: Check command ID with keyboard shortcuts already present in category.
  • CHECK_ALLOWED: Check if key is allowed for the category before adding keyboard shortcut.
  • CHECK_ALL: Default value, combination of all previous values.

Using Keyboard Shortcut Manager

  • For categories flagged with GLOBAL

When a keyboard shortcut entry is detected, the category's callback is automatically called if available, and a WM_COMMAND is send to the category's hwnd if available. The keyboard shortcut command identifier will be send as parameter.

Sample file : TestKeyboardShortcut.cpp:

void GlobalKSCallback(int commandID)
{
  if
    (g_Editor)g_Editor->OnGlobalKeyboardShortcut(commandID);
}

int RegisterKeyboardShortcutCategory()
{
  KeyboardShortcutManager* ksm = s_Plugininterface->GetKeyboardShortcutManager();
  if (ksm)
  {
    //category ACTIVE+GLOBAL with callback for global keyboard shortcuts
    int index = ksm->RegisterCategory(STR_CATEGORY,NULL,ACTIVE+GLOBAL,NULL,globalKSCallback,GetCommandName);
    if (index>=0)
      return 1;
  }
  return 0;
}
Sample file : TestEditorDlg.cpp:
int TestEditorDlg::OnGlobalKeyboardShortcut(int commandID)
{
  //user code here
  return 0;  //return 1 if successful/keyboard shortcut has been processed
}
  • For categories flagged with LOCAL

You will have to catch WM_KEYDOWN and WM_SYSKEYDOWN in the editor dialog PreTranslateMessage function, and call the KeyboardShortcutManager::TestKS() function with the virtual key contained in wParam as parameter.

Sample file : TestEditorDlg.cpp:

BOOL TestEditorDlg::PreTranslateMessage(MSG* pMsg)
{
  switch(pMsg->message)
  {
    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
    {
      KeyboardShortcutManager* ksm = GetInterface()->GetKeyboardShortcutManager();

      //call Test function of KeyboardShortcutManager
      int commandID=ksm->TestKS(STR_CATEGORY,pMsg->wParam);

      if (commandID)
        if (OnLocalKeyboardShortcut(commandID))  //user callback
          return 1;
    }break;
  }
  return DllEditorDlg::PreTranslateMessage(pMsg);
}

int TestEditorDlg::OnLocalKeyboardShortcut(int commandID)
{
  //user code here
  return 0;  //return 1 if successful/keyboard shortcut has been processed
}

Edit Keyboard Shortcuts

The Edit Keyboard Shortcuts dialog is not directly available from Virtools Dev interface (yet). Virtools Interface Plugins that use keyboard shortcuts must provide a way to show this dialog, like the Action Manager available in Virtools Dev 3.0.

To open this dialog, use:

void PluginInterface::EditKeyboardShortcuts(
  const char* registeredCategoryName=NULL,
  const char* registeredShortcutName=NULL);
  • registeredCategoryName: If not null, then the Edit Keyboard Shortcuts dialog will open the category's shortcut list by default.
  • registeredShortcutName: If not null, then the Edit Keyboard Shortcuts dialog will set the focus to the specified keyboard shortcut (if the keyboard shortcut belongs to registeredCategoryName).

See how to get the PluginInterface instance here.

Next: VIControls


Virtools Interface SDK - VIControls

  1. Overview
  2. Creating a Virtools Dev Interface Plugin with the AppWizard in Microsoft Visual Studio .Net 2003
  3. Filling the PluginInfo structure to define a Virtools Interface Plugin
  4. Graphic User Interface
  5. Plugin Callback
  6. Plugin Communication with Virtools Dev
  7. Plugin Menu
  8. Plugin Customizable Keyboard Shortcuts
  9. VIControls
  10. CKControls

VIControls Overview

The VIControls SDK is a set of Windows dialog and controls. Some controls are overridden basic Windows controls, while others are new controls. (These are listed later in this chapters). VIControls are used to create the general "Virtools Dev" look and feel. To use these overridden basic Windows controls, you simply have to change the class name in the instance declaration of the control.

Example of a line to change in the header of the editor and the toolbar:
Instead of the line:

CButton m_button;

Type:

VIButton m_button;

Base Headers:

  • VIControl.h: Contains the base class VIControl for all controls in the VIControls SDK.
  • VIControlGlobals.h: Contains global functions used for the VIControls. The most important functions for the "Virtools Dev" look and feel are: GetVIFont, GetVIBrush and GetVIColor, to get predefined brushes, fonts and colors (whose indexes are found in VIGdiManager.h).
  • VIGdiManager.h: Contains the declaration of the VIGdiManager class, which is the graphic manager for the CKControls SDK. Although the VIGdiManager is not directly accessible, you can access it with global functions found in VIControlGlobals.h, such as GetVIBrush and GetVIColor. The main purpose of this file is to provide the indexes of predefined fonts, brushes and colors.).

List of Controls & Dialogs

Creating VIControls in the CPP file:

A sample manual code to create a control usually looks like this:

VI_ctrl_name_* ctrl=new VI_ctrl_name_;
[...] //optional pre initialization steps
ctrl->Create("ctrl name",WS_CHILD|WS_VISIBLE,RECT,this,int_identifier);
[...] //optional post initialization steps

However, for overridden Windows controls, you can also:

  • Associate a Control variable with the control (ie, a CButton with the button resource) via the Class Wizard in Microsoft Visual C++.
  • Find the fitting control class in the VIControls SDK (i.e. VIButton or VIToolbarButton for CButton) and replace the MFC class with the VIControl class in the header of the dialog.

Control & Dialog List

Note: The declaration of the control (whose name is classname) is in classname.h.

  • VIAngleCtrl: New control, to set an angle.

  • VIBitmapButton: Derives from VIButton (overridden basic Windows control), used for bitmap buttons. Used for 5 states button (normal, rollover, pushed, pushed rollover, disabled).
    To set the bitmaps, use either the VIBitmapButton::SetBitmaps(..) function with bitmap resources identifiers:
    VIBitmapButton* ctrl=new VIBitmapButton;
{ //use AFX_MANAGE_STATE only for resources loading
  AFX_MANAGE_STATE(AfxGetStaticModuleState());
  //** the SetBitmaps() function with resources identifiers
  ctrl->SetBitmaps(IDB_NORMAL,IDB_ROLLOVER,IDB_PUSHED,IDB_PUSHEDROLLOVER,IDB_DISABLED);
}
ctrl->Create("ctrl name",WS_CHILD|WS_VISIBLE,rect,this,id);
    Or directly with CBitmap*:
    [...]
//** or the SetBitmaps() function with CBitmap*
ctrl->SetBitmaps(
  /*(CBitmap*)*/ Normal,
  /*(CBitmap*)*/ NormalHighlighted,
  /*(CBitmap*)*/ Pushed,
  /*(CBitmap*)*/ PushedHighlighted,
  /*(CBitmap*)*/ Disabled,
  /*(BOOL)*/      ReleaseBitmaps /*=TRUE*/);
[...]
    If you want the button to remain in the pushed state, you should manually call VIBitmapButton->SetPushed(TRUE) on the WM_COMMAND sent by the button when clicked upon.
  • VIButton: Derives from CButton (classic Windows control), used for text button:
    normal
    rollover
    pushed rollover
    pushed
    disabled
  • VICheckButton: Derives from CButton, used as a check box (unchecked [image], checked [image]).
    Note: Use the BS_AUTOCHECKBOX style:
    ctrl->Create("ctrl name",BS_AUTOCHECKBOX|WS_CHILD,rect,this,identifier);
  • VIColorDialog: A dialog to specify a color.
    VIColorDialog* ctrl=new VIColorDialog(parentCWnd);
ctrl->Create(parentCWnd);
ctrl->ShowWindow(SW_SHOW);

  • VIColorDialog2: Derives from VIColorDialog, with more functionalities. (Must add #include "VIColorDialog2.h" in code)
  • VIComboBox: Derives from CComboBox. Do not forget to add the combo box style CBS_DROPDOWN or CBS_DROPDOWNLIST:
    VIComboBox* ctrl=new VIComboBox;
//do not forget that the given rect is used for the combobox width and the combo list's height
//WS_BORDER to have a line under the edit of the combobox, and CBS_DROPDOWNLIST,CBS_DROPDOWN or CBS_SIMPLE
ctrl->Create(WS_BORDER|CBS_DROPDOWNLIST|WS_CHILD,rect,this,identifier);
ctrl->AddString("Str1");
ctrl->AddString("Str2");

  • VIComboEx: Derives from CComboBoxEx (overridden basic Windows controls).
  • VIDialog: Derives from CDialog. Used to gives dialog a Virtools Dev look and feel. Here are the basic steps to follow to use VIDialog class.
    • Add a new dialog resource (for example with the identifier IDD_DIALOG1) in your resource, and remove the Ok and Cancel button, since they are managed automatically by the VIDialog class.
    • Remove the System Menu since it's not in the Virtools Dev look and feel (otherwise you may experience a visual bug where the close button is there but not shown unless you click on it).

    • Create a dialog class with the Microsoft Visual C++ 6.0 Class Wizard from the dialog resource. For example, we create the MyDialog class, which derives from CDialog and uses the IDD_DIALOG1, and the code is in the MyDialog.h and MyDialog.cpp files.
    • In the newly created .h and .cpp files, replace all instances of the text "CDialog" with "VIDialog".
    • Override the WM_INITDIALOG callback of your dialog so it looks like this:
      BOOL MyDialog::OnInitDialog()
{
  VIDialog::OnInitDialog();
//use VIDialog::SetCustomButtons to set the Ok, Apply and Cancel buttons name.
//if the name of a button is NULL, then the VIDialog will consider
//that the corresponding button will not be shown
//
//use VIDialog::ShowCustomButtons to show or hide all or part of the Ok, Apply and Cancel buttons.
//
//use VIDialog::SetCustomButtonPositions to set the Ok, Apply and Cancel buttons positions:
//they will always be at the bottom of the dialog, but you can change the horizontal positions,
//which are by default right aligned, with Ok before Apply before Cancel.

//do your initialization stuff here
[...]
//end initialization stuff
  RECT r;
  GetClientRect(&r);
//the call to AdjustWindows is needed in order for all child windows to be correctly placed
  AdjustWindows(&r,TRUE);
  return TRUE;
}
    • To open the dialog as a modal dialog, the code should looks like this:
      {
//because the dialog resource is in your dll, you must change the current module state
  AFX_MANAGE_STATE(AfxGetStaticModuleState());
//to create a modal dialog
  MyDialog dlg_modal;
  dlg_modal.DoModal();
}
    • To open the dialog as a modeless dialog, the code should looks like this:
      MyDialog* dlg_modeless=new MyDialog;
{
  AFX_MANAGE_STATE(AfxGetStaticModuleState());
//to avoid a crash,
//the parent window must be set to NULL when the module state
//has been changed to retrieve the plugin resource
  dlg_modeless->Create(IDD_DIALOG1,NULL);
}
//the parent can be set here if necessary
 if
  (parentCWnd)dlg_modeless->SetParent(parentCWnd);
//show the window
dlg_modeless->ShowWindow(SW_SHOW);

  • VIDialogButton: Derives from VIButton. Same as a VIButton (that is, a flat text button with a rounded rectangle border), but with different colors fitted for the external background color of a VIDialog, such as the Ok and Cancel buttons of the VIDialog.
  • VIEdit: derives from CEdit.

  • VIGasPedal: A progression bar that can be modified by the mouse. Just click in the control to set the progression bar to the mouse position. Derives from the VIProgressBar class, which does not support user input.

  • VIImageList: An image list such as the CImageList but with a different interface.
  • VIListBox: Derives from CListBox. It is the same control but with Virtools Dev predefined background color.
  • VIListCtrl: Derives from CListCtrl. It is the same control as the Windows control, but with Virtools Dev background color.
  • VIMessageDlg: Dialog with a title, an icon and a simple static message in. A quick way to use this class is to use the global VIMessageBox function specified at the end of the class' header; it works a bit like the Windows AfxMessageBox function.
  • VIPopupMenu: This class is a CMenu wrapper. It does not derives from CKControl and colors are not customizable with this wrapper. This class exists to make it easier to create popup menus and sub menus. Sub menus are identified with an ID, as well as commands.
  • VIProgressBar: Derives from CWnd, it is a progression bar that cannot be changed directly by user input (use VIGasPedal instead).
  • VIRichEdit: Derives from CRichEdit. Added functionalities are Undo and the possibilty to set a dictionary for autocompletion. It is used in the VSL Editor.
  • VISlider: Derives from CSliderCtrl. It is a slider that takes mouse input into account.

  • VISplitBar: Splitbar such as the one found in VISplitterWnd. They can be dragged with the left mouse button, and send a windows notification to their parent, through the WM_NOTIFY message, with the notification code VI_NM_END_DRAG_SPLITTER when the left mouse button is released.
  • VISplitterWnd: a Splitter Window like the CSplitterWnd but a lot easier to use. Just create the VISplitterWnd, specify the number of horizontal and vertical splitbars, create your sub controls with the VISplitterWnd as parent. Then set the sub control's pane within the splitter windows with the VISplitterWnd::SetWindowToPane function.

    Note: This is the Shader Editor, which use several VISplitterWnds.
  • VIStaticImage: A control to show an image specified by a VxImageDesc from the VxMath SDK.
  • VIStaticRectangle: Derives from CStatic, used to draw a rectangle.
  • VIStaticText: Derives from CStatic, used to draw a text.
  • VITabCtrl: An horizontal customizable Tab Control.

    Note: This bitmap comes from the Action Manager.
  • VIToolbarButton: Derives from VIButton. Same as a VIButton (i.e. a flat text button with a rounded rectangle as border), but with different colors fitted for the editor's toolbars.
  • VITreeCtrl: Derives from CTreeCtrl. It is the same control as the Windows control, but with Virtools Dev's predefined background color.

Next: CKControls


Virtools Interface SDK -CKControls

  1. Overview
  2. Creating a Virtools Dev Interface Plugin with the AppWizard in Microsoft Visual Studio .Net 2003
  3. Filling the PluginInfo structure to define a Virtools Interface Plugin
  4. Graphic User Interface
  5. Plugin Callback
  6. Plugin Communication with Virtools Dev
  7. Plugin Menu
  8. Plugin Customizable Keyboard Shortcuts
  9. VIControls
  10. CKControls

CKControls Overview

The CKControls SDK is a set of Windows controls and tools which usually have a relation with the CK2Win32 SDK. They provide the Virtools Dev visual style.

List of Controls and Tools

Note: The declaration of the control (whose name is classname) is in classname.h.

Note: All classes defined in the CKControls SDK are enclosed within the namespace CKControl. A project created with the Virtools Interface SDK (dll) App Wizard has already the line using namespace CKControl; in the precompiled header.

  • CKVIPopupMenu: Derives from VIPopupMenu from the VIControls SDK. The only addition is when the popup menu is shown, the current composition is paused if Virtools Dev was in Play Mode.
  • CMultiListCtrl: Like CListCtrl but with a different code and graphic interface. (e.g. it is used in the ActionManager available in Virtools Dev 3.0.) Full lines or each separate column can be in custom draw mode, i.e. the programmer can code how the cell or line will be drawn.

  • CMultiTreeCtrl: Same as the CMultiListCtrl, but the control is used more like a CTreeCtrl. For instance, it is used in the Level View.

  • MultiParamEditDlg: This is a dialog used to edit several CKParameters, such as when editing a behavior from the Schematic View.

  • ParamEditDlg: This is a dialog used to edit one CKParameter, such as when editing a parameter from the Schematic View. The possible edit fields are the name, the type and the value.

  • ScrollWnd: This class is a invisible window that automatically manages its child window with scrollbars according to the child's size. A ScrollWnd should have only one child window. You have to specify which scrollbars are to be managed with the ScrollWnd::ModifyFlags function and the optional flags SCROLLBAR_HORZ and SCROLLBAR_VERT.


Send Comments to Virtools - Help Improve Virtools Documentation!

Use this form to send comments to Virtools about the Online Reference. Note that you must be connected to the Internet to use this form. If you are not connected to the Internet, you can alternatively send comments by e-mail.

Topic:
Name:
 Email Address (optional):
Comments:

Note: This form is not intended as a way for you to receive feedback or technical support. The information you provide will be used to enhance future updates to the documentation. Thanks!