CAD开发者社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

AutoCAD 2018 开发者帮助

使用 MFC 和“从 Typelib 添加类”向导访问 AutoCAD ActiveX Automation

2024-5-18 16:58| 发布者: admin| 查看: 12| 评论: 0|原作者: admin|来自: AutoCAD

使用 MFC 和“从 Typelib 添加类”向导访问 AutoCAD ActiveX Automation

此方法使用 MFC 和 Visual C++ 从 Typelib 向导添加类来读取 AutoCAD 类型库 (acax22enu.tlb)。示例程序使用 AutoCAD 的 COM ActiveX 自动化接口在模型空间中创建圆。以下各节提供了指导您完成程序设置和实施的过程:

设置新的 MFC 项目文件

  1. 启动 Visual C++ 并创建一个名为 AsdkMfcComSamp 的新 MFC DLL 项目。
  2. 在“应用程序设置”中,选择“MFC 扩展 DLL”。
  3. 选择“完成”以创建项目。

要开始添加特定的 ObjectARX 功能,必须调整项目设置并添加样板代码。

添加 ObjectARX 兼容性

将适当的值添加到项目属性中,以使项目生成为 ObjectARX 程序。确保 ObjectARX \inc\lib 目录位于项目的搜索路径中。该程序需要链接到以下库:

acad.lib
acdb22.lib
rxapi.lib

在项目的定义 (DEF) 文件中,将以下行添加到 EXPORTS 部分:

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 头文件时挂起调试符号的定义来实现的。

从项目的调试版本中排除调试 MFC 代码

在生成的 stdafx.h 文件中,在第一个 MFC include 语句(通常 ,#include <afxwin.h>)add the following code:

#ifdef _DEBUG
#undef _DEBUG
#endif

从“生成”菜单中,选择“生成 AsdkMfcComSamp”以验证项目设置是否正确。

你的项目应该可以成功构建,但此时它不做任何事情。下一步是使用 ActiveX 自动化调用实现命令处理程序。

首先,您必须确定哪些接口是必需的。要向模型空间添加新圆,需要 、 和 接口。您可以使用 AutoCAD 类型库 acax22enu.tlb 获取这些接口的定义,如下一过程所示。IAcadApplicationIAcadDocumentIAcadModelSpace

导入 AutoCAD ActiveX 界面的步骤

  1. 从 Microsoft Visual C++ 项目菜单中选择“添加类”。
  2. 选择“从 TypeLib 添加类”以启动“从 TypeLib 添加类”向导。
  3. 从下拉列表中选择 AutoCAD 类型库。(或者,选择“文件”单选按钮并浏览到 acax22enu.tlb 文件。
  4. 选择所需的接口(在本例中为 、 和 ),然后使用箭头按钮将它们添加到生成的类列表中。IAcadApplicationIAcadDocumentIAcadModelSpace
  5. 选择 Finish。该向导为接口包装类创建新的头文件,并将其添加到项目中。
    注意:AutoCAD ActiveX 自动化界面记录在 ActiveX 和 VBA 参考中。

现在,您已经导入了必要的接口,可以实现命令处理功能了。

实现 AutoCAD ActiveX Automation 调用的步骤

  1. AsdkMfcComSamp.cpp 文件中,包括接口包装类的头文件。
  2. 在空函数中,为三个接口包装类添加声明:addCircleThroughMfcCom()
CAcadApplication IApp;
CAcadDocument IDoc;
CAcadModelSpace IMSpace;

使用 () 函数获取 AutoCAD 的 MFC 对象,并调用以下方法:acedGetAcadWinAppCWinAppGetIDispatch

IDispatch *pDisp = acedGetAcadWinApp()->
GetIDispatch(TRUE);

获得对象后,将其附着到本地定义的对象,并确保AutoCAD可见:IDispatchCAcadApplication

IApp.AttachDispatch(pDisp);
IApp.put_Visible(true);

获取活动文档派单并将其附加到本地定义的对象:CAcadDocument

pDisp = IApp.get_ActiveDocument();
IDoc.AttachDispatch(pDisp);

查询活动文档中的模型空间:

pDisp = IDoc.get_ModelSpace();
IMSpace.AttachDispatch(pDisp);

圆需要中心点和半径。为了使此操作对不同的编程语言高效且透明,COM 接口使用 type 。一个点以 .添加以下代码以设置 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;

从对象调用方法:AddCircleCAcadModelSpace

IMSpace.AddCircle(pt1, 2.0);

下面是完成的函数,添加了清理代码和异常处理:

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()


路过

雷人

握手

鲜花

鸡蛋

最新评论

QQ|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 )

GMT+8, 2024-6-27 16:02

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部