<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: ArchiCAD 27 Add-On: Menu not appearing in menubar in Archicad C++ API</title>
    <link>https://community.graphisoft.com/t5/Archicad-C-API/ArchiCAD-27-Add-On-Menu-not-appearing-in-menubar/m-p/710598#M10998</link>
    <description>&lt;P&gt;Hi Barry,&lt;/P&gt;&lt;P&gt;Asking for fresh eyes was the right call — and the writeup is genuinely good, better than most bug reports here. The enum fix was necessary but it was never going to be sufficient, and here's why.&lt;/P&gt;&lt;H2&gt;Why NoError doesn't mean anything here&lt;/H2&gt;&lt;P&gt;ACAPI_MenuItem_RegisterMenu does not load your strings. It records the resource ID and returns. Archicad reads the actual 'STR#' resource much later, when it builds the menu bar. So a missing or uncompiled resource fails &lt;STRONG&gt;silently, long after your return code was checked&lt;/STRONG&gt;. That's your whole symptom: four green log lines and an empty menu bar.&lt;/P&gt;&lt;P&gt;So the question isn't "why did registration fail" — it didn't. It's "where did the strings go."&lt;/P&gt;&lt;H2&gt;1. Your add-on has no name (check this first)&lt;/H2&gt;&lt;P&gt;This is the one that matches your Work Environment symptom exactly.&lt;/P&gt;&lt;P&gt;In the WE command list, commands are grouped under the add-on's registered name. That name comes from CheckEnvironment, which is supposed to do this:&lt;/P&gt;&lt;PRE&gt;API_AddonType __ACENV_CALL CheckEnvironment (API_EnvirParams* envir)
{
    RSGetIndString (&amp;amp;envir-&amp;gt;addOnInfo-&amp;gt;name,        32000, 1, ACAPI_GetOwnResModule ());
    RSGetIndString (&amp;amp;envir-&amp;gt;addOnInfo-&amp;gt;description, 32000, 2, ACAPI_GetOwnResModule ());
    return APIAddon_Normal;
}&lt;/PRE&gt;&lt;P&gt;Yours returns immediately without touching addOnInfo — and it can't, because your stub API_EnvirParams is char pad[1024] with no addOnInfo member at all. There's also no 'STR#' 32000 anywhere in your RFIX file to read from.&lt;/P&gt;&lt;P&gt;Result: an unnamed add-on. Nothing to search for in Work Environment → Menus. Which is precisely what you observed.&lt;/P&gt;&lt;P&gt;Two halves, both required — the string in RFIX &lt;STRONG&gt;and&lt;/STRONG&gt; the RSGetIndString calls in CheckEnvironment. Fixing either one alone gets you nowhere.&lt;/P&gt;&lt;H2&gt;2. Both .grc files have the same base filename&lt;/H2&gt;&lt;P&gt;You have LayoutManagerAddon.grc in RFIX &lt;STRONG&gt;and&lt;/STRONG&gt; LayoutManagerAddon.grc in RINT. The DevKit convention is:&lt;/P&gt;&lt;PRE&gt;res/RFIX/LayoutManagerAddonFix.grc     &amp;lt;- note the "Fix" suffix
res/RINT/LayoutManagerAddon.grc&lt;/PRE&gt;&lt;P&gt;The suffix isn't cosmetic. ResConv compiles each .grc to an intermediate output derived from the source filename, and identical base names in two directories can land on the same output path — one silently overwrites the other. That would explain MDID being found (add-on loads, shows in Add-On Manager) while 'STR#' 32001 is nowhere to be seen.&lt;/P&gt;&lt;P&gt;I'm not certain this is what's biting you specifically, but it costs thirty seconds to rename and rebuild.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;How to verify either of the above:&lt;/STRONG&gt; open the built .apx in Resource Hacker, or in Visual Studio via File → Open → File → then Resource View. Look for a custom resource of type STR#. If your menu strings aren't in there, the C++ side is irrelevant until that's fixed.&lt;/P&gt;&lt;H2&gt;3. Resource skeletons&lt;/H2&gt;&lt;P&gt;&lt;STRONG&gt;res/RFIX/LayoutManagerAddonFix.grc&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE&gt;'STR#' 32000 "Add-On name and description" {
/* [  1] */  "Layout Manager"
/* [  2] */  "Launches the Layout Manager application"
}

