使用 COM 访问 AutoCAD ActiveX Automation 
此方法通过纯 COM 技术访问 AutoCAD ActiveX Automation。此方法需要更多的编码,但不依赖于 MFC。示例程序使用 COM ActiveX 自动化接口向 AutoCAD 菜单栏添加新的快捷菜单。以下各节提供了演示必要步骤的过程: 设置新的 ObjectARX 项目
 acad.lib
acdb24.lib
rxapi.lib
 
  将名为 AsdkPlainComSamp.def 的新定义 (DEF) 文件添加到项目中。 打开新的 DEF 文件,并将以下行添加到 EXPORTS 部分: acrxEntryPoint PRIVATE acrxGetApiVersion PRIVATE 将名为 AsdkPlainComSamp.cpp 的新源 (CPP) 文件添加到项目中。 打开新的 CPP 文件,并添加以下代码以使程序 ObjectARX 兼容: #include <rxregsvc.h>
#include <aced.h>
// Used to add/remove the menu with the same command.
//
static bool bIsMenuLoaded = false;
static void initApp()
{
    acedRegCmds->addCommand(
        "ASDK_PLAIN_COM", 
        "AsdkComMenu",
        "ComMenu", 
        ACRX_CMD_MODAL, 
        addMenuThroughCom);
}
static void unloadApp()
{
    acedRegCmds->removeGroup("ASDK_PLAIN_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;
}
 
  通过将以下代码添加到AsdkPlainComSamp.cpp源文件,在新的AutoCAD命令处理程序函数中存根: void addMenuThroughCom()
{
}
 
  下一步是确定访问AutoCAD菜单栏需要哪些界面。在本例中,、、、和为必填项。要获取这些接口的定义,请使用 AutoCAD 类型库 acax24<language>.tlb,如下一过程所示。IAcadApplicationIAcadMenuBarIAcadMenuGroupsIAcadMenuGroupIAcadPopupMenusIAcadPopupMenuIAcadPopupMenuItem 导入 AutoCAD ActiveX 界面的步骤将以下行添加到AsdkPlainComSamp.cpp文件的顶部,确保使用系统上安装AutoCAD的路径: import "c:\\acad\\acax24<language>.tlb" no_implementation \
    raw_interfaces_only named_guids
 
  将以下声明添加到 () 函数:addMenuThroughCom AutoCAD::IAcadApplication *pAcad; AutoCAD::IAcadMenuBar *pMenuBar; AutoCAD::IAcadMenuGroups *pMenuGroups; AutoCAD::IAcadMenuGroup *pMenuGroup; AutoCAD::IAcadPopupMenus *pPopUpMenus; AutoCAD::IAcadPopupMenu *pPopUpMenu; AutoCAD::IAcadPopupMenuItem *pPopUpMenuItem; 现在,您的应用程序导入了正确的界面,您可以使用它们来实现 AutoCAD 功能。自动化的更直接的 COM 方法用于访问 AutoCAD 及其自动化组件。下一个过程演示如何实现此目的。此过程中的所有代码示例都应按显示的顺序添加到 () 函数中。acedGetIDispatch()IDispatchaddMenuThroughCOM 实现 AutoCAD ActiveX Automation 调用的步骤在AsdkPlainComSamp.cpp文件中,将以下代码添加到空函数中以获取AutoCAD:addMenuThroughCOM()IDispatch HRESULT hr = NOERROR; LPUNKNOWN pUnk = NULL; LPDISPATCH pAcadDisp = acedGetIDispatch(TRUE); 用于获取 AutoCAD 应用程序对象。此外,请确保 AutoCAD 可见。如下代码所示:IUnknown hr = pAcadDisp->QueryInterface(AutoCAD::IID_IAcadApplication, (void**)&pAcad); pAcadDisp->Release(); if (FAILED(hr)) return; pAcad->put_Visible(true); 在AutoCAD应用程序界面中,获取菜单栏和菜单组集合: pAcad->get_MenuBar(&pMenuBar); pAcad->get_MenuGroups(&pMenuGroups); pAcad->Release(); 确定菜单栏上当前有多少个菜单: long numberOfMenus; pMenuBar->get_Count(&numberOfMenus); pMenuBar->Release(); 从菜单组集合中获取第一个菜单。这通常是 ,但也可能是其他东西:ACAD VARIANT index; VariantInit(&index); V_VT(&index) = VT_I4; V_I4(&index) = 0; pMenuGroups->Item(index, &pMenuGroup); pMenuGroups->Release(); 从第一个菜单组中获取快捷菜单集合: pMenuGroup->get_Menus(&pPopUpMenus); pMenuGroup->Release(); 根据菜单是否已创建,可以构建新的快捷菜单或删除以前创建的快捷菜单。以下代码完成了该示例: WCHAR wstrMenuName[256];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, 
   "AsdkComAccess", -1, wstrMenuName, 256); 
