zoukankan      html  css  js  c++  java
  • 【转载】SDK中调用COM的例子

    Using COM to Access AutoCAD ActiveX Automation [ObjectARX Developer's Guide: ARXD]

     SDK中调用COM的例子

    This method accesses AutoCAD ActiveX Automation through pure COM techniques. This method requires more coding, but does not rely on MFC. The sample program uses the COM ActiveX Automation interfaces to add a new shortcut menu to the AutoCAD menu bar. The following sections provide procedures that demonstrate the necessary steps:

    • To set up a new ObjectARX project
    • To import AutoCAD ActiveX interfaces
    • To implement AutoCAD ActiveX Automation calls

    To set up a new ObjectARX project

    1. Start Visual C++ and create a new Win32 DLL project called AsdkPlainComSamp.
    2. Add the appropriate values to the project settings to make the project build as an ObjectARX program. This program needs to link with the following libraries:
          acad.lib acdb16.lib rxapi.lib acedapi.lib
    1. Add a new definitions (DEF) file named AsdkPlainComSamp.def to the project.
    2. Open the new DEF file, and add the following lines to the EXPORTS section:
          acrxEntryPoint        PRIVATE
          acrxGetApiVersion     PRIVATE
    1. Add a new source (CPP) file named AsdkPlainComSamp.cpp to the project.
    2. Open the new CPP file, and add the following code to make the program ObjectARX compatible:

    #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;

    }
    1. Stub in your new AutoCAD command handler function by adding the following code to the AsdkPlainComSamp.cpp source file:

    void addMenuThroughCom()

    {

    }

    The next step is to decide which interfaces are necessary to access the AutoCAD menu bar. In this case, IAcadApplication, IAcadMenuBar, IAcadMenuGroups, IAcadMenuGroup, IAcadPopupMenus, IAcadPopupMenu, and IAcadPopupMenuItem are required. To get the definitions of these interfaces, use the AutoCAD type library, acax16<lang>.tlb, as shown in the next procedure.


    To import AutoCAD ActiveX interfaces

    1. Add the following line to the top of the AsdkPlainComSamp.cpp file, making sure to use the path where AutoCAD is installed on your system:

    import "c:\\acad\\acad.tlb" no_implementation "

        raw_interfaces_only named_guids
    1. Add the following declarations to the addMenuThroughCom() function:
    AutoCAD::IAcadApplication *pAcad;
    AutoCAD::IAcadMenuBar 
    *pMenuBar;
    AutoCAD::IAcadMenuGroups 
    *pMenuGroups;
    AutoCAD::IAcadMenuGroup 
    *pMenuGroup;
    AutoCAD::IAcadPopupMenus 
    *pPopUpMenus;
    AutoCAD::IAcadPopupMenu 
    *pPopUpMenu;
    AutoCAD::IAcadPopupMenuItem 
    *pPopUpMenuItem;

    Now that your application imports the proper interfaces, you can use them to implement AutoCAD functionality. The more direct COM approach to Automation uses QueryInterface to access the IUnknown of AutoCAD and its Automation components. The next procedure shows how to accomplish this. All code examples in this procedure should be added to your addMenuThroughCOM() function in the sequence presented.


    To implement AutoCAD ActiveX Automation calls

    1. In the AsdkPlainComSamp.cpp file, add the following code to the empty addMenuThroughCOM() function to get AutoCAD's IUnknown:
    HRESULT hr = NOERROR;
    CLSID clsid;
    LPUNKNOWN pUnk 
    = NULL;
    LPDISPATCH pAcadDisp 
    = NULL; 
    hr 
    = ::CLSIDFromProgID(L"AutoCAD.Application",
            
    &clsid);
    if (FAILED(hr))
        
    return;
    if(::GetActiveObject(clsid, NULL, &pUnk) != S_OK)
        
    return;
    hr 
    = pUnk->QueryInterface(IID_IDispatch, (LPVOID*&pAcadDisp);
    pUnk
    ->Release();
    if (FAILED(hr))
        
    return;
    1. Use IUnknown to get the AutoCAD application object. Also, make sure AutoCAD is visible. This is shown in the following code:

    hr = pAcadDisp->QueryInterface(AutoCAD::IID_IAcadApplication, (void**)&pAcad);
    pAcadDisp
    ->Release();
    if (FAILED(hr))
        
    return;
    pAcad
    ->put_Visible(true);
    1. From the AutoCAD application interface, get the menu bar and menu groups collections:
    pAcad->get_MenuBar(&pMenuBar);
    pAcad
    ->get_MenuGroups(&pMenuGroups);
    pAcad
    ->Release();
    1. Determine how many menus are current on the menu bar:
    long numberOfMenus;
    pMenuBar
    ->get_Count(&numberOfMenus);
    pMenuBar
    ->Release();
    1. Get the first menu from the menu groups collection. This normally is ACAD, but could be something else:
    VARIANT index;
    VariantInit(
    &index);
    V_VT(
    &index) = VT_I4;
    V_I4(
    &index) = 0;
    pMenuGroups
    ->Item(index, &pMenuGroup);
    pMenuGroups
    ->Release();
    1. Get the shortcut menus collection from the first menu group:
    pMenuGroup->get_Menus(&pPopUpMenus);
    pMenuGroup
    ->Release();
    1. Depending on whether the menu is already created, either construct a new shortcut menu or remove the previously created one. The following code completes the example:

    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, strMenuItemMacro, &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();

    Here is the finished function:


    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;
        CLSID clsid;
        LPUNKNOWN pUnk 
    = NULL;
        LPDISPATCH pAcadDisp 
    = NULL; 
        hr 
    = ::CLSIDFromProgID(L"AutoCAD.Application",&clsid);
        
    if (FAILED(hr))
            
    return;
        
    if(::GetActiveObject(clsid, NULL, &pUnk) != S_OK)
            
    return;
        hr 
    = pUnk->QueryInterface(IID_IDispatch, (LPVOID*&pAcadDisp);
        pUnk
    ->Release();
        
    if (FAILED(hr))
            
    return;
        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();

    }

    Both of these examples can be found in the ObjectARX SDK. They are located in the samples"com directory. Each sample contains code for adding a circle and a menu using either Win32 API or MFC programming techniques. Because these methods access AutoCAD through COM interfaces, these programming techniques can be used from other C++ contexts—not just from ObjectARX. Similar techniques can also be used in other languages, such as Visual Basic.

  • 相关阅读:
    Codeforces Round #499 (Div. 2) C.FLY 数学推导_逆推
    Codeforces div2 #499 B. Planning The Expedition 大水题
    Lost Cows POJ
    洛谷P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows 状压动归
    2018.9.30 ~ 2018.11.1 做题记录
    推荐一款强大的轻量级模块化WEB前端快速开发框架--UIkit
    jQuery Validate多实例讲解
    关于Css的垂直居中的一些方法
    关于浮动与清除浮动,你应该知道的
    使用 Vuex + Vue.js 构建单页应用
  • 原文地址:https://www.cnblogs.com/alonecat06/p/1452245.html
Copyright © 2011-2022 走看看