'MDID' 32001 "Add-On Identifier" {
   944270126
   1113797136
}&lt;/PRE&gt;&lt;P&gt;&lt;STRONG&gt;res/RINT/LayoutManagerAddon.grc&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE&gt;'STR#' 32500 "Menu strings" {
/* [  1] */  "Layout Manager"       // top-level menu title
/* [  2] */  "Layout Manager..."    // the command item
}

'STR#' 32501 "Menu prompt strings" {
/* [  1] */  "Layout Manager"
/* [  2] */  "Opens the Layout Manager"
}&lt;/PRE&gt;&lt;PRE&gt;ACAPI_MenuItem_RegisterMenu (32500, 32501, MenuCode_UserDef, MenuFlag_Default);&lt;/PRE&gt;&lt;P&gt;The specific numbers are yours to choose as long as they're in the 32000–32767 range and match the code. What matters: &lt;STRONG&gt;the prompt STR# must have the same number of lines as the menu STR#&lt;/STRONG&gt;, title line included. ResConv accepts a mismatch without complaint; Archicad then quietly drops items. Your current promptStrResID = 0 should be a real resource.&lt;/P&gt;&lt;P&gt;Also drop APIAddon_Preload back to APIAddon_Normal — preload is for add-ons that must be alive before a project opens, which a launcher isn't.&lt;/P&gt;&lt;H2&gt;4. The forward declarations have to go&lt;/H2&gt;&lt;P&gt;I understand why you went there, but this is the actual root problem rather than a workaround for it.&lt;/P&gt;&lt;P&gt;API_EnvirParams and API_MenuParams are not shaped like your stubs. You're passing pointers to structures whose real layout you're guessing at, and reading fields at addresses that hold something else. Right now it happens not to crash. That's luck, not correctness — and it's already cost you addOnInfo.&lt;/P&gt;&lt;P&gt;The linker conflicts that pushed you here are almost certainly a &lt;STRONG&gt;C runtime mismatch&lt;/STRONG&gt;: the DevKit libraries are built against the release DLL runtime (/MD), while CMake's default Debug configuration uses /MDd. That produces exactly the flavour of duplicate-symbol and unresolved-symbol noise that looks like ACAPinc.h is at fault when it isn't.&lt;/P&gt;&lt;P&gt;Rather than patching your own CMakeLists, take Examples/Example_Add-On from the DevKit wholesale as your scaffold and drop your .cpp into it. It has the runtime setting, the WINDOWS / ACExtension / UNICODE defines, and the ResConv steps already wired correctly. Copying just the CMakeLists.txt out of it won't work — the relative paths to the DevKit break.&lt;/P&gt;&lt;H2&gt;5. Two cheap diagnostics&lt;/H2&gt;&lt;P&gt;&lt;STRONG&gt;Bisect the resource question.&lt;/STRONG&gt; Temporarily swap MenuCode_UserDef for one of the standard placement codes and restart Archicad. If the item appears anywhere at all, your resources are compiling and the problem is UserDef placement plus Work Environment. If it still doesn't, go back to section 2.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Clear the cache.&lt;/STRONG&gt; Archicad caches add-on registration and command layout. Your first broken registration may still be cached, meaning you're rebuilding code and looking at a stale menu. Quit Archicad completely (not just the project) before each rebuild, and once the add-on has a proper name, create a fresh Command Layout Scheme from the factory default in Work Environment → Command Layout Schemes.&lt;/P&gt;&lt;H2&gt;Order I'd work in&lt;/H2&gt;&lt;OL&gt;&lt;LI&gt;Rename the RFIX file, add 'STR#' 32000, rebuild, inspect the .apx for your string resources&lt;/LI&gt;&lt;LI&gt;Move to the Example_Add-On scaffold so you can include ACAPinc.h&lt;/LI&gt;&lt;LI&gt;With the real headers available, fill in addOnInfo-&amp;gt;name / description in CheckEnvironment&lt;/LI&gt;&lt;LI&gt;Add the prompt strings and pass a real promptStrResID&lt;/LI&gt;&lt;LI&gt;Fresh Command Layout Scheme, then look for the menu&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;One last thing: for what it's worth, the fact that you got four correct entry points, correct exports, and a clean load without a working DevKit build is not nothing. The resource pipeline is the part of this API that catches out people who &lt;EM&gt;have&lt;/EM&gt; read the documentation — it fails quietly by design, and there's no error to search for. You didn't miss something obvious.&lt;/P&gt;&lt;P&gt;Good luck — post the resource inspection result if it doesn't come together.&lt;/P&gt;</description>
    <pubDate>Mon, 03 Aug 2026 04:16:42 GMT</pubDate>
    <dc:creator>dmitry_nordlab</dc:creator>
    <dc:date>2026-08-03T04:16:42Z</dc:date>
    <item>
      <title>ArchiCAD 27 Add-On: Menu not appearing in menubar</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/ArchiCAD-27-Add-On-Menu-not-appearing-in-menubar/m-p/710522#M10997</link>
      <description>&lt;P class=""&gt;&lt;STRONG&gt;Platform:&lt;/STRONG&gt; Windows 11, ArchiCAD 27 (build 6020)&lt;BR /&gt;&lt;STRONG&gt;DevKit:&lt;/STRONG&gt; API.Development.Kit.WIN.27.6003&lt;BR /&gt;&lt;STRONG&gt;Toolchain:&lt;/STRONG&gt; Visual Studio 2019 (v142), CMake, Ninja&lt;/P&gt;&lt;HR /&gt;&lt;H2 id="background"&gt;Background&lt;/H2&gt;&lt;P class=""&gt;I want to be upfront: this add-on is &lt;STRONG&gt;vibe coded&lt;/STRONG&gt; — 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.&lt;/P&gt;&lt;HR /&gt;&lt;H2 id="what-works"&gt;What works&lt;/H2&gt;&lt;UL&gt;&lt;LI&gt;The add-on builds cleanly with no linker errors&lt;/LI&gt;&lt;LI&gt;It appears in&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Options → Add-On Manager&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(checked, loaded)&lt;/LI&gt;&lt;LI&gt;All four entry functions are confirmed called via a log file:&lt;/LI&gt;&lt;/UL&gt;&lt;DIV class=""&gt;&lt;PRE&gt;CheckEnvironment called!
