1.創建ObjectArx應用程序
ObjectARX 應用程序是一個 DLL,它共享 AutoCAD 的地址空間並對 AutoCAD 進行直接函數調用。ObjectARX 應用程序通常實現可從 AutoCAD 內部訪問的命令。這些命令通常使用自定義類實現。創建 ObjectARX 應用程序涉及以下常規步驟。
1.1創建對象 ARX 應用程序
- 創建自定義類以實現新命令。 您可以從大多數 ObjectARX 層次結構和符號表類派生自定義類。
- 確定 ObjectARX 應用程序將處理哪些 AutoCAD 消息。 AutoCAD 向 ObjectARX 應用程序發送各種消息,指示 AutoCAD 中發生了特定事件。您可以決定應用程序將響應哪些消息,以及將觸發哪些操作。
- 實現 AutoCAD 的入口點。 AutoCAD 通過函數調用 ObjectARX 應用程序,該函數取代了C++程序的功能。您負責在應用程序中實現該函數。該函數調用已與特定 AutoCAD 消息關聯的函數。acrxEntryPoint()main()acrxEntryPoint()acrxEntryPoint()
- 實現初始化。 在 ObjectARX 應用程序中,需要初始化已創建的任何自定義類,並重新生成 ObjectARX 運行時類樹。此外,如果要添加命令,則必須向 AutoCAD 註冊這些命令。
- 準備卸貨。 要創建運行良好的 ObjectARX 應用程序,必須在卸載應用程序時刪除所有自定義類和命令。
1.2響應 AutoCAD 消息
AutoCAD 向 ObjectARX 應用程序發送的消息有四類:
- 發送到所有應用程序的消息
- 僅當應用程序已向 AutoLISP®函數註冊時才發送的消息acedDefun()
- 發送到已向 ObjectARX 註冊服務的應用程序的消息
- 僅由使用 ActiveX 自動化的應用程序響應的消息(僅限 Windows)
1.2.1ObjectARX 應用程序對 AutoCAD 消息的反應
|
消息
|
建議的操作
|
|
kInitAppMsg |
註冊服務、類、AcEd 命令和反應器以及 AcRxDynamicLinker 反應器。初始化應用程序的系統資源,例如設備和窗口。執行所有一次性早期初始化。AcRx,AcEd和AcGe都是活躍的。如果要解鎖和重新鎖定應用程序,請存儲 pkt 參數的值。 不要期望初始化設備驅動程序、激活任何用户界面資源、按特定順序加載應用程序、存在 AutoLISP 或打開任何數據庫。涉及任何這些假設的調用都將導致錯誤情況,有時甚至是致命的。AcDb 和 AcGi 文庫通常尚未激活,儘管相關的 AcRx 和其他結構已經到位。 |
|
kUnloadAppMsg |
執行最終的系統資源清理。在 kInitAppMsg 中啓動或創建的任何內容現在都應該停止或銷燬。 不要指望事情與kInitAppMsg的描述有任何不同。在進行此調用時,AutoCAD 大部分可以拆除,除了在 kInitAppMsg Do 描述中列為活動的庫。 |
|
kOleUnloadAppMsg |
此消息應僅由在 Windows 上使用 ActiveX 自動化的應用程序響應。 如果應用程序可以卸載,請使用 AcRx::kRetOK 進行響應(其他應用程序未引用其任何 ActiveX 對象或接口)。如果無法卸載,請使用 AcRx::kRetError 進行響應。 |
|
kLoadDwgMsg |
執行與當前圖形編輯會話相關的初始化。AcDb、AcGi 和用户界面 API 現在都處於活動狀態。未指定是否對圖形執行了任何操作。所有 AutoCAD 提供的 API 現在都處於活動狀態。此時可以執行 AutoLISP 函數註冊,並初始化用户界面。現在要執行的其他操作包括輪詢 AutoCAD 驅動程序和查詢 AcEditorReactor 事件(如果您希望儘早訪問 )。acdbHostApplicationServices()->workingDatabase() 不要對每個圖形編輯會話執行不希望發生的任何操作。假設每次程序執行多次發送此消息。 |
|
kUnloadDwgMsg |
發佈或清理為響應 kLoadDwgMsg 代碼而啓動或註冊的所有內容。釋放所有AcDb反應器,不包括持久性反應器。 不要釋放未綁定到編輯會話的系統資源,也不要清理 AcRx 類、AcEd 反應器或命令;它們在編輯會話中保持有效。 |
|
kDependencyMsg |
當其他應用程序依賴於應用程序時,請執行應用程序所需的任何操作,例如鎖定應用程序,使其無法卸載。 |
|
kNoDependencyMsg |
當不再有任何其他應用程序依賴於您的應用程序時,請執行應用程序所需的任何操作,例如解鎖應用程序,以便用户可以根據需要卸載它。 |
|
kInvkSubrMsg |
調用在 中註冊的函數。通過調用 來確定函數。使用 aceedRetxxx() 返回值。acedDefun()acedGetFuncode() 除了函數調用之外,這裏不做太多事情。 |
|
kPreQuitMsg |
卸載應用程序控制的任何依賴項(應用程序、DLL 等),以確保在應用程序之前卸載這些依賴項。 |
|
kEndMsg kCfgMsg kQuitMsg kSaveMsg |
請考慮使用 AcEditorReactor 事件回調作為響應這些消息的替代方法。 如果要響應通過 AcEditorReactor 進行的等效事件回調,請不要響應這些消息。 |
1.3ObjectARX 應用程序中的事件序列
在 AutoCAD 和 ObjectARX 應用程序之間傳遞消息的過程幾乎完全是在一個方向上流動的 — 從 AutoCAD 到 ObjectARX 應用程序。下圖顯示了傳遞消息的典型順序。
如果在圖形已打開時加載應用程序,則會連續發送 和 消息。如果在編輯會話正在進行時卸載 ObjectARX 應用程序,則會連續發送 和 消息。kInitAppMsgkLoadDwgMsgkUnloadDwgkUnloadApp
1.4實現 AutoCAD 的入口點
AutoCAD 通過 調用 ObjectARX 模塊,該模塊取代了C++程序的功能。您負責實現該函數,如本節所述。acrxEntryPoint()main()acrxEntryPoint()
該函數充當 AutoCAD(或其他主機程序)與 ObjectARX 應用程序通信的入口點。ObjectARX 程序可以通過返回狀態代碼與 AutoCAD 進行通信。調用 定義 的函數的所有請求都由函數發出。如果使用 ObjectARX 或函數定義新命令,AutoCAD 將立即執行與該命令關聯的函數(請參見加載 ObjectARX 應用程序)。acrxEntryPoint()acedDefun()acrxEntryPoint()acedRegFunc()
該函數具有以下簽名: acrxEntryPoint()
extern "C"
AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt);
.msg
表示從 ObjectARX 內核發送到應用程序的消息。
PKT
保存數據包數據值。
應用代碼
包含返回到 AutoCAD 的狀態代碼。
在函數的定義中,您可以編寫 switch 語句或類似代碼來解密來自 AutoCAD 的消息,執行與每條消息相關的相應操作,並返回整數狀態值。acrxEntryPoint()
危險:用於函數的最終返回值將導致應用程序被卸載,但消息和 .在這些情況下,如果返回,則不會卸載應用程序。kRetErroracrxEntryPoint()kOleUnloadAppMsgkUnloadAppMsgkRetError
以下代碼顯示了有效 switch 語句的框架:
extern "C"
AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch(msg) {
case AcRx::kInitAppMsg:
break;
case AcRx::kUnloadAppMsg:
break;
...
default:
break;
}
return AcRx::kRetOK;
}
1.5初始化對象ARX 應用程序
必須初始化應用程序定義的任何自定義類和命令。此初始化可以在函數的情況下進行,也可以在從該函數調用的函數中進行。AcRx::kInitAppMsgacrxEntryPoint()
初始化對象ARX 應用程序
- 如果已定義自定義類,請調用其函數。rxInit() 定義自定義類在“派生自定義 ObjectARX 類”中進行了詳細討論。
- 如果已定義自定義類,請調用以重新生成 ObjectARX 運行時類樹。acrxBuildClassHierarchy() 為了提高效率,請在為每個自定義類調用函數後調用一次。acrxBuildClassHierarchy()rxinit()
- 執行所需的任何其他初始化。
- 註冊服務名稱。 如果其他應用程序將依賴於您的應用程序,則建議註冊服務名稱。註冊服務名稱允許其他應用程序根據服務進行註冊,並允許應用程序在卸載之前檢查它是否有任何依賴項。如果要使用 ObjectARX 機制從應用程序導出符號函數,則還需要為應用程序註冊服務名稱。您可以使用函數 ,也可以使用類。有關注冊服務的更多信息,請參閲 ObjectARX 參考中的“AcRxService”。acrxRegisterService()AcRxService
- 使用 AutoCAD 命令機制註冊命令。 用於使 AutoCAD 知道應用程序定義的命令。更多信息請參閲“註冊新命令”。acedRegCmds->addCommand()
1.6準備卸載
卸載應用程序時,必須清理應用程序創建的任何自定義類或命令。這應該發生在您的函數的情況下,或者在從該情況下調用的函數中發生。AcRx::kUnloadAppMsgacrxEntryPoint()
卸載對象 ARX 應用程序
- 如果已使用宏 或 創建了命令,請將其刪除。acedRegCmdsacedDefun()通常,使用 .acedRegCmds->removeGroup()
- 如果已創建自定義類,請將其刪除。使用該函數從 AcRx 運行時樹中刪除自定義類。必須首先從派生類的葉子開始刪除類,然後從類樹到父類。deleteAcRxClass()
- 刪除應用程序添加的任何對象。無法告訴 AutoCAD 忘記當前駐留在數據庫中的實例。但是,卸載應用程序時,AutoCAD 會自動將此類對象轉換為 或 的實例。AcDbObjectAcDbProxyObjectAcDbProxyEntity
- 移除已連接到任何 、、 或對象的所有反應器。(持久反應器是一個例外;當應用程序卸載時,它們將成為代理對象。AcDbObjectAcDbDatabaseAcRxDynamicLinkerAcEditorAcDbObjects
- 如果已創建服務名稱,請將其刪除。可以使用該函數刪除應用程序已註冊的任何服務。請參閲 ObjectARX 參考中的列表。acrxServiceDictionary->remove()acrxServiceDictionary
1.7示例應用程序
下面的示例應用程序實現在加載和卸載應用程序時調用的函數。它的初始化功能向AutoCAD添加了兩個新命令:CREATE和ITERATE。
它還初始化新類,並使用函數將其添加到 ObjectARX 層次結構中。
// The initialization function called from the acrxEntryPoint()
// function during the kInitAppMsg case is used to add commands
// to the command stack and to add classes to the ACRX class
// hierarchy.
//
void
initApp()
{
acedRegCmds->addCommand("ASDK_DICTIONARY_COMMANDS",
"ASDK_CREATE", "CREATE", ACRX_CMD_MODAL,
createDictionary);
acedRegCmds->addCommand("ASDK_DICTIONARY_COMMANDS",
"ASDK_ITERATE", "ITERATE", ACRX_CMD_MODAL,
iterateDictionary);
AsdkMyClass::rxInit();
acrxBuildClassHierarchy();
}
// The cleanup function called from the acrxEntryPoint()
// function during the kUnloadAppMsg case removes this application's
// command set from the command stack and removes this application's
// custom classes from the ACRX runtime class hierarchy.
//
void
unloadApp()
{
acedRegCmds->removeGroup("ASDK_DICTIONARY_COMMANDS");
// Remove the AsdkMyClass class from the ACRX runtime
// class hierarchy. If this is done while the database is
// still active, it should cause all objects of class
// AsdkMyClass to be turned into proxies.
//
deleteAcRxClass(AsdkMyClass::desc());
}
2.註冊新命令
2.1命令堆棧
AutoCAD 命令存儲在命令堆棧中的組中,該命令堆棧由類定義。每個 AutoCAD 會話將創建一個命令堆棧實例。此堆棧由您定義的自定義命令組成。該宏允許您訪問命令堆棧。AcEdCommandStackacedRegCmds()
添加命令時,還會為其分配組名。一個好的策略是使用已註冊的開發人員前綴作為組名稱,以避免與其他命令發生名稱衝突。給定組中的命令名稱必須是唯一的,並且組名稱必須是唯一的。但是,多個應用程序可以添加同名的命令,因為組名使命令明確。
通常使用該函數一次添加一個命令,並按函數組刪除命令。您還可以使用該函數一次刪除一個命令。作為退出前清理的一部分,應用程序需要刪除它註冊的任何命令。AcEdCommandStack::addCommand()removeGroup()removeCmd()
函數的簽名為addCommand()
Acad::ErrorStatus
addCommand(
const char* cmdGroupName,
const char* cmdGlobalName,
const char* cmdLocalName,
Adesk::Int32 commandFlags,
AcRxFunctionPtr functionAddr,
AcEdUIContext *UIContext = NULL,
int fcode=-1,
HINSTANCE hResourceHandle = NULL,
AcEdCommand** cmdPtrRet = NULL);
cmd組名稱
要向其添加命令的組的 ASCII 表示形式。如果該組不存在,則會在添加命令之前創建該組。
cmd全局名稱
要添加的命令名稱的 ASCII 表示形式。此名稱表示全局或未翻譯的名稱(請參閲“全局與本地命令名稱”)。
cmd本地名稱
要添加的命令名稱的 ASCII 表示形式。此名稱表示本地名稱或翻譯名稱。
命令標誌
與命令關聯的標誌。可能的值包括ACRX_CMD_TRANSPARENT、ACRX_CMD_MODAL、ACRX_CMD_USEPICKSET和ACRX_CMD_REDRAW(請參閲“透明命令與模式命令”)。
函數地址
AutoCAD 調用此命令時要執行的函數的地址。
UiContext
指向回調類的輸入指針。AcEdUIContext
fcode
輸入分配給命令的整數代碼。
hResourceHandle
執行命令時要設為當前狀態的輸入資源句柄
cmdPtrRet
輸入指針指向要填充的 AcEdCommand 對象的地址的指針,用於添加命令
注意:建議以前綴開頭所有組和命令名稱,以避免與其他加載的應用程序發生可能的命名衝突。您選擇的前綴可能是公司名稱的縮寫或其他短名稱,有助於將應用程序註冊的組和命令與其他應用程序註冊的組和命令唯一標識。例如,可以將 ADSK 的前綴添加到 MOVE 命令的版本中,從而生成 ASDKMOVE 的最終名稱。
2.2查找順序
調用命令時,將按組名稱搜索命令堆棧,然後按組中的命令名稱搜索。通常,註冊的第一個組將是第一個搜索的組,但您無法始終預測此順序。使用該函數指定應首先搜索特定組。在用户級別,ARX 命令的“組”選項允許用户指定首先搜索哪個組。AcEdCommandStack::popGroupToTop()
2.3全局命令名稱與本地命令名稱
將命令添加到 AutoCAD 時,需要指定可用於任何語言的全局名稱,以及本地化名稱(即要在外語版本的 AutoCAD 中使用的命令名稱的翻譯版本)。如果不需要將命令名稱轉換為本地語言,則可以對全局名稱和本地名稱使用相同的名稱。
2.4透明命令與模式命令
命令可以是透明的,也可以是模式的。當提示用户輸入時,可以調用透明命令。僅當 AutoCAD 正在發佈命令提示符且當前沒有其他命令或程序處於活動狀態時,才能調用模式命令。函數的參數指定新命令是模式 (ACRX_CMD_MODAL) 還是透明 (ACRX_CMD_TRANSPARENT)。該參數還指定命令的其他選項。請參閲對象ARX參考。透明命令只能嵌套一個級別(即調用主命令,主命令調用一個透明命令)。commandFlagsAcEdCommandStack::addCommand()commandFlagsAcEdCommandStack
如果創建多個對一組通用全局對象進行操作的命令,請考慮是否應使它們成為模式,以便它們不會相互干擾。如果此類衝突不是問題,則使新命令透明化會導致更大的使用靈活性。
3加載ObjectArx應用程序
您可以使用以下任一方法加載 ObjectARX 應用程序:
- 為應用程序提供允許其由 AutoCAD 按需加載的功能。這些功能包括 Windows 系統註冊表中特定於應用程序的條目。請參閲需求加載。
- 在初始模塊文件 acad.rx 中指定應用程序。此文件包含 ASCII 文本,其中包含 AutoCAD 在啓動時應加載的所有程序的名稱。文件中的每一行都包含一個程序名稱(如果文件不在 AutoCAD 庫搜索路徑的目錄中,則包含路徑)。acad.rx 文件還必須位於 AutoCAD 搜索路徑上的目錄中。
- 使用 從另一個 ObjectARX 應用程序發出應用程序加載請求。AcRxDynamicLinker::loadModule()
- 使用 APPLOAD 命令。
- 創建一個捆綁包並將其部署到應用程序插件文件夾。請參閲應用程序自動加載。
- 使用 AutoLISP 中的函數。arxload()
- 使用 ObjectARX 中的函數。acedArxLoad()
- 在 AutoCAD 命令行上輸入 ARX 命令,然後使用“加載”選項。
- 從 DOS 命令行啓動 AutoCAD,使用 或 開關,後跟 ObjectARX 應用程序或對象啓用程序的路徑和文件名。例如:/ld-ld
4卸載ObjectArx應用程序
您可以使用以下任一方法卸載 ObjectARX 應用程序(如果它已解鎖):
- 使用 從另一個 ObjectARX 應用程序發出應用程序卸載請求。AcRxDynamicLinker::unloadModule()
- 使用 APPLOAD 命令。這將打開一個對話框,允許您加載和卸載應用程序。
- 從應用程序插件文件夾中刪除捆綁包。請參閲應用程序自動加載。
- 使用 AutoLISP 中的函數。arxunload
- 使用 ObjectARX 中的函數。acedArxUnload()
- 在 AutoCAD 命令行上輸入 ARX 命令,然後使用“卸載”選項。
4.1解鎖應用程序
默認情況下,應用程序處於鎖定狀態,無法卸載。要歸類為“不可加載”應用程序,應用程序必須確保 AutoCAD 和其他應用程序不再引用應用程序已定義的任何對象或結構。在使應用程序不可加載之前,請非常小心,不要讓客户端應用程序包含指向地址空間中任何對象的活動指針。有關應用程序必須執行才能卸載的清理操作的列表,請參閲準備卸載。
如果要使應用程序不可加載,則需要存儲與 .該參數將由函數使用。默認情況下,應用程序處於鎖定狀態。如果解鎖應用程序,則可以將其卸載。pktAcRx::kInitAppMsgpktunlockApplication()
使用以下兩個函數鎖定和解鎖應用程序:
virtual bool
AcRxDynamicLinker::lockApplication(void* pkt) const = 0;
virtual bool
AcRxDynamicLinker::unlockApplication(void* pkt) const = 0;
以下函數檢查應用程序是否已鎖定:
virtual bool
AcRxDynamicLinker::isApplicationLocked(const char* name) const = 0;
還提供了類似的全局函數:
bool
acrxLockApplication(void* pkt);
bool
acrxUnlockApplication(void* pkt);
bool
acrxApplicationIsLocked(const char* modulename);
5.應用程序自動加載
ObjectARX 應用程序可以使用包格式作為插件的一部分加載,包格式是擴展名為 .bundle 的常見文件夾結構。每個包都可以包含部署應用程序和註冊應用程序中包含的命令所需的文件。通過將包放置在本地驅動器上的某個應用程序插件文件夾中,將包加載到 AutoCAD 中。
APPAUTOLOAD 系統變量控制 AutoCAD 何時從“應用程序插件”文件夾中查找和加載插件。如果 APPAUTOLOAD 設置為 0,則可以使用 APPAUTOLOADER 命令加載插件。
有關使用軟件包格式部署應用程序的信息,請參閲《定製指南》中的“安裝和卸載插件應用程序”。
6.按需加載
按需加載是 AutoCAD 的一項功能,它會自動嘗試加載不駐留在 AutoCAD 中的 ObjectARX 應用程序。可以將 ObjectARX 應用程序設計為在以下一種或多種情況下由 AutoCAD 加載:
- 讀取包含由不存在的應用程序創建的自定義對象的圖形文件時
- 當用户或其他應用程序發出缺少的應用程序的命令之一時
- 啓動AutoCAD時
注意:在 AutoCAD 啓動時實現需求加載的應用程序將在 acad.rx 中列出的應用程序之前加載。
Autodesk 建議開發利用 AutoCAD 按需加載功能的 ObjectARX 應用程序,因為需求加載具有以下優點:
- 限制代理對象的創建(請參閲代理對象)
- 為加載 ObjectARX 應用程序提供了更大的靈活性
- 通過僅在需要應用程序功能時才加載應用程序來節省內存
要使應用程序可供按需加載訪問,Windows 系統註冊表中必須存在特定於應用程序的信息。此外,具有多個 DLL 的 ObjectARX 應用程序可能需要一個“控制器”模塊,該模塊負責加載應用程序的所有其他組件。最後,必須將 DEMANDLOAD 系統變量設置為需求加載的適當值。
注意:
可以從本地計算機上的路徑或使用因特網地址按需加載 ObjectARX 應用程序。
6.1AutoCAD、Windows System Registry 和 ObjectARX 應用程序
AutoCAD 使用 Windows 系統註冊表來維護各種應用程序信息,包括唯一標識可能安裝在任何給定計算機上的不同 AutoCAD 版本、語言版本和產品(如 AutoCAD 地圖)的信息。標識不同版本的 AutoCAD 的註冊表信息對於 ObjectARX 開發人員具有特別重要的意義。ObjectARX 應用程序的安裝程序必須將有關該應用程序的信息與有關應運行該應用程序的 AutoCAD 版本的信息相關聯。
AutoCAD 安裝程序在系統註冊表中創建一個唯一的時間戳鍵,緊靠版本號鍵的下方(以及將相同的安裝 ID 添加到可執行文件本身)。此項可確保同一版本中不同版本的 AutoCAD 能夠填充其自己的系統註冊表部分。在此鍵中,存儲屬性的值,例如 AutoCAD 文件的位置和語言版本,如以下示例所示:
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R24.1\
ACAD-5101:409\
...
Language:REG_SZ:English
Location:REG_SZ:C:\Program Files\Autodesk\AutoCAD <release_name>
...
ObjectARX 應用程序的安裝程序必須能夠找到相應的 AutoCAD 版本密鑰,以及相應的語言和產品值。
時間戳鍵還用於標識當前加載的 AutoCAD 版本(或最近加載的版本)。此標識是必需的,因為 AutoCAD 的“當前”版本會在加載註冊表時重置註冊表全局部分中的信息以供自己使用。HKEY_CLASSES_ROOT
註冊表的發佈密鑰部分中的值用於標識當前版本,例如:CurVer
\\HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\R24.1\
CurVer:REG_SZ:ACAD-5101:409
6.2在安裝 ObjectARX 應用程序時修改註冊表
AutoCAD 使用 Windows 系統註冊表來查找 ObjectARX 應用程序以進行按需加載。註冊表的 AutoCAD 部分的一部分用於提供有關 ObjectARX 應用程序的註冊表信息位置的信息。
ObjectARX 應用程序的安裝程序必須在系統註冊表中創建需求加載所需的特定鍵和值。某些必需的項和值必須在註冊表的 AutoCAD 部分中創建,而其他項和值必須在註冊表的 ObjectARX 應用程序的部分中創建。
如果 ObjectARX 應用程序設計為與多個版本的 AutoCAD(即不同的語言版本或相關產品,如 AutoCAD 地圖)一起運行,則安裝程序必須將相應的信息添加到每個版本的 AutoCAD 的註冊表部分。
因此,ObjectARX 應用程序的安裝過程必須包括:
- 驗證相應版本的 AutoCAD 的系統註冊表部分是否存在。(如果註冊表的 AutoCAD 部分不存在,則應警告用户尚未安裝兼容版本的 AutoCAD,並且應中止安裝。
- 在相應版本的 AutoCAD 的系統註冊表部分中為應用程序創建一組特定的鍵和值。
- 為應用程序本身創建一個主鍵,並使用另一組特定鍵和值填充該鍵。
請參閲 ObjectARX SDK 的 samples\entity\polysamp\demandload 目錄,瞭解有關如何修改系統註冊表以按需加載示例程序 polysamp 的信息。
6.2.1適應 Windows 權限級別
如果當前 Windows 用户不是高級用户,則 AutoCAD 及其下運行的應用程序都無法寫入註冊表區域。為了處理這種情況,AutoCAD 支持在“和”註冊表“部分中輸入需求荷載條目。HKEY_LOCAL_MACHINEHKEY_LOCAL_MACHINEHKEY_CURRENT_USER
對於需求加載,AutoCAD 首先在 下查找條目。如果在那裏找到必要的條目,則使用它們。如果在 下找不到這些條目,AutoCAD 將在 下查找。HKEY_CURRENT_USERHKEY_CURRENT_USERHKEY_LOCAL_MACHINE
ObjectDBX 還遵循本節中介紹的 AutoCAD 註冊表搜索規則。
ObjectARX 提供的 API 可簡化寫入註冊表正確區域的過程。有關這些 API 的更多信息,請參閲使用 ObjectARX API 簡化註冊表設置。
6.2.2創建 AutoCAD 子項和值
創建 AutoCAD 子項和值
必須將 ObjectARX 應用程序的安裝程序設計為在要運行該應用程序的每個版本的 AutoCAD 的系統註冊表部分中管理該應用程序的一組鍵和值。註冊表的此部分必須包括標識應用程序主模塊和應用程序的命令集的鍵和值。
下面的示例演示必須為應用程序創建和維護的註冊表部分中的項和值的佈局:
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\releaseNum\
ACAD-ProductID:LocaleID\
Applications\
ApplicationName\
DESCRIPTION:REG_SZ:User Friendly App Name
LOADCTRLS:REG_DWORD:acrxAppLoadReason
LOADER:REG_SZ:DirPathFileName
Commands\
GlobalCommandName1:REG_SZ:LocalCommandName1
GlobalCommandName2:REG_SZ:LocalCommandName2
GlobalCommandName3:REG_SZ:LocalCommandName3
GlobalCommandName4:REG_SZ:LocalCommandName4
GlobalCommandName5:REG_SZ:LocalCommandName5
Groups\
GroupName:REG_SZ:GroupName
...
和 鍵由 AutoCAD 安裝程序創建。releaseNumACAD-ProductID:LocaleID
密鑰必須是應用程序的邏輯名稱,AutoCAD 在內部使用該名稱來標識程序。ApplicationName
鍵中的值必須包括 AutoCAD 應首先加載的模塊的完整路徑和文件名。加載程序模塊隨後負責加載組成應用程序的任何其他模塊。LOADER
該值使用下列十六進制值的一個或多個邏輯 OR 及其關聯含義來定義加載應用程序的條件:acrxAppLoadReason
0x01
檢測到代理對象時加載應用程序。
0x02
在 AutoCAD 啓動時加載應用程序。
0x04
在調用命令時加載應用程序。
0x08
根據用户或其他應用程序的請求加載應用程序。
0x10
不要加載應用程序。
0x20
透明地加載應用程序。
鍵中的值可用於唯一標識 ObjectARX 應用程序的命令組,從而也用於標識命令。Groups
全局函數可以在 ObjectARX 應用程序中用於將有關應用程序的信息輸入到系統註冊表的 AutoCAD 部分中。通常, 會在首次加載應用程序時輸入此信息,並在後續加載中確認該信息是否存在。acrxRegisterApp()acrxRegisterApp()
7.需求負載系統變量
AutoCAD DEMANDLOAD 系統變量控制 ObjectARX 應用程序的需求加載選項。
默認情況下,設置 DEMANDLOAD 系統變量(安裝 AutoCAD 時)以在命令調用或代理檢測時啓用應用程序的需求加載,前提是在應用程序的系統註冊表項中指定了任一選項。當系統註冊表中指定了這些選項中的任何一個時,DEMANDLOAD 的設置不會影響 AutoCAD 啓動時的需求加載,也不會影響用户或應用程序的請求。(請參見創建 AutoCAD 子項和值)。
系統變量的合法值可以組合使用。它們定義如下:
0
禁用所有 ObjectARX 應用程序的需求加載。
1
允許在檢測到代理對象時按需加載 ObjectARX 應用程序。
2
允許在命令調用時按需加載 ObjectARX 應用程序。
3
為代理對象和命令調用啓用需求加載(默認值)。
DEMANDLOAD 系統變量允許用户禁用所有 ObjectARX 應用程序的需求加載,這些應用程序具有指定命令調用和代理檢測時需求加載的系統註冊表設置。如果相應的系統註冊表設置不存在,則它不會導致應用程序被需求加載。
8.檢測自定義對象時的需求加載
加載包含自定義對象的 DWG 或 DXF 文件時,AutoCAD 將確定是否加載關聯的應用程序。如果未加載應用程序,並且設置了系統變量 DEMANDLOAD 的第一個位,AutoCAD 將在 Windows 系統註冊表中搜索有關應用程序及其加載程序模塊的信息。如果 AutoCAD 在系統註冊表中找到相應的信息,則會加載應用程序。
注意:檢測自定義類時的需求加載僅適用於直接或間接派生自 的類。AcDbObject
作為一個假設的例子,假設AutoCAD讀取由ObjectARX應用程序polysamp(PolySamp Inc.的產品)創建的文件。
- 讀取圖形文件時,AutoCAD 會遇到使用應用程序多邊形創建的自定義對象,並確定應用程序未加載。
- AutoCAD 發現 DEMANDLOAD 系統變量設置為在代理檢測時啓用應用程序的需求加載,因此它會在系統註冊表的“AutoCAD 應用程序”部分中搜索密鑰。在此鍵中,它查找值,該值定義應加載應用程序的條件。註冊表的此部分如下所示:polysampLOADCTRLS
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\ObjectDBX\<VERSION>\Applications\<Application>
DESCRIPTION:REG_SZ:PolyCad
LOADCTRLS:REG_DWORD:0xd
LOADER:REG_SZ:C:\Program Files\polysampinc\polyui.dbx
AutoCAD reads the polysamp\LOADER key to determine the directory, path, and file name of the module to be loaded.
然後,AutoCAD 嘗試加載 ObjectARX 模塊。如果模塊成功加載,AutoCAD 會將應用程序的句柄添加到要發送 kLoadDwgMsg 消息的應用程序句柄列表中。然後,AutoCAD 驗證應用程序是否已正確加載,並驗證自定義類是否已註冊。如果應用程序已成功加載,AutoCAD 將繼續加載圖形文件。如果無法加載 ObjectARX 模塊,或者仍然沒有可用的類實現,則自定義對象將被視為代理並繼續加載。
9.根據命令按需加載
如果用户調用的命令未註冊到 AutoCAD,AutoCAD 將嘗試加載相應的 ObjectARX 應用程序。
為了支持命令調用時的需求加載,ObjectARX 應用程序的安裝程序必須在系統註冊表中為應用程序的命令創建適當的鍵和值。系統註冊表的應用程序部分應包含如下命令信息:Commands
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R24.1\
ACAD-5101:409\
Applications\polysamp\
DESCRIPTION:REG_SZ:PolyCad
LOADCTRLS:REG_DWORD:0xd
LOADER:REG_SZ:C:\Program Files\polysampinc\polyui.arx
Commands\
ASDKPOLY:REG_SZ:ASDKPOLY
ASDKDRAGPOLY:REG_SZ:ASDKDRAGPOLY
ASDKPOLYEDIT:REG_SZ:ASDKPOLYEDIT
Groups\
ASDK:REG_SZ:ASDK
...
注意:使用組前綴調用命令也會消除命令的歧義。換句話説,GROUP_NAME。COMMAND_NAME將要求加載與指定命令組關聯的命令。
ObjectARX 應用程序還必須包括對宏的相應調用,以便命令時按需加載才能正常工作。acedRegCmds
10.AutoCAD 啓動時的需求加載
可以通過對系統註冊表中的值使用(也可以使用另一個合法值執行 OR)來指定 AutoCAD 啓動時 ObjectARX 應用程序的需求加載,如下所示。0x020x02LOADCTRLS
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R24.1\
ACAD-5101:409\
Applications\PolyCAD\
LOADCTRLS:REG_DWORD:0x02
11.上下文菜單調用時的需求加載
如果應用程序定義了自定義對象上下文菜單,則可以提供註冊表設置,以確保在用户右鍵單擊其中一個對象時加載所需的模塊。為此,請向註冊表部分添加一個項。在高級用户的計算機上,配置單元顯示在以下注冊表位置:ContextHandlersContextHandlers
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R24.1\
ACAD-5101:409\
ContextHandlers
鍵的名稱應為自定義對象類名。鍵的值應該是需要加載的應用程序的邏輯名稱的逗號分隔列表。這些邏輯名稱必須與註冊表配置單元中存在的項匹配,如創建 AutoCAD 子項和值中所述。ApplicationNameApplications
以下示例説明了對象的鍵:ContextHandlerAcDbTable
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R24.1\
ACAD-5101:409\
ContextHandlers\
AcDbTable:REG_SZ:AcadTable,AcSmSheetList
當用户右鍵單擊對象時,此鍵可保證與邏輯名稱關聯的模塊被加載。AcDbTableAcadTableAcSmSheetList
12.使用 ObjectARX API 簡化註冊表設置
ObjectARX 提供的 API 簡化了將需求加載條目寫入註冊表的任務。儘管安裝時更適合編寫初始註冊表項,但如果您需要在運行時更改需求負載信息,這些 API 可能很有用。例如,應用程序可以在安裝時寫入默認設置,然後使用這些 API 在運行時將用户特定的值寫入。HKEY_LOCAL_MACHINEHKEY_CURRENT_USER
類函數和全局函數將註冊表項寫入當前用户權限指示的位置。如果用户具有高級用户權限,則條目將寫入 下。否則,它們將寫在 下。AcadAppInfoacrxRegisterApp()HKEY_LOCAL_MACHINEHKEY_CURRENT_USER
該函數寫入需求加載所需的所有註冊表項。它提供了一個參數,該參數強制將條目寫入配置單元,即使用户在 中具有寫入權限也是如此。有關詳細信息,請參閲對象ARX參考。AcadAppInfo::writeToRegistry()HKEY_CURRENT_USERHKEY_LOCAL_MACHINEwriteToRegistry
以下方法提供了將組和命令需求負載信息寫入註冊表的功能:
- writeGroupNameToRegistry
- writeCommandNameToRegistry
全局函數是執行部分註冊表設置的單調用包裝器。您可以將此函數與您自己的對象結合使用。有關詳細文檔和重要注意事項,請參閲對象ARX 參考。acrxRegisterApp()AcadAppInfoAcadAppInfoacrxRegisterApp
12.1刪除系統註冊表信息
如果升級或刪除了應用程序,則從系統註冊表中刪除 ObjectARX 應用程序信息可能會很有用。ObjectARX API 包含函數,它是 的對應函數。它會從系統註冊表的“AutoCAD”部分中刪除有關應用程序的信息。acrxUnregisterApp()acrxRegisterApp()
13.代碼示例:編寫需求加載鍵
以下示例(來自 ObjectARX SDK polysamp 示例程序)説明了如何為註冊組和命令的 ObjectARX 應用程序編寫需求加載鍵:
void updateRegistry()
{
// Fill the AppInfo structure with our demand loading details.
AcadAppInfo appInfo;
appInfo.setAppName("AsdkPolyCAD"); // Application name
appInfo.setModuleName(acedGetAppName());// Module path
appInfo.setAppDesc("AsdkPolyCAD"); // Description
appInfo.setLoadReason(// Specify when we want these to load
AcadApp::LoadReasons(
AcadApp::kOnCommandInvocation |
AcadApp::kOnLoadRequest));
// Write the appInfo to the registry.
appInfo.writeToRegistry();
// Write the group name.
appInfo.writeGroupNameToRegistry("ASDK_POLYGON");
// Write out all our commands (Global,Local).
appInfo.writeCommandNameToRegistry("ASDK_POLY","POLY");
appInfo.writeCommandNameToRegistry("ASDK_DRAGPOLY","DRAGPOLY");
appInfo.writeCommandNameToRegistry("ASDK_POLYEDIT","POLYEDIT");
appInfo.writeCommandNameToRegistry("ASDK_TRANSACT","TRANSACT");
appInfo.writeCommandNameToRegistry("ASDK_HILITPOLY","HILITPOLY");
appInfo.writeCommandNameToRegistry("ASDK_HILITSOLID","HILITSOLID");
appInfo.writeCommandNameToRegistry("ASDK_CREATEINSERT","CREATEINSERT");
appInfo.writeCommandNameToRegistry("ASDK_HILITINSERT","HILITINSERT");
}
注意:對象啓用程序使用 ObjectARX 註冊表格式的縮寫版本。有關更多詳細信息,請參閲“對象啓用程序”中的“為需求加載註冊對象啓用程序”部分。
14.使用系統註冊表管理應用程序
為需求加載創建了系統註冊表信息後,一組 ObjectARX 函數可以使用相同的信息來加載、卸載和監視獨立於按需加載功能的 ObjectARX 應用程序是否存在。其中前兩個函數使用的參數是邏輯應用程序名稱。AppName
以下 ObjectARX 函數可用於已註冊的應用程序名稱:
bool acrxLoadApp ("AppName")
此函數採用單個參數,該參數表示要加載的應用程序的不區分大小寫的邏輯名稱。如果加載失敗,該函數返回 0,如果加載成功,則返回 1。
bool acrxUnloadApp ("AppName")
此函數採用單個參數,該參數表示以前加載的應用程序的不區分大小寫的邏輯名稱。如果卸載失敗,該函數返回 0,如果卸載成功,則返回 1。
void *acrxLoadedApps ()
此函數以 的形式返回一個字符串數組,其中包含當前加載的每個應用程序的邏輯應用程序名稱。如果未加載任何應用程序,則該函數返回 NULL。調用方負責釋放為返回的字符串分配的空間。void *