cancel
Showing results for 
Search instead for 
Did you mean: 
EN
cancel
Showing results for 
Search instead for 
Did you mean: 
The Smoked Salmon
Participant

ArchiCAD 27 Add-On: Menu not appearing in menubar

Platform: Windows 11, ArchiCAD 27 (build 6020)
DevKit: API.Development.Kit.WIN.27.6003
Toolchain: Visual Studio 2019 (v142), CMake, Ninja


Background

I want to be upfront: this add-on is vibe coded — meaning it was written with AI assistance without deep prior knowledge of the ArchiCAD C++ API. I'm an architect, not a developer. The goal is a simple launcher add-on that opens a Python GUI application from ArchiCAD's menubar.


What works

  • The add-on builds cleanly with no linker errors
  • It appears in Options → Add-On Manager (checked, loaded)
  • All four entry functions are confirmed called via a log file:
CheckEnvironment called!
RegisterInterface called!
RegisterMenu OK       ← ACAPI_MenuItem_RegisterMenu returns 0
Initialize called!
InstallMenuHandler OK ← ACAPI_MenuItem_InstallMenuHandler returns 0
  • The .apx exports all 6 required symbols:
    GetExportedFuncAddrs, SetImportedFuncAddrs, CheckEnvironment,
    RegisterInterface, Initialize, FreeData

The problem

No menu entry appears anywhere in the menubar or any submenu.

I've been trying to get a custom top-level menu ("Layout Manager") to appear in the menubar using MenuCode_UserDef.

During debugging I discovered my hand-rolled enum had the wrong value — I wasn't including ACAPinc.h (see note below), so I had defined it manually:

// What I had (WRONG — this is actually MenuCode_Image):
MenuCode_UserDef = 8

// Correct value from APIdefs_Registration.h:
MenuCode_UserDef = 0

I have now corrected this and rebuilt. The menu still does not appear.

I also noticed this note in the Add-On Manager dialog:

"The visibility and menu location of Add-Ons in the Archicad interface depend on Work Environment settings. These can be customized in Work Environment → Command Layout Schemes."

When searching for "Layout Manager" in Work Environment → Menus, the command does not appear in the available commands list.


What I'm looking for

I'm not sure what I'm missing. It could be the enum value, the resource structure, the Work Environment, the APIAddon_Preload return value, the struct layouts, the way I'm forward-declaring the API functions — or something else entirely that I haven't thought of.

Rather than assuming I know what the problem is, I'd really appreciate a fresh set of eyes. What would you check first? Is there something fundamentally wrong with this approach that would explain why RegisterMenu returns NoError but nothing shows up?


Relevant code

LayoutManagerAddon.cpp (simplified)

#include <windows.h>
#include <shellapi.h>
#include <stdio.h>

typedef int          GSErrCode;
typedef unsigned int GSFlags;
#define NoError 0

typedef enum {
    APIAddon_DontRegister = 0,
    APIAddon_Normal       = 1,
    APIAddon_Preload      = 2
} API_AddonType;

typedef enum {
    MenuCode_UserDef = 0    // from APIdefs_Registration.h
} APIMenuCodeID;

#define MenuFlag_Default 0

struct API_MenuItemRef           { short menuResID; short itemIndex; };
struct API_ServerApplicationInfo { short mainVersion; short releaseVersion; char pad[508]; };
struct API_EnvirParams           { API_ServerApplicationInfo serverInfo; char pad[1024]; };
struct API_MenuParams            { API_MenuItemRef menuItemRef; };

GSErrCode __cdecl ACAPI_MenuItem_RegisterMenu(
    short menuStrResID, short promptStrResID,
    APIMenuCodeID menuPosCode, GSFlags menuFlags);

GSErrCode __cdecl ACAPI_MenuItem_InstallMenuHandler(
    short menuStrResID, GSErrCode (__cdecl* handlerProc)(const API_MenuParams*));

static void WriteLog(const wchar_t* msg) { /* logs to file */ }
static void LaunchLayoutManager() { /* ShellExecuteW to .exe */ }

static GSErrCode __cdecl MenuCommandHandler(const API_MenuParams*)
{
    LaunchLayoutManager();
    return NoError;
}

extern "C" {

__declspec(dllexport) API_AddonType __cdecl CheckEnvironment(API_EnvirParams*)
{
    return APIAddon_Preload;
}

__declspec(dllexport) GSErrCode __cdecl RegisterInterface(void)
{
    return ACAPI_MenuItem_RegisterMenu(32001, 0, MenuCode_UserDef, MenuFlag_Default);
}

__declspec(dllexport) GSErrCode __cdecl Initialize(void)
{
    return ACAPI_MenuItem_InstallMenuHandler(32001, MenuCommandHandler);
}

__declspec(dllexport) GSErrCode __cdecl FreeData(void) { return NoError; }

} // extern "C"

res/RINT/LayoutManagerAddon.grc

'STR#' 32001 "Menu strings" {
    "Layout Manager"
    "Layout Manager..."
}

res/RFIX/LayoutManagerAddon.grc

'MDID' 32500 "Add-On Identifier" {
    944270126   /* developer ID */
    1113797136  /* local ID */
}

Note on approach

I am intentionally not using ACAPinc.h because including it caused linker conflicts with the Module libraries in my CMake setup. Instead I forward-declare the two API functions I need (ACAPI_MenuItem_RegisterMenu and ACAPI_MenuItem_InstallMenuHandler) with their C++ name-mangled signatures as exported by ACAP_STAT.lib. Both functions return NoError at runtime.

I'm open to the possibility that this approach is flawed in a way I don't understand. Any guidance appreciated.

 

Thank you.

 

Operating system used: Windows 12

0 Replies 0

Didn't find the answer?

Check other topics in this Forum

Back to Forum

Read the latest accepted solutions!

Accepted Solutions

Start a new conversation!