RegisterInterface called!
RegisterMenu OK       ← ACAPI_MenuItem_RegisterMenu returns 0
Initialize called!
InstallMenuHandler OK ← ACAPI_MenuItem_InstallMenuHandler returns 0&lt;/PRE&gt;&lt;/DIV&gt;&lt;UL&gt;&lt;LI&gt;The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;.apx&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;exports all 6 required symbols:&lt;BR /&gt;GetExportedFuncAddrs,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;SetImportedFuncAddrs,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;CheckEnvironment,&lt;BR /&gt;RegisterInterface,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Initialize,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;FreeData&lt;/LI&gt;&lt;/UL&gt;&lt;HR /&gt;&lt;H2 id="the-problem"&gt;The problem&lt;/H2&gt;&lt;P class=""&gt;&lt;STRONG&gt;No menu entry appears anywhere in the menubar or any submenu.&lt;/STRONG&gt;&lt;/P&gt;&lt;P class=""&gt;I've been trying to get a custom top-level menu ("Layout Manager") to appear in the menubar using MenuCode_UserDef.&lt;/P&gt;&lt;P class=""&gt;During debugging I discovered my hand-rolled enum had the &lt;STRONG&gt;wrong value&lt;/STRONG&gt; — I wasn't including ACAPinc.h (see note below), so I had defined it manually:&lt;/P&gt;&lt;DIV class=""&gt;&lt;PRE&gt;&lt;SPAN class=""&gt;// What I had (WRONG — this is actually MenuCode_Image):&lt;/SPAN&gt;
&lt;SPAN class=""&gt;MenuCode&lt;/SPAN&gt;_UserDef = &lt;SPAN class=""&gt;8&lt;/SPAN&gt;

