Documentation should use urls.
Are function names case insensitive? Yes!
Add date and handle types with "B1" and "B2"? Excel seems to ignore the 1 and 2.
#define XLLEXPORT __pragma(...), constexpr check of FUNCTION ??? or generate add-in ???
https://blog.conan.io/2021/02/10/Dependencies-Visual-Studio-C++-property-files.html
https://docs.microsoft.com/en-us/office/dev/add-ins/excel/make-custom-functions-compatible-with-xll-udf Adds formula auto complete.
x86 or x64 for /F "tokens=3" %A in ('reg query HKLM\SOFTWARE\Microsoft\Office\ClickToRun\Configuration /v Platform') do (echo %A)
Generate JS from AddIn?
Use function tests instead of lambdas. Get names from nm | grep '^test' Allow wildcards.
Use xlfRegister("file.xll") to require add-in. Versions?
Create zip file for visualizers and project template to replace msi.
Add signing certificate https://github.com/actions/starter-workflows/blob/main/ci/dotnet-desktop.yml
https://docs.microsoft.com/en-us/office/troubleshoot/office-suite-issues/click-hyperlink-to-sso-website Add a custom HTTP header to the GET response for the Office file contents. "Content-Disposition: Attachment"
https://www.drdobbs.com/architecture-and-design/faking-dde-with-private-servers/184409151?pgno=3
Exception thrown at ... in EXCEL.EXE: 0xC0000005: https://docs.microsoft.com/en-us/office/client-developer/excel/how-to-call-xll-functions-from-the-function-wizard-or-replace-dialog-boxes?redirectedfrom=MSDN
#define CLASS_NAME_BUFFSIZE 50 #define WINDOW_TEXT_BUFFSIZE 50 // Data structure used as input to xldlg_enum_proc(), called by // called_from_paste_fn_dlg(), called_from_replace_dlg(), and // called_from_Excel_dlg(). These functions tell the caller whether // the current worksheet function was called from one or either of // these dialog boxes. typedef struct { bool is_dlg; short low_hwnd; char *window_title_text; // set to NULL if don't care } xldlg_enum_struct; // The callback function called by Windows for every top-level window. BOOL CALLBACK xldlg_enum_proc(HWND hwnd, xldlg_enum_struct *p_enum) { // Check if the parent window is Excel. // Note: Because of the change from MDI (Excel 2010) // to SDI (Excel 2013), comment out this step in Excel 2013. if(LOWORD((DWORD)GetParent(hwnd)) != p_enum->low_hwnd) return TRUE; // keep iterating char class_name[CLASS_NAME_BUFFSIZE + 1]; // Ensure that class_name is always null terminated for safety. class_name[CLASS_NAME_BUFFSIZE] = 0; GetClassName(hwnd, class_name, CLASS_NAME_BUFFSIZE); // Do a case-insensitve comparison for the Excel dialog window // class name with the Excel version number truncated. size_t len; // The length of the window's title text if(_strnicmp(class_name, "bosa_sdm_xl", 11) == 0) { // Check if a searching for a specific title string if(p_enum->window_title_text) { // Get the window's title and see if it matches the given text. char buffer[WINDOW_TEXT_BUFFSIZE + 1]; buffer[WINDOW_TEXT_BUFFSIZE] = 0; len = GetWindowText(hwnd, buffer, WINDOW_TEXT_BUFFSIZE); if(len == 0) // No title { if(p_enum->window_title_text[0] != 0) return TRUE; // No match, so keep iterating } // Window has a title so do a case-insensitive comparison of the // title and the search text, if provided. else if(p_enum->window_title_text[0] != 0 && _stricmp(buffer, p_enum->window_title_text) != 0) return TRUE; // Keep iterating } p_enum->is_dlg = true; return FALSE; // Tells Windows to stop iterating. } return TRUE; // Tells Windows to continue iterating. }
bool called_from_paste_fn_dlg(void) { XLOPER xHwnd; // Calls Excel4, which only returns the low part of the Excel // main window handle. This is OK for the search however. if(Excel4(xlGetHwnd, &xHwnd, 0)) return false; // Couldn't get it, so assume not // Search for bosa_sdm_xl* dialog box with no title string. xldlg_enum_struct es = {FALSE, xHwnd.val.w, ""}; EnumWindows((WNDENUMPROC)xldlg_enum_proc, (LPARAM)&es); return es.is_dlg; }
states: uninstalled, known, installed, loaded
AIM: HKCU\Software\Microsoft\Office<version>\Excel\Add-in Manager - value name: full path OPENn: HKCU\Software\Microsoft\Office<version>\Excel\Options\Open - value name: OPENn data: "/R full_path" DIR: %AppData%\Microsoft\Templates\ - trusted location;
AddinManager uses AIM or OPENn but never both
New() puts full path in AIM
Add() moves AIM\full_path to OPENn
Remove() moves OPENn
to AIM\full_path
Delete() remove and then delete AIM registry entry
Install() copy to DIR
Status of add-in manager.
If in OPENn check for newer.
AIM and OPENn not set Prompt to install xlGetName in Template Prompt for New to add to AIM Prompt to Add (does not work?)