【XLL 文档翻译】【第1部分】 Add-in 管理器 和 XLL 接口函数
xlAddInManagerInfo/xlAddInManagerInfo12
在 Excel 會話中,每一次調用 Add-In 管理器時,系統會調用這兩個函數。此函數可以在 Add-In 管理器中提供關于 Add-In 的信息。
如果 XLL 同時輸出了這兩個函數,Excel 2007 會優先調用 xlAddInManagerInfo12 。xlAddInManagerInfo12功能 應該和 xlAddInManagerInfo 保持一至,從而保證 XLL 在不同版本的 Excel 中相互兼容。Excel 總是默認 xlAddInManagerInfo12 返回 XLOPER12 數據類型,xlAddInManagerInfo 返回 XLOPER 數據類型。
xlAddInManagerInfo12 只能由 Excel 2007 版本 調用,同樣早期版本的 Excel 也不支持 XLOPER12 數據類型。
XLL 可以不用實現和輸出這兩個函數,這并不會影響 XLL 的運行。
函數原型
LPXLOPER WINAPI xlAddInManagerInfo(LPXLOPER pxAction); LPXLOPER WINAPI xlAddInManagerInfo(LPXLOPER pxAction);參數
pxAction: 一個 XLOPER/XLOPER12 數值類型指針。
Excel 會調用此參數。
屬性值/返回值
如果 pxAction 數值是1 ,你的這個函數在實現時就需要返回 一個關于 add-in 的字符串信息,通常返回的 add-in 名稱或是版本號。其它情況下,函數需要返回 #VALUE!。
如果你沒有返回任意一個字符串,Excel 會嘗試將返回值轉換為 字符串。
備注
如果返回的字符串是一個動態分析內存空間,你必需確保內存最終是可以釋放的。如果字符串由 Excel 分配,你可以設置 xlbitXLFree 選項。如果字符串是由 DLL 分配的,你就需要設置為 xlbitDLLFree 選項,并且實現 xlAutoFree(如果返回的是XLOPER) 或 xlAutoFree12(如果返回的 XLOPER12) 函數。
實例
\SAMPLES\GENERIC\GENERIC.C
LPXLOPER12 WINAPI xlAddInManagerInfo12(LPXLOPER12 xAction) {static XLOPER12 xInfo, xIntAction;/* ** This code coerces the passed-in value to an integer. This is how the ** code determines what is being requested. If it receives a 1, it returns a ** string representing the long name. If it receives anything else, it ** returns a #VALUE! error. */Excel12f(xlCoerce, &xIntAction, 2, xAction, TempInt12(xltypeInt));if(xIntAction.val.w == 1) {xInfo.xltype = xltypeStr;xInfo.val.str = L"\026Example Standalone DLL";}else {xInfo.xltype = xltypeErr;xInfo.val.err = xlerrValue;}// Word of caution - returning static XLOPERs/XLOPER12s is not thread safe // for UDFs declared as thread safe. Use alternate memory allocation mechanisms.return (LPXLOPER12)&xInfo; }xlAutoAdd
在 Excel 會話期間,任意時候使用 Add-In 管理器載入 XLL 都會調用此函數。需要注意的是,此函數不會在 Excel 啟動時預載入 add-in 時調用。
此函數可以用于顯示自定義對話框告知用戶 Add-In 已經激活,或是讀寫注冊表,檢查認證信息等等。
對 XLL 來說,此函數不是必需函數。
原型
int WINAPI xlAutoAdd(void);參數
此函數沒有帶參數
屬性值和返回值
你的函數實現需要返回 1 (int)
備注
當你需要在 使用 Add-In 管理添加 XLL 執行某些操作時,使用此 函數
實例
函數實例參考:
\SAMPLES\EXAMPLE\EXAMPLE.C 和 \SAMPLES\GENERIC\GENERIC.C 下面的代碼來自于\SAMPLES\EXAMPLE\EXAMPLE.C.
xlAutoClose
任何時候去激活 XLL 都會調用這個函數。 Excel 會在正常關閉程序時,去激活 add-in 。也可以在 使用 Excel 的時候,由用戶手動去激活。
Excel 不強制要求 XLL 實現和輸出些函數。盡管它有時對以下操作十分有用,如:如果 XLL 去激活函數和命令,釋放資源、取消定制等等。如果 XLL 沒有確定要去激活函數和命令,Excel 會在調用 xlAutoClose 函數后,執行此操作。
函數原型
int WINAPI xlAutoClose ( void );參數
這個函數沒有帶任何參數。
屬性和返回值
你實現此函數時,必需返回 1 (int)。
備注
Excel 在任何時候去激活 XLL ,去激活就是從內存中卸載 XLL。XLL 會在以下幾種情形被去激活:
- 在運行 Excel 時激活了XLL,然后正常關閉 Excel 的情況下。
- 在 Excel 運行期間,用戶手動卸載。
- XLL 可以使用幾下幾種方法制裁:
- 使用 Add-In 管理器。
- 在其它的 XLL 中調用 xlFUnfregister 函數,使用 DLL 名稱做為唯一參數。
- 在 XLM 宏表中調用 UNREGISTER ,使用 DLL 名稱做為唯一參數。
這個函數可以做以下這些操作:
- 移除由 XLL 添加的菜單和菜單項。
- 執行任何必要的全局清理
- 刪除輸出函數創建的名稱。記住注冊 函數 可能會導致創建一些名稱。
實例
實例源文件在 SAMPLES\EXAMPLE\EXAMPLE.C 和 SAMPLES\GENERIC\GENERIC.C,下面的實例來自于SAMPLES\GENERIC\GENERIC.C.
int WINAPI xlAutoClose(void) {int i;XLOPER12 xRes;// // This block first deletes all names added by xlAutoOpen or // xlAutoRegister12. Next, it checks if the drop-down menu Generic still // exists. If it does, it is deleted using xlfDeleteMenu. It then checks // if the Test toolbar still exists. If it is, xlfDeleteToolbar is // used to delete it. // // The following code to delete the defined names // does not work in the current version of Excel. // You cannot delete these names once they are Registered. // The code is left here in case the functionality becomes // available in a future version. //for (i = 0; i < g_rgWorksheetFuncsRows; i++)Excel12f(xlfSetName, 0, 1, TempStr12(g_rgWorksheetFuncs[i][2]));for (i = 0; i < g_rgCommandFuncsRows; i++)Excel12f(xlfSetName, 0, 1, TempStr12(g_rgCommandFuncs[i][2])); // // Everything else works as documented. //Excel12f(xlfGetBar, &xRes, 3, TempInt12(10), TempStr12(L"Generic"), TempInt12(0));if (xRes.xltype != xltypeErr){Excel12f(xlfDeleteMenu, 0, 2, TempNum12(10), TempStr12(L"Generic"));// Free the XLOPER12 returned by xlfGetBar //Excel12f(xlFree, 0, 1, (LPXLOPER12) &xRes);}Excel12f(xlfGetToolbar, &xRes, 2, TempInt12(7), TempStr12(L"Test"));if (xRes.xltype != xltypeErr){Excel12f(xlfDeleteToolbar, 0, 1, TempStr12(L"Test"));// Free the XLOPER12 returned by xlfGetToolbar //Excel12f(xlFree, 0, 1, (LPXLOPER12) &xRes);}return 1; }xlAutoFree / xlAutoFree12
當 XLL 工作表函數返回 XLOPER / XLOPER12 數據類型,并且它們設置了一個標識,告訴 Excel這個 XLL 需要釋放時才會調用這兩個函數。 它能夠讓 XLL 返回一個動態分配數組、字符串 和 外部引用 時不會造成內存泄漏。更詳細的信息,請查看 Excel 2007 內存管理 一節。
只有 Excel 2007 及其以后的版本才支持 xlAutoFree12 函數,和 XLOPER12 數據類型。
Excel 不強制要求 XLL 實現和輸出些函數。但當你的 XLL 函數返回了 動態分配 的 XLOPER 和 XLOPER12 數據類型時或是包含了動態分配的內存指針時,你必需實現它們。確保你的 XLL 從頭到尾,就使用一至的方法來管理內存,以及統一的 xlAutoFree 和 xlAutoFree12 的函數實現。
在 xlAutoFree / xlAutoFree12 函數內部,Excel 的回調功能是不可用的,但有一個例外,xlFree 函數可用于釋放 Excel 分配的內存。
函數原型
void WINAPI xlAutoFree(LPXLOPER pxFree); void WINAPI xlAutoFree12(LPXLOPER12 pxFree);參數
pxFree ( 在 xlAutoFree 中使用 LPXLOPER )
pxFee (在 xlAutoFree12 中使用 LPXLOPER12 )
XLOPER 或 XLOPER12 內存指針,表示需要釋放的內存。
屬性值 / 返回值
這個函數不會返回任何值,因此需要聲明為返回 void。
備注
當 Excel 2007 設置了使用 多線程計算時, xlAutoFree / xlAutoFree12 會在同一個線程上被調用 并返回。系統總是在隨后的單元格評估線程之前調用 xlAutoFree / xlAutoFree12 。這簡化了你的 XLL 中的線程設計。
如果你的 xlAutoFree / xlAutoFree12 支持查看 pxFree 的 xltype 字段,你需要知道, xlbitDLLFree 位必需設置。
實例
實例 1
第一個實例來自于 \SAMPLES\EXAMPLE\EXAMPLE.C 示范了 xlAutoFree 的具體實現,這只有一個函數 fArray 。通常,你的 XLL 中有多個函數返回了 XLOPER 或 XLOPER12 需要釋放。在這種情況下,需要一個受較少限制的實現。
實例 2
第二個實例,始終假設 XLOPER12 創建與 1.6.3節的 的 xl12_Str_example、xl12_Ref_example 和 xl12_Multi_example。假設已經設置了 xlbitDLLFree 位。所有的字符串,數組,和外部引用內在都是使用 malloc 動態分配,因此希望在需要釋放時可以正常釋放。
實例 3
第三個實例實現,始終是用 malloc 為函數返回的 XLOPER12數據類型, 動態分配字符串,外部引用和數組,并且 XLOPER12 自身也是動態分配的。函數返回的動態分配 XLOPER12 類型是確保函數線程安全性的唯一方法。
// // BEGIN EXAMPLE IMPLEMENTATION 1 //LPXLOPER12 WINAPI fArray(void) {LPXLOPER12 pxArray;static XLOPER12 xMulti;int i;int rwcol;xMulti.xltype = xltypeMulti | xlbitDLLFree;xMulti.val.array.columns = 1;xMulti.val.array.rows = 8;// For large values of rows and columns, this would overflow// use __int64 in that case and return an error if rwcol// contains a number that won't fit in sizeof(int) bytesrwcol = xMulti.val.array.columns * xMulti.val.array.rows; pxArray = (LPXLOPER12)GlobalLock(hArray = GlobalAlloc(GMEM_ZEROINIT, rwcol * sizeof(XLOPER12)));xMulti.val.array.lparray = pxArray;for(i = 0; i < rwcol; i++) {pxArray[i].xltype = xltypeInt;pxArray[i].val.w = i;}// Word of caution - returning static XLOPERs/XLOPER12s is not thread safe // for UDFs declared as thread safe, use alternate memory allocation mechanismsreturn (LPXLOPER12)&xMulti; }void WINAPI xlAutoFree12(LPXLOPER12 pxFree) {GlobalUnlock(hArray);GlobalFree(hArray);return; }// // BEGIN EXAMPLE IMPLEMENTATION 2 // void WINAPI xlAutoFree12(LPXLOPER12 pxFree) {if(pxFree->xltype & xltypeMulti){ /* Assume all string elements were allocated using malloc, and ** need to be freed using free. Then free the array itself. */int size = pxFree->val.array.rows *pxFree->val.array.columns;LPXLOPER12 p = pxFree->val.array.lparray;for(; size-- > 0; p++) // check elements for stringsif(p->xltype == xltypeStr)free(p->val.str);free(pxFree->val.array.lparray);}else if(pxFree->xltype & xltypeStr){free(pxFree->val.str);}else if(pxFree->xltype & xltypeRef){free(pxFree->val.mref.lpmref);} }// // BEGIN EXAMPLE IMPLEMENTATION 3 // LPXLOPER12 WINAPI example_xll_function(LPXLOPER12 pxArg) { // Thread-safe return value. Every invocation of this function // gets its own piece of memory.LPXLOPER12 pxRtnValue = (LPXLOPER12)malloc(sizeof(XLOPER12));// Initialize to a safe defaultpxRtnValue->xltype = xltypeNil;// Set the value of pxRtnValue making sure that strings, external // references, arrays, and strings within arrays are all dynamically // allocated using malloc. // (code omitted) // ...// Set xlbitDLLFree regardless of the type of the return value to // ensure xlAutoFree12 is called and pxRtnValue is freed.pxRtnValue->xltype |= xlbitDLLFree;return pxRtnValue; }void WINAPI xlAutoFree12(LPXLOPER pxFree) {if(pxFree->xltype & xltypeMulti){ // Assume all string elements were allocated using malloc, and // need to be freed using free. Then free the array itself.int size = pxFree->val.array.rows *pxFree->val.array.columns;LPXLOPER12 p = pxFree->val.array.lparray;for(; size-- > 0; p++) // check elements for stringsif(p->xltype == xltypeStr)free(p->val.str);free(pxFree->val.array.lparray);}else if(pxFree->xltype & xltypeStr){free(pxFree->val.str);}else if(pxFree->xltype & xltypeRef){free(pxFree->val.mref.lpmref);} // Assume pxFree was itself dynamically allocated using malloc.free(pxFree); }xlAutoOpen
每個有效的 XLL 必需輸出和實現此函數。 xlAutoOpen 函數是注冊 XLL 函數和命令的推薦方法,它還常用于 初始化數據結構,自定義用戶界面等等。
函數原型
int WINAPI xlAutoOpen ( void );參數
這個函數沒帶任何參數。
屬性值 / 返回值
實現此函數時,必需返回 1 ( int )。
備注
Excel 會在 XLL 被激活后調用此函數。XLL 會在以下幾種情形下被激活。
- 如果在上一次 Excel 正常關閉時,激活了某個 XLL。那么在 Excel 啟動時,會再次激活。
- 在 Excel 運行過程中載入 XLL。
- XLL 可以使用下面幾種方法載入:
- 使用文件中的打開菜單打開XLL(Excel 2007 支持使用此方法載入 XLL )
- 使用 Add-In 管理器
- 從其它的XLL調用 xlfRegister,使用 DLL 名稱作為唯一的參數。
- 從 XLM 宏表,調用 REGISTER,使用 DLL 名稱作為唯一的參數。
- 如果 add-in 是去激活的,并在 Excel 運行期間重新激活,此函數會再次被調用。
實例
查看文件 SAMPLES\EXAMPLE\EXAMPLE.C, SAMPLES\GENERIC\GENERIC.C, 和 SAMPLES\STOCK\STOCK.CPP 中的此函數實現實例。
xlAutoRegister/xlAutoRegister12
任何時候調用 XLM 函數 REGISTER 或 C API 等效函數 xlfRegister 函數,都會調用 xlAutoRegister 函數。其函數返回的數據類型和參數被登記為缺失。它允許 XLL 查找它的輸出的函數和命令列表,注冊指定的函數的參數和返回數據類型。
如果 XLL 同時輸出了這兩個函數,Excel 會優先調用 xlAutoRegister12
Excel 不強制要求 XLL 實現和輸出這些函數。
如果 xlAutoRegister / xlAutoRegister12 嘗試在沒有提供參數和返回值的情況下注冊函數。就會發生 遞歸循環調用,最終造成調用堆棧溢出 Excel 發生崩潰。
函數原型
LPXLOPER12 WINAPI xlAutoRegister12(LPXLOPER12 pxName); LPXLOPER WINAPI xlAutoRegister(LPXLOPER pxName);參數
pxName (xltypeStr)
被注冊的 XLL 函數的名稱。
屬性值 / 返回值
這個函數應該返回 打算使用 xlfRegister函數 注冊的 XLL 函數的 pxName 的注冊結果,如果指定的函數不在 XLL 的輸出函數列表中,它將返回一個 #VLAUE! 錯誤,或 NULL (由Excel解釋 #VALUE 時獲取)
備注
你的 xlAutoRegister 將根據傳入的名稱執行一個區分大小寫的查詢,查找 XLL 輸出的函數和命令列表,如果函數或命令被找到,xlAutoRegister 將試圖使用 xlfRegister 函數注冊它,確保 函數的參數和返回支持 string 類型,以及其它關于函數的必要信息。在 調用 xlfRegister 返回后,這些信息將返回給 Excel。 如果函數注冊成功,xlfRegister 返回 一個xltypeNum 值,其內部包含了 函數的注冊ID。
實例
在文件 SAMPLES\EXAMPLE\EXAMPLE.C 查看此函數的實現實例。
xlAutoRemove
任何時候,用戶在 Excel 運行期間,使用 Add-In 管理器去激活 XLL,都會調用此函數。這個函數,不會在 Excel 關閉時 add-in 正常或異常安裝時被調用。
這個函數可以用于顯示用戶自定義對話框,告訴用戶這個 add-in 已經被 去激活,或是讀取和設置注冊表信息。
Excel 不強制要求 XLL 實現和輸出這個函數。
函數原型
int WINAPI xlAutoRemove(void);參數
此函數沒有帶有參數
屬性值 / 返回值
實現這個函數時,必需返回 1 ( int )。
備注
當你希望在完成任何任務后,從 Add-In 管理器中刪除這個 XLL,就可以使用此函數。
實例
參考文件 \SAMPLES\EXAMPLE\EXAMPLE.C 和 \SAMPLES\GENERIC\GENERIC.C 中的函數實現. 下面的代碼來自于 \SAMPLES\EXAMPLE\EXAMPLE.C.
int WINAPI xlAutoRemove(void) { /* Display a dialog box indicating that the XLL was successfully removed */Excel12f(xlcAlert, 0, 2,TempStr12(L"Thank you for removing Example.XLL!"),TempInt12(2));return 1; }轉載于:https://www.cnblogs.com/boluoke/p/5841205.html
總結
以上是生活随笔為你收集整理的【XLL 文档翻译】【第1部分】 Add-in 管理器 和 XLL 接口函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c/c++小知识
- 下一篇: could not find the m