&lt;SPAN class=""&gt;// Correct value from APIdefs_Registration.h:&lt;/SPAN&gt;
&lt;SPAN class=""&gt;MenuCode&lt;/SPAN&gt;_UserDef = &lt;SPAN class=""&gt;0&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;P class=""&gt;I have now corrected this and rebuilt. The menu still does not appear.&lt;/P&gt;&lt;P class=""&gt;I also noticed this note in the Add-On Manager dialog:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P class=""&gt;&lt;EM&gt;"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."&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P class=""&gt;When searching for "Layout Manager" in &lt;STRONG&gt;Work Environment → Menus&lt;/STRONG&gt;, the command does &lt;STRONG&gt;not appear&lt;/STRONG&gt; in the available commands list.&lt;/P&gt;&lt;HR /&gt;&lt;H2 id="what-im-looking-for"&gt;What I'm looking for&lt;/H2&gt;&lt;P class=""&gt;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.&lt;/P&gt;&lt;P class=""&gt;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?&lt;/P&gt;&lt;HR /&gt;&lt;H2 id="relevant-code"&gt;Relevant code&lt;/H2&gt;&lt;H3 id="layoutmanageraddoncpp-simplified"&gt;LayoutManagerAddon.cpp (simplified)&lt;/H3&gt;&lt;DIV class=""&gt;&lt;PRE&gt;#include &amp;lt;windows.&lt;SPAN class=""&gt;h&lt;/SPAN&gt;&amp;gt;
#include &amp;lt;shellapi.&lt;SPAN class=""&gt;h&lt;/SPAN&gt;&amp;gt;
#include &amp;lt;stdio.&lt;SPAN class=""&gt;h&lt;/SPAN&gt;&amp;gt;

typedef int          &lt;SPAN class=""&gt;GSErrCode&lt;/SPAN&gt;;
typedef unsigned int &lt;SPAN class=""&gt;GSFlags&lt;/SPAN&gt;;
#define &lt;SPAN class=""&gt;NoError&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt;

typedef enum {
    &lt;SPAN class=""&gt;APIAddon&lt;/SPAN&gt;_DontRegister = &lt;SPAN class=""&gt;0&lt;/SPAN&gt;,
    &lt;SPAN class=""&gt;APIAddon&lt;/SPAN&gt;_Normal       = &lt;SPAN class=""&gt;1&lt;/SPAN&gt;,
    &lt;SPAN class=""&gt;APIAddon&lt;/SPAN&gt;_Preload      = &lt;SPAN class=""&gt;2&lt;/SPAN&gt;
} API_AddonType;

typedef enum {
    &lt;SPAN class=""&gt;MenuCode&lt;/SPAN&gt;_UserDef = &lt;SPAN class=""&gt;0&lt;/SPAN&gt;    &lt;SPAN class=""&gt;// from APIdefs_Registration.h&lt;/SPAN&gt;
} &lt;SPAN class=""&gt;APIMenuCodeID&lt;/SPAN&gt;;

#define &lt;SPAN class=""&gt;MenuFlag&lt;/SPAN&gt;_Default &lt;SPAN class=""&gt;0&lt;/SPAN&gt;

struct API_MenuItemRef           { short menuResID; short itemIndex; };
struct API_ServerApplicationInfo { short mainVersion; short releaseVersion; char pad[&lt;SPAN class=""&gt;508&lt;/SPAN&gt;]; };
struct API_EnvirParams           { API_ServerApplicationInfo serverInfo; char pad[&lt;SPAN class=""&gt;1024&lt;/SPAN&gt;]; };
struct API_MenuParams            { API_MenuItemRef menuItemRef; };

&lt;SPAN class=""&gt;GSErrCode&lt;/SPAN&gt; __cdecl &lt;SPAN class=""&gt;ACAPI_MenuItem_RegisterMenu&lt;/SPAN&gt;(
    short menuStrResID, short promptStrResID,
    &lt;SPAN class=""&gt;APIMenuCodeID&lt;/SPAN&gt; menuPosCode, &lt;SPAN class=""&gt;GSFlags&lt;/SPAN&gt; menuFlags);