if (!bIsMenuLoaded) {
    pPopUpMenus->Add(wstrMenuName, &pPopUpMenu);
    if (pPopUpMenu != NULL) {
        pPopUpMenu->put_Name(wstrMenuName);
        WCHAR wstrMenuItemName[256];
        MultiByteToWideChar(CP_ACP, 0,"&Add A ComCircle",
            -1, wstrMenuItemName, 256); 
        WCHAR wstrMenuItemMacro[256];
        MultiByteToWideChar(CP_ACP, 0, "AsdkComCircle ",
            -1, wstrMenuItemMacro, 256); 
        VariantInit(&index);
        V_VT(&index) = VT_I4;
        V_I4(&index) = 0;
        pPopUpMenu->AddMenuItem(index, wstrMenuItemName,
            wstrMenuItemMacro, &pPopUpMenuItem);
        VariantInit(&index);
        V_VT(&index) = VT_I4;
        V_I4(&index) = 1;
        pPopUpMenu->AddSeparator(index, 
            &pPopUpMenuItem);
        MultiByteToWideChar(CP_ACP, 0,
            "Auto&LISP Example", -1, 
            wstrMenuItemName, 256); 
        MultiByteToWideChar(CP_ACP, 0,
            "(prin1 \"Hello\") ", -1, 
            wstrMenuItemMacro, 256); 
        VariantInit(&index);
        V_VT(&index) = VT_I4;
        V_I4(&index) = 2;
        pPopUpMenu->AddMenuItem(index, wstrMenuItemName,
            wstrMenuItemMacro, &pPopUpMenuItem);
        VariantInit(&index);
        V_VT(&index) = VT_I4;
        V_I4(&index) = numberOfMenus - 2;
        pPopUpMenu->InsertInMenuBar(index);
        pPopUpMenu->Release();
        pPopUpMenuItem->Release();
        bIsMenuLoaded = true;
    }else {
        acutPrintf("\nMenu not created.");
    }
 }else {
    VariantInit(&index);
    V_VT(&index) = VT_BSTR;
    V_BSTR(&index) = wstrMenuName;
    pPopUpMenus->RemoveMenuFromMenuBar(index);
    VariantClear(&index);
    bIsMenuLoaded = false;
}
pPopUpMenus->Release();
 
  这是完成的函数: void addMenuThroughCom()
{
    AutoCAD::IAcadApplication *pAcad;
    AutoCAD::IAcadMenuBar *pMenuBar;
    AutoCAD::IAcadMenuGroups *pMenuGroups;
    AutoCAD::IAcadMenuGroup *pMenuGroup;
    AutoCAD::IAcadPopupMenus *pPopUpMenus;
    AutoCAD::IAcadPopupMenu *pPopUpMenu;
    AutoCAD::IAcadPopupMenuItem *pPopUpMenuItem;
    HRESULT hr = NOERROR;
    LPUNKNOWN pUnk = NULL;
    LPDISPATCH pAcadDisp = acedGetIDispatch(TRUE); 
 
    hr = pAcadDisp->QueryInterface(AutoCAD::IID_IAcadApplication, (void**)&pAcad);
    pAcadDisp->Release();
    if (FAILED(hr))
        return;
    pAcad->put_Visible(true);
    pAcad->get_MenuBar(&pMenuBar);
    pAcad->get_MenuGroups(&pMenuGroups);
    pAcad->Release();
    long numberOfMenus;
    pMenuBar->get_Count(&numberOfMenus);
    pMenuBar->Release();
    VARIANT index;
    VariantInit(&index);
    V_VT(&index) = VT_I4;
    V_I4(&index) = 0;
    pMenuGroups->Item(index, &pMenuGroup);
    pMenuGroups->Release();
    pMenuGroup->get_Menus(&pPopUpMenus);
    pMenuGroup->Release();
    WCHAR wstrMenuName[256];
    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, 
        "AsdkComAccess", -1, wstrMenuName, 256); 
    if (!bIsMenuLoaded) {
        pPopUpMenus->Add(wstrMenuName, &pPopUpMenu);
        if (pPopUpMenu != NULL) {
            pPopUpMenu->put_Name(wstrMenuName);
            WCHAR wstrMenuItemName[256];
            MultiByteToWideChar(CP_ACP, 0,"&Add A ComCircle",
                -1, wstrMenuItemName, 256); 
            WCHAR wstrMenuItemMacro[256];
            MultiByteToWideChar(CP_ACP, 0, "AsdkComCircle ",
                -1, wstrMenuItemMacro, 256); 
            VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = 0;
            pPopUpMenu->AddMenuItem(index, wstrMenuItemName,
                wstrMenuItemMacro, &pPopUpMenuItem);
            VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = 1;
            pPopUpMenu->AddSeparator(index, 
                &pPopUpMenuItem);
            MultiByteToWideChar(CP_ACP, 0,
                "Auto&LISP Example", -1, 
                wstrMenuItemName, 256); 
            MultiByteToWideChar(CP_ACP, 0,
                "(prin1 \"Hello\") ", -1, 
                wstrMenuItemMacro, 256); 
            VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = 2;
            pPopUpMenu->AddMenuItem(index, wstrMenuItemName,
                wstrMenuItemMacro, &pPopUpMenuItem);
            VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = numberOfMenus - 2;;
            pPopUpMenu->InsertInMenuBar(index);
            pPopUpMenu->Release();
            pPopUpMenuItem->Release();
            bIsMenuLoaded = true;
        } else {
            acutPrintf("\nMenu not created.");
        }
    } else {
        VariantInit(&index);
        V_VT(&index) = VT_BSTR;
        V_BSTR(&index) = wstrMenuName;
        pPopUpMenus->RemoveMenuFromMenuBar(index);
        VariantClear(&index);
        bIsMenuLoaded = false;
    }
    pPopUpMenus->Release();
}
 
  这两个示例都可以在 ObjectARX SDK 中找到。它们位于 samples\com 目录中。每个示例都包含使用 Win32 API 或 MFC 编程技术添加圆圈和菜单的代码。由于这些方法通过 COM 接口访问 AutoCAD,因此可以从其他 C++ 上下文中使用这些编程技术,而不仅仅是从 ObjectARX 使用。类似的技术也可以用于其他语言,如 Visual Basic。  | 
|Archiver|CAD开发者社区
( 苏ICP备2022047690号-1   苏公网安备32011402011833)
GMT+8, 2025-11-4 14:33
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.