11 KiB
ToonBoomActionManager.dll Class Analysis
This document describes the reverse-engineered class structures from ToonBoomActionManager.dll.
IDA Database: RE/ToonBoomActionManager.dll.i64
Overview
ToonBoomActionManager.dll provides the action/command management infrastructure for Toon Boom applications (Harmony Premium, Storyboard Pro). It implements:
- Responder Chain: First responder and selection responder management
- Menu System: XML-based menu creation and management
- Toolbar System: Customizable toolbars with dynamic item insertion
- Shortcut Management: Keyboard shortcut handling
- Action Triggering: Command execution and validation
Class Hierarchy
AC_Manager (abstract interface)
└── AC_ManagerImpl (concrete, inherits QObject)
AC_Object (abstract interface)
├── AC_Item (abstract interface)
├── AC_Separator (abstract interface)
└── AC_Toolbar (abstract, also inherits AC_Container, AC_Help)
└── AC_ToolbarImpl (concrete, inherits QToolBar)
AC_Container (abstract interface)
└── AC_ContainerImpl (concrete)
AC_Help (abstract interface)
AC_Responder (abstract interface)
└── AC_ResponderTemplate (concrete)
└── AC_ResponderTemplateWidget<T> (template)
AC_Manager / AC_ManagerImpl
Purpose
Central manager for the action/command system. Handles responder registration, menu/toolbar creation, and action triggering.
Key Addresses
| Symbol | Address |
|---|---|
| AC_Manager vtable | 0x18004e508 |
| AC_ManagerImpl vtable (QObject) | 0x18004e750 |
| AC_ManagerImpl vtable (AC_Manager) | 0x18004e7c8 |
| AC_ManagerImpl::AC_ManagerImpl | 0x18000ef20 |
| AC_ManagerImpl::~AC_ManagerImpl | 0x18000f300 |
Memory Layout (AC_ManagerImpl)
Total size: 0x158 (344 bytes) on x64
| Offset | Size | Type | Field |
|---|---|---|---|
| +0x00 | 0x10 | QObject base | |
| +0x10 | 0x08 | vptr | AC_Manager vtable |
| +0x18 | 0x08 | void* | m_keywords (shared ptr data) |
| +0x20 | 0x08 | void* | m_keywords (continued) |
| +0x28 | 0x08 | void* | m_keywords (continued) |
| +0x30 | 0x01 | bool | m_trimShortcuts (init value) |
| +0x38 | 0x18 | Responder name→list tree | |
| +0x50 | 0x18 | Menu tree | |
| +0x68 | 0x08 | ptr | m_shortcutManager |
| +0x78 | 0x18 | QString | m_hoverId |
| +0x90 | 0x18 | QString | m_genericImage |
| +0xA8 | 0x18 | QString | m_toolbarCustomizeImage |
| +0xC0 | 0x18 | Toolbar tree | |
| +0xD8 | 0x18 | vector | m_registeredResponders |
| +0xF0 | 0x18 | vector | m_responderStack |
| +0x108 | 0x08 | ptr | m_menuBar |
| +0x118 | 0x08 | ptr | m_applicationResponder |
| +0x120 | 0x08 | ptr | m_selectionResponder |
| +0x128 | 0x08 | ptr | m_itemGenerator |
| +0x130 | 0x01 | bool | m_option_trimShortcuts |
Key Methods
Responder Management
firstResponder()- Returns top of responder stack (offset +248)applicationResponder()- Returns m_applicationResponder (offset +296)registerResponder(responder, widget)- Adds responder to registry; ifwidget != nullptr, inserts into a global widget map and callsQObject::connect(widget, destroyed(QObject*), ...)(seedocs/AC_Manager_registerResponder_QBitArrayCrash.md:1)setFirstResponder(responder)- Sets active first responderpushUp(responder)- Stack manipulation (note:pushOutexists on theAC_ManagerImplQObject vtable in this build, but is not part of theAC_Manager*vtable at0x18004e7c8)
Menu/Toolbar Creation
createMenuBar(element, parent)- Create menu from XMLcreateToolbar(element, ids, mainWindow, area, name, owner)- Create toolbarloadMenus(path)/loadToolbars(path, ids)- Load from file
AC_Manager Toolbar Vtable Slots (Verified in IDA)
loadToolbars(const QDomElement&, QList<QString>&)- slot 46 (+0x170) at0x180015940loadToolbars(const QString&, QList<QString>&)- slot 47 (+0x178) at0x180015f20(parses file then forwards to slot 46)toolbarElement(const QString&)- slot 52 (+0x1a0) at0x180016240(returnsQDomElementby value via MSVC x64 hidden sret out buffer)updateToolbars()- slot 53 (+0x1a8) at0x180016350(schedulesfireUpdateToolbars()viaQTimer::singleShot(300, ...))
Note: loadToolbars(...) does not call updateToolbars() directly (verified by decompilation of 0x180015940 / 0x180015f20).
Framework ABI note: AC_Manager is a vtable interface; loadToolbars(const QDomElement&, ...) must be declared before loadToolbars(const QString&, ...) to match slots 46/47. If your call appears to hit updateToolbars() or the wrong loadToolbars overload, suspect an ABI mismatch (wrong virtual order and/or wrong base pointer/vptr).
Action Triggering
trigger(responderIdentity, actionName, forEach)- Execute actionperformValidation(responderIdentity, actionName, enabled, checked)- Validate action state
Signals
void firstResponderChanged();
void selectionResponderChanged();
void updateToolbarsSignal();
void updateToolbarsText();
AC_Toolbar / AC_ToolbarImpl
Purpose
Customizable toolbar with support for:
- Dynamic item insertion from XML
- Placeholder-based customization
- Configuration save/restore
- Context-sensitive help
Key Addresses
| Symbol | Address |
|---|---|
| AC_ToolbarImpl vtable (QObject) | 0x180054c90 |
| AC_ToolbarImpl vtable (QPaintDevice) | 0x180054e70 |
| AC_ToolbarImpl vtable (AC_Toolbar) | 0x180054eb0 |
| AC_ToolbarImpl vtable (AC_Container) | 0x180054ef8 |
| AC_ToolbarImpl vtable (AC_Help) | 0x1800550f8 |
| AC_ToolbarImpl::AC_ToolbarImpl | 0x180032df0 |
| AC_ToolbarImpl::~AC_ToolbarImpl | 0x180033080 |
Memory Layout (AC_ToolbarImpl)
Total size: 0x118 (280 bytes) on x64
| Offset | Size | Type | Field |
|---|---|---|---|
| +0x00 | 0x28 | QToolBar base (includes QObject, QPaintDevice) | |
| +0x28 | 0x58 | AC_ContainerImpl | m_container (embedded) |
| +0x80 | 0x08 | vptr | AC_Toolbar vtable |
| +0x88 | 0x08 | vptr | AC_Container vtable |
| +0x90 | 0x08 | vptr | AC_Help vtable |
| +0x98 | 0x18 | QString | m_responderIdentity |
| +0xB0 | 0x18 | vector | m_defaultConfig |
| +0xC8 | 0x01 | bool | m_isCustomizable |
| +0xD0 | 0x08 | ptr | m_customizeButton |
| +0xD8 | 0x08 | ptr | m_unknown |
| +0xE0 | 0x08 | QObject* | m_owner |
| +0xE8 | 0x10 | QWeakPointer | m_mainWindow |
| +0xF8 | 0x04 | float | m_scaleFactor (default 1.0) |
| +0x100 | 0x18 | QString | m_translationContext |
Interface Pointers
When you have an AC_Toolbar*:
QToolBar*=(char*)this - 128AC_ContainerImpl*=(char*)this - 88- Identity QString is at
(char*)this - 72
Key Methods
Item Management
insert(beforeObject, element)- Insert item from XMLinsertAtPlaceholder(placeholder, element)- Insert at named placeholderinsertSeparator(beforeObject)- Insert separatorremoveObject(identity)- Remove item by identityclear()- Remove all items
Configuration
config()- Get current item order as QListsetConfig(list)- Restore from saved configurationdefaultConfig()- Get default item orderisDefaultConfig()- Check if current matches default
Validation
validateContent()- Update enabled/checked statesvalidateContentIfVisible()- Only validate if toolbar is shownupdateSeparators()- Hide separators adjacent to hidden items
Signals
void customized(QString identity);
AC_ContainerImpl
Purpose
Base container implementation for managing AC_Object children.
Memory Layout
Total size: 0x58 (88 bytes) on x64
| Offset | Size | Type | Field |
|---|---|---|---|
| +0x00 | 0x08 | vptr | AC_ContainerImpl vtable |
| +0x08 | 0x08 | ptr | m_manager (AC_ManagerImpl*) |
| +0x10 | 0x18 | QString | m_identity |
| +0x28 | 0x01 | bool | m_enabled |
| +0x29 | 0x01 | bool | m_isToolbar |
| +0x30 | 0x18 | vector | m_objects |
| +0x48 | 0x10 | Placeholder tree |
Enumerations
AC_Result
enum class AC_Result : int {
Handled = 0, // Action handled successfully
NotHandled = 1, // Action not handled by any responder
Error = 2 // Error during handling
};
AC_ManagerOption
enum class AC_ManagerOption : int {
TrimShortcuts = 0 // Whether to trim whitespace from shortcuts
};
AC_Help::cshHelpType
enum cshHelpType {
Type0 = 0,
Type1 = 1,
Type2 = 2,
Type3 = 3,
Type4 = 4,
ToolbarHelp = 5
};
XML Element Types
AC_ToolbarImpl::insert() handles these XML element types:
| Tag Name | Handler | Creates |
|---|---|---|
item |
sub_1800363E0 | AC_ToolbarItemImpl |
menu |
sub_1800363E0 | AC_ToolbarItemImpl (menu button) |
multibutton |
sub_180037F30 | AC_ToolbarMultiButtonImpl |
combobox |
sub_1800395D0 | AC_ToolbarComboBox |
placeholder |
sub_18001B9F0 | Placeholder object |
separator |
sub_18003ABD0 | AC_ToolbarSeparatorImpl |
Usage Patterns
Getting AC_Manager Instance
// Via PLUG_Services (from ToonBoomPlugInManager.dll)
AC_Manager* manager = PLUG_Services::getActionManager();
Creating a Toolbar
QList<QString> ids;
AC_Toolbar* toolbar = manager->createToolbar(
xmlElement, // QDomElement with toolbar definition
&ids, // Output: list of created item IDs
mainWindow, // QMainWindow to attach to
Qt::TopToolBarArea,// Toolbar area
"myToolbar", // Object name
owner // Owner QObject for cleanup
);
Triggering an Action
AC_Result result = manager->trigger(
"NetworkView", // Responder identity
"onActionZoomIn", // Action/slot name
false // Don't iterate all responders
);
Validating an Action
bool enabled, checked;
manager->performValidation("NetworkView", "onActionZoomIn", &enabled, &checked);
Related Files
framework/include/toon_boom/ac_manager.hpp- AC_Manager headerframework/include/toon_boom/toolbar.hpp- AC_Toolbar headerframework/include/toon_boom/PLUG_Services.hpp- Service access
Methodology
This analysis was performed using:
- IDA Pro decompilation of ToonBoomActionManager.dll
- Vtable analysis to identify class hierarchies
- Constructor/destructor analysis for memory layout
- Cross-reference analysis for method identification
- String analysis for signal/slot names
All offsets verified against x64 Windows builds of Toon Boom Harmony Premium.