&lt;SPAN class=""&gt;GSErrCode&lt;/SPAN&gt; __cdecl &lt;SPAN class=""&gt;ACAPI_MenuItem_InstallMenuHandler&lt;/SPAN&gt;(
    short menuStrResID, &lt;SPAN class=""&gt;GSErrCode&lt;/SPAN&gt; (__cdecl* handlerProc)(&lt;SPAN class=""&gt;const&lt;/SPAN&gt; API_MenuParams*));

&lt;SPAN class=""&gt;static&lt;/SPAN&gt; &lt;SPAN class=""&gt;void&lt;/SPAN&gt; &lt;SPAN class=""&gt;WriteLog&lt;/SPAN&gt;(&lt;SPAN class=""&gt;const&lt;/SPAN&gt; wchar_t* msg) { &lt;SPAN class=""&gt;/* logs to file */&lt;/SPAN&gt; }
&lt;SPAN class=""&gt;static&lt;/SPAN&gt; &lt;SPAN class=""&gt;void&lt;/SPAN&gt; &lt;SPAN class=""&gt;LaunchLayoutManager&lt;/SPAN&gt;() { &lt;SPAN class=""&gt;/* ShellExecuteW to .exe */&lt;/SPAN&gt; }

&lt;SPAN class=""&gt;static&lt;/SPAN&gt; &lt;SPAN class=""&gt;GSErrCode&lt;/SPAN&gt; __cdecl &lt;SPAN class=""&gt;MenuCommandHandler&lt;/SPAN&gt;(&lt;SPAN class=""&gt;const&lt;/SPAN&gt; API_MenuParams*)
{
    &lt;SPAN class=""&gt;LaunchLayoutManager&lt;/SPAN&gt;();
    &lt;SPAN class=""&gt;return&lt;/SPAN&gt; &lt;SPAN class=""&gt;NoError&lt;/SPAN&gt;;
}

extern &lt;SPAN class=""&gt;"C"&lt;/SPAN&gt; {

&lt;SPAN class=""&gt;__declspec&lt;/SPAN&gt;(dllexport) API_AddonType __cdecl &lt;SPAN class=""&gt;CheckEnvironment&lt;/SPAN&gt;(API_EnvirParams*)
{
    &lt;SPAN class=""&gt;return&lt;/SPAN&gt; &lt;SPAN class=""&gt;APIAddon&lt;/SPAN&gt;_Preload;
}

&lt;SPAN class=""&gt;__declspec&lt;/SPAN&gt;(dllexport) &lt;SPAN class=""&gt;GSErrCode&lt;/SPAN&gt; __cdecl &lt;SPAN class=""&gt;RegisterInterface&lt;/SPAN&gt;(&lt;SPAN class=""&gt;void&lt;/SPAN&gt;)
{
    &lt;SPAN class=""&gt;return&lt;/SPAN&gt; &lt;SPAN class=""&gt;ACAPI_MenuItem_RegisterMenu&lt;/SPAN&gt;(&lt;SPAN class=""&gt;32001&lt;/SPAN&gt;, &lt;SPAN class=""&gt;0&lt;/SPAN&gt;, &lt;SPAN class=""&gt;MenuCode&lt;/SPAN&gt;_UserDef, &lt;SPAN class=""&gt;MenuFlag&lt;/SPAN&gt;_Default);
}

&lt;SPAN class=""&gt;__declspec&lt;/SPAN&gt;(dllexport) &lt;SPAN class=""&gt;GSErrCode&lt;/SPAN&gt; __cdecl &lt;SPAN class=""&gt;Initialize&lt;/SPAN&gt;(&lt;SPAN class=""&gt;void&lt;/SPAN&gt;)
{
    &lt;SPAN class=""&gt;return&lt;/SPAN&gt; &lt;SPAN class=""&gt;ACAPI_MenuItem_InstallMenuHandler&lt;/SPAN&gt;(&lt;SPAN class=""&gt;32001&lt;/SPAN&gt;, &lt;SPAN class=""&gt;MenuCommandHandler&lt;/SPAN&gt;);
}

&lt;SPAN class=""&gt;__declspec&lt;/SPAN&gt;(dllexport) &lt;SPAN class=""&gt;GSErrCode&lt;/SPAN&gt; __cdecl &lt;SPAN class=""&gt;FreeData&lt;/SPAN&gt;(&lt;SPAN class=""&gt;void&lt;/SPAN&gt;) { &lt;SPAN class=""&gt;return&lt;/SPAN&gt; &lt;SPAN class=""&gt;NoError&lt;/SPAN&gt;; }

} &lt;SPAN class=""&gt;// extern "C"&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;H3 id="resrintlayoutmanageraddongrc"&gt;res/RINT/LayoutManagerAddon.grc&lt;/H3&gt;&lt;DIV class=""&gt;&lt;PRE&gt;&lt;SPAN class=""&gt;'STR#'&lt;/SPAN&gt; &lt;SPAN class=""&gt;32001&lt;/SPAN&gt; &lt;SPAN class=""&gt;"Menu strings"&lt;/SPAN&gt; {
    &lt;SPAN class=""&gt;"Layout Manager"&lt;/SPAN&gt;
    &lt;SPAN class=""&gt;"Layout Manager..."&lt;/SPAN&gt;
}&lt;/PRE&gt;&lt;/DIV&gt;&lt;H3 id="resrfixlayoutmanageraddongrc"&gt;res/RFIX/LayoutManagerAddon.grc&lt;/H3&gt;&lt;DIV class=""&gt;&lt;PRE&gt;&lt;SPAN class=""&gt;'MDID'&lt;/SPAN&gt; &lt;SPAN class=""&gt;32500&lt;/SPAN&gt; &lt;SPAN class=""&gt;"Add-On Identifier"&lt;/SPAN&gt; {
    &lt;SPAN class=""&gt;944270126&lt;/SPAN&gt;   &lt;SPAN class=""&gt;/* developer ID */&lt;/SPAN&gt;
    &lt;SPAN class=""&gt;1113797136&lt;/SPAN&gt;  &lt;SPAN class=""&gt;/* local ID */&lt;/SPAN&gt;
}&lt;/PRE&gt;&lt;/DIV&gt;&lt;HR /&gt;&lt;H2 id="note-on-approach"&gt;Note on approach&lt;/H2&gt;&lt;P class=""&gt;I am intentionally &lt;STRONG&gt;not using ACAPinc.h&lt;/STRONG&gt; 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.&lt;/P&gt;&lt;P class=""&gt;I'm open to the possibility that this approach is flawed in a way I don't understand. Any guidance appreciated.&lt;/P&gt;&lt;P class=""&gt;&amp;nbsp;&lt;/P&gt;&lt;P class=""&gt;Thank you.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT face="courier new,courier" color="grey"&gt;Operating system used: &lt;EM&gt;Windows 12&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 31 Jul 2026 19:17:31 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/ArchiCAD-27-Add-On-Menu-not-appearing-in-menubar/m-p/710522#M10997</guid>
      <dc:creator>The Smoked Salmon</dc:creator>
      <dc:date>2026-07-31T19:17:31Z</dc:date>
    </item>
    <item>
      <title>Re: ArchiCAD 27 Add-On: Menu not appearing in menubar</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/ArchiCAD-27-Add-On-Menu-not-appearing-in-menubar/m-p/710598#M10998</link>
      <description>&lt;P&gt;Hi Barry,&lt;/P&gt;&lt;P&gt;Asking for fresh eyes was the right call — and the writeup is genuinely good, better than most bug reports here. The enum fix was necessary but it was never going to be sufficient, and here's why.&lt;/P&gt;&lt;H2&gt;Why NoError doesn't mean anything here&lt;/H2&gt;&lt;P&gt;ACAPI_MenuItem_RegisterMenu does not load your strings. It records the resource ID and returns. Archicad reads the actual 'STR#' resource much later, when it builds the menu bar. So a missing or uncompiled resource fails &lt;STRONG&gt;silently, long after your return code was checked&lt;/STRONG&gt;. That's your whole symptom: four green log lines and an empty menu bar.&lt;/P&gt;&lt;P&gt;So the question isn't "why did registration fail" — it didn't. It's "where did the strings go."&lt;/P&gt;&lt;H2&gt;1. Your add-on has no name (check this first)&lt;/H2&gt;&lt;P&gt;This is the one that matches your Work Environment symptom exactly.&lt;/P&gt;&lt;P&gt;In the WE command list, commands are grouped under the add-on's registered name. That name comes from CheckEnvironment, which is supposed to do this:&lt;/P&gt;&lt;PRE&gt;API_AddonType __ACENV_CALL CheckEnvironment (API_EnvirParams* envir)
{
    RSGetIndString (&amp;amp;envir-&amp;gt;addOnInfo-&amp;gt;name,        32000, 1, ACAPI_GetOwnResModule ());
    RSGetIndString (&amp;amp;envir-&amp;gt;addOnInfo-&amp;gt;description, 32000, 2, ACAPI_GetOwnResModule ());
    return APIAddon_Normal;
}&lt;/PRE&gt;&lt;P&gt;Yours returns immediately without touching addOnInfo — and it can't, because your stub API_EnvirParams is char pad[1024] with no addOnInfo member at all. There's also no 'STR#' 32000 anywhere in your RFIX file to read from.&lt;/P&gt;&lt;P&gt;Result: an unnamed add-on. Nothing to search for in Work Environment → Menus. Which is precisely what you observed.&lt;/P&gt;&lt;P&gt;Two halves, both required — the string in RFIX &lt;STRONG&gt;and&lt;/STRONG&gt; the RSGetIndString calls in CheckEnvironment. Fixing either one alone gets you nowhere.&lt;/P&gt;&lt;H2&gt;2. Both .grc files have the same base filename&lt;/H2&gt;&lt;P&gt;You have LayoutManagerAddon.grc in RFIX &lt;STRONG&gt;and&lt;/STRONG&gt; LayoutManagerAddon.grc in RINT. The DevKit convention is:&lt;/P&gt;&lt;PRE&gt;res/RFIX/LayoutManagerAddonFix.grc     &amp;lt;- note the "Fix" suffix
res/RINT/LayoutManagerAddon.grc&lt;/PRE&gt;&lt;P&gt;The suffix isn't cosmetic. ResConv compiles each .grc to an intermediate output derived from the source filename, and identical base names in two directories can land on the same output path — one silently overwrites the other. That would explain MDID being found (add-on loads, shows in Add-On Manager) while 'STR#' 32001 is nowhere to be seen.&lt;/P&gt;&lt;P&gt;I'm not certain this is what's biting you specifically, but it costs thirty seconds to rename and rebuild.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;How to verify either of the above:&lt;/STRONG&gt; open the built .apx in Resource Hacker, or in Visual Studio via File → Open → File → then Resource View. Look for a custom resource of type STR#. If your menu strings aren't in there, the C++ side is irrelevant until that's fixed.&lt;/P&gt;&lt;H2&gt;3. Resource skeletons&lt;/H2&gt;&lt;P&gt;&lt;STRONG&gt;res/RFIX/LayoutManagerAddonFix.grc&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE&gt;'STR#' 32000 "Add-On name and description" {
/* [  1] */  "Layout Manager"
/* [  2] */  "Launches the Layout Manager application"
}

