此方法使用 MFC 和 Visual C++ 从 Typelib 添加类向导来读取 AutoCAD 类型库 (acax24enu.tlb)。示例程序使用 AutoCAD 的 COM ActiveX 自动化界面在模型空间中创建圆。以下各节提供了指导您完成程序设置和实现的过程:
设置新的 MFC 项目文件
若要开始添加特定的 ObjectARX 功能,必须调整项目设置并添加样板代码。 添加对象 ARX 兼容性将适当的值添加到项目属性中,以使项目生成为 ObjectARX 程序。确保 ObjectARX\inc和 \lib目录位于项目的搜索路径中。此程序需要与以下库链接: acad.lib
acdb24.lib
rxapi.lib
在项目的定义 (DEF) 文件中,将以下行添加到“导出”部分: acrxEntryPoint PRIVATE acrxGetApiVersion PRIVATE 打开AsdkMfcComSamp.cpp源文件并添加以下代码以使程序 ObjectARX 兼容: #include <rxregsvc.h> #include <aced.h> #include <rxmfcapi.h> static void initApp() { acedRegCmds->addCommand( "ASDK_MFC_COM", "AsdkMfcComCircle", "MfcComCircle", ACRX_CMD_MODAL, addCircleThroughMfcCom); } static void unloadApp() { acedRegCmds->removeGroup("ASDK_MFC_COM"); } extern "C" AcRx::AppRetCode acrxEntryPoint (AcRx::AppMsgCode msg, void* appId) { switch(msg) { case AcRx::kInitAppMsg: acrxDynamicLinker->unlockApplication(appId); acrxDynamicLinker->registerAppMDIAware(appId); initApp(); break; case AcRx::kUnloadAppMsg: unloadApp(); break; default: break; } return AcRx::kRetOK; } 通过将以下代码添加到AsdkMfcComSamp.cpp源文件,在新的 AutoCAD 命令处理程序函数中存根: void addCircleThroughMfcCom() { } 若要在没有链接器警告的情况下生成项目,必须使 MFC 知道调试项目链接到使用发布 MFC 库生成的库。这是通过在编译器处理 MFC 头文件时仅挂起调试符号的定义来实现的。 To exclude debug MFC code from the debug build of your projectIn the generated stdafx.h file, before the first MFC include statement (usually ,add the following code: #include <afxwin.h>) #ifdef _DEBUG #undef _DEBUG #endif From the Build menu, select Build AsdkMfcComSamp to verify that your project setup is correct. Your project should build successfully, but at this point it doesn't do anything. The next step is to implement the command handler with ActiveX Automation calls. First, you must decide which interfaces are necessary. To add a new circle to model space, the , , and interfaces are required. You use the AutoCAD type library, acax24enu.tlb, to get the definitions of these interfaces, as shown in the next procedure. IAcadApplicationIAcadDocumentIAcadModelSpace To import AutoCAD ActiveX interfaces
Now that you have imported the necessary interfaces, you are ready to implement the command-handling function. To implement AutoCAD ActiveX Automation calls
CAcadApplication IApp; CAcadDocument IDoc; CAcadModelSpace IMSpace; Use the () function to obtain the MFC object for AutoCAD, and call the method: acedGetAcadWinAppCWinAppGetIDispatch IDispatch *pDisp = acedGetAcadWinApp()-> GetIDispatch(TRUE); Once you have the object, attach it to the locally defined object and make sure that AutoCAD is visible: IDispatchCAcadApplication IApp.AttachDispatch(pDisp); IApp.put_Visible(true); Obtain the active document dispatch and attach it to the locally defined object: CAcadDocument pDisp = IApp.get_ActiveDocument(); IDoc.AttachDispatch(pDisp); Query the active document for model space: pDisp = IDoc.get_ModelSpace(); IMSpace.AttachDispatch(pDisp); A circle requires a center point and radius. To make this efficient and transparent to different programming languages, the COM interface uses the type. A point is stored in a as a . Add the following code to set up a and store it in a : VARIANTVARIANTSAFEARRAYSAFEARRAYVARIANT SAFEARRAYBOUND rgsaBound; rgsaBound.lLbound = 0L; rgsaBound.cElements = 3; SAFEARRAY* pStartPoint = NULL; pStartPoint = SafeArrayCreate(VT_R8, 1, &rgsaBound); // X value // long i = 0; double value = 4.0; SafeArrayPutElement(pStartPoint, &i, &value); // Y value // i++; value = 2.0; SafeArrayPutElement(pStartPoint, &i, &value); // Z value // i++; value = 0.0; SafeArrayPutElement(pStartPoint, &i, &value); VARIANT pt1; VariantInit(&pt1); V_VT(&pt1) = VT_ARRAY | VT_R8; V_ARRAY(&pt1) = pStartPoint; Call the method from the object: AddCircleCAcadModelSpace IMSpace.AddCircle(pt1, 2.0); Here is the finished function, with clean-up code and exception handling added: void addCircleThroughMfcCom() { TRY { CAcadApplication IApp; CAcadDocument IDoc; CAcadModelSpace IMSpace; IDispatch *pDisp = acedGetAcadWinApp()-> GetIDispatch(TRUE); // AddRef is called on the // pointer IApp.AttachDispatch(pDisp); // does not call AddRef() IApp.put_Visible(true); pDisp = IApp.get_ActiveDocument(); // AddRef is called IDoc.AttachDispatch(pDisp); pDisp = IDoc.get_ModelSpace(); // AddRef is called IMSpace.AttachDispatch(pDisp); SAFEARRAYBOUND rgsaBound; rgsaBound.lLbound = 0L; rgsaBound.cElements = 3; SAFEARRAY* pStartPoint = NULL; pStartPoint = SafeArrayCreate(VT_R8, 1, &rgsaBound); // X value long i = 0; double value = 4.0; SafeArrayPutElement(pStartPoint, &i, &value); // Y value i++; value = 2.0; SafeArrayPutElement(pStartPoint, &i, &value); // Z value i++; value = 0.0; SafeArrayPutElement(pStartPoint, &i, &value); VARIANT pt1; VariantInit(&pt1); V_VT(&pt1) = VT_ARRAY | VT_R8; V_ARRAY(&pt1) = pStartPoint; IMSpace.AddCircle(pt1, 2.0); VariantClear(&pt1); // Release() is called implicitly on the local objects } CATCH(COleDispatchException,e) { e->ReportError(); e->Delete(); } END_CATCH; } 重新生成项目。 在AutoCAD中加载ARX文件,然后在命令行中输入MFCCOMCIRCLE以测试代码。 COM 程序员通常需要调用以前已调用的任何接口指针。在上面的示例中,MFC 通过内部调用其本地接口包装器对象来减轻您的此责任。但是,在使用完 COM 接口指针后,应注意需要释放它们。以下过程中演示了显式释放接口指针的技术。Release()AddRef()Release() |
|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 )
GMT+8, 2024-5-19 14:00
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.