'MDID' 32001 "Add-On Identifier" {
   944270126
   1113797136
}&lt;/PRE&gt;&lt;P&gt;&lt;STRONG&gt;res/RINT/LayoutManagerAddon.grc&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE&gt;'STR#' 32500 "Menu strings" {
/* [  1] */  "Layout Manager"       // top-level menu title
/* [  2] */  "Layout Manager..."    // the command item
}

'STR#' 32501 "Menu prompt strings" {
/* [  1] */  "Layout Manager"
/* [  2] */  "Opens the Layout Manager"
}&lt;/PRE&gt;&lt;PRE&gt;ACAPI_MenuItem_RegisterMenu (32500, 32501, MenuCode_UserDef, MenuFlag_Default);&lt;/PRE&gt;&lt;P&gt;The specific numbers are yours to choose as long as they're in the 32000–32767 range and match the code. What matters: &lt;STRONG&gt;the prompt STR# must have the same number of lines as the menu STR#&lt;/STRONG&gt;, title line included. ResConv accepts a mismatch without complaint; Archicad then quietly drops items. Your current promptStrResID = 0 should be a real resource.&lt;/P&gt;&lt;P&gt;Also drop APIAddon_Preload back to APIAddon_Normal — preload is for add-ons that must be alive before a project opens, which a launcher isn't.&lt;/P&gt;&lt;H2&gt;4. The forward declarations have to go&lt;/H2&gt;&lt;P&gt;I understand why you went there, but this is the actual root problem rather than a workaround for it.&lt;/P&gt;&lt;P&gt;API_EnvirParams and API_MenuParams are not shaped like your stubs. You're passing pointers to structures whose real layout you're guessing at, and reading fields at addresses that hold something else. Right now it happens not to crash. That's luck, not correctness — and it's already cost you addOnInfo.&lt;/P&gt;&lt;P&gt;The linker conflicts that pushed you here are almost certainly a &lt;STRONG&gt;C runtime mismatch&lt;/STRONG&gt;: the DevKit libraries are built against the release DLL runtime (/MD), while CMake's default Debug configuration uses /MDd. That produces exactly the flavour of duplicate-symbol and unresolved-symbol noise that looks like ACAPinc.h is at fault when it isn't.&lt;/P&gt;&lt;P&gt;Rather than patching your own CMakeLists, take Examples/Example_Add-On from the DevKit wholesale as your scaffold and drop your .cpp into it. It has the runtime setting, the WINDOWS / ACExtension / UNICODE defines, and the ResConv steps already wired correctly. Copying just the CMakeLists.txt out of it won't work — the relative paths to the DevKit break.&lt;/P&gt;&lt;H2&gt;5. Two cheap diagnostics&lt;/H2&gt;&lt;P&gt;&lt;STRONG&gt;Bisect the resource question.&lt;/STRONG&gt; Temporarily swap MenuCode_UserDef for one of the standard placement codes and restart Archicad. If the item appears anywhere at all, your resources are compiling and the problem is UserDef placement plus Work Environment. If it still doesn't, go back to section 2.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Clear the cache.&lt;/STRONG&gt; Archicad caches add-on registration and command layout. Your first broken registration may still be cached, meaning you're rebuilding code and looking at a stale menu. Quit Archicad completely (not just the project) before each rebuild, and once the add-on has a proper name, create a fresh Command Layout Scheme from the factory default in Work Environment → Command Layout Schemes.&lt;/P&gt;&lt;H2&gt;Order I'd work in&lt;/H2&gt;&lt;OL&gt;&lt;LI&gt;Rename the RFIX file, add 'STR#' 32000, rebuild, inspect the .apx for your string resources&lt;/LI&gt;&lt;LI&gt;Move to the Example_Add-On scaffold so you can include ACAPinc.h&lt;/LI&gt;&lt;LI&gt;With the real headers available, fill in addOnInfo-&amp;gt;name / description in CheckEnvironment&lt;/LI&gt;&lt;LI&gt;Add the prompt strings and pass a real promptStrResID&lt;/LI&gt;&lt;LI&gt;Fresh Command Layout Scheme, then look for the menu&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;One last thing: for what it's worth, the fact that you got four correct entry points, correct exports, and a clean load without a working DevKit build is not nothing. The resource pipeline is the part of this API that catches out people who &lt;EM&gt;have&lt;/EM&gt; read the documentation — it fails quietly by design, and there's no error to search for. You didn't miss something obvious.&lt;/P&gt;&lt;P&gt;Good luck — post the resource inspection result if it doesn't come together.&lt;/P&gt;</description>
      <pubDate>Mon, 03 Aug 2026 04:16:42 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/ArchiCAD-27-Add-On-Menu-not-appearing-in-menubar/m-p/710598#M10998</guid>
      <dc:creator>dmitry_nordlab</dc:creator>
      <dc:date>2026-08-03T04:16:42Z</dc:date>
    </item>
  </channel>
</rss>

