ObjectARX, AutoCAD. Среда программирования библиотеки C++

Использование COM, чтобы обратиться к AutoCAD ActiveX Автоматизация


Этот метод требует большего количества кодирования, но не полагается НА MFC.

Вызывать ActiveX Автоматизацию связывает с помощью интерфейса без MFC

1 типовая программа будет использовать COM ActiveX интерфейсы Автоматизации, чтобы добавить новое всплывающее меню к строке меню AutoCAD. Visual C++ Начала и создает новый Win32 проект Динамически компонуемой библиотеки по имени AsdkComDocSamp.

2 Добавляют соответствующие значения к проектным{*строительным*} назначениям, чтобы делать проектную{*строительную*} компоновку как программа ObjectARX. Эта программа должна связаться со следующими библиотеками:

Acad.lib

Rxapi.lib

Acrx15.lib

Acutil15.lib

Acedapi.lib

3 Добавляют новый файл определения к проекту по имени AsdkComDocSamp.def и добавляют следующие линии:

DESCRIPTION ’Autodesk AsdkCom ARX test application’

LIBRARY AsdkComDocSamp

EXPORTS acrxEntryPoint



_SetacrxPtp

acrxGetApiVersion

4 Добавляют новый исходный файл к проекту по имени AsdkComDocSamp.cpp и добавляют следующий код, чтобы делать программу ObjectARX совместимой:

#include <rxregsvc.h>

#include <aced.h>

#include <adslib.h>

// Used to add/remove the menu with the same command.

//

static bool bIsMenuLoaded = false;

void

addMenuThroughCom()

{

}

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;

}

5 Импортируют AutoCAD, напечатают библиотеку, чтобы приобрести определения для объектов COM. Добавьте следующую линию к вершине AsdkComDocSamp.cpp файла.


Удостоверитесь, чтобы использовать путь для AutoCAD, установленного на вашей системе:

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

Raw_interfaces_only named_guids

6 Решают, который связывает с помощью интерфейса Вас, будет должен обратиться. Так как этот пример использует строку меню AutoCAD, это требует большинства объектов меню. Они объявлены в функции addMenuThroughCom следующим образом:

AutoCAD::IAcadApplication *pAcad;

AutoCAD::IAcadMenuBar *pMenuBar;

AutoCAD::IAcadMenuGroups *pMenuGroups;

AutoCAD::IAcadMenuGroup *pMenuGroup;

AutoCAD::IAcadPopupMenus *pPopUpMenus;

AutoCAD::IAcadPopupMenu *pPopUpMenu;

AutoCAD::IAcadPopupMenuItem *pPopUpMenuItem;

7 более прямой подход COM обращаться к интерфейсам Автоматизации использует QueryInterface. Следующий код возвращает IUNKNOWN для AutoCAD:

HRESULT hr = NOERROR;

CLSID clsid;

LPUNKNOWN pUnk = NULL;

LPDISPATCH pAcadDisp = NULL;

hr = ::CLSIDFromProgID(L"AutoCAD.Application", &clsid);

if (SUCCEEDED(hr))

{

if(::GetActiveObject(clsid, NULL, &pUnk) == S_OK)

{

if (pUnk->QueryInterface(IID_IDispatch, (LPVOID*) &pAcadDisp) != S_OK)

return;

pUnk->Release();

}

}

8 Использования IUnknown, чтобы получить объект приложения AutoCAD. Также, удостоверитесь, что AutoCAD видим и получать объекты IACADMENUBAR И IACADMENUGROUPS.

Этому показывают в следующем коде:

if (SUCCEEDED(pAcadDisp->QueryInterface (AutoCAD::IID_IAcadApplication,(void**)&pAcad)))

{

pAcad->put_Visible(true);

}

else {

acutPrintf("\nQueryInterface trouble.");

return;

}

9 С приложением AutoCAD, получите строку меню и коллекции групп меню.

Определите, сколько меню текущие на строке меню:

pAcad->get_MenuBar(&pMenuBar);

pAcad->get_MenuGroups(&pMenuGroups);

pAcad->Release();

long numberOfMenus;

pMenuBar->get_Count(&numberOfMenus);

pMenuBar->Release();

10 Получают первое меню от коллекции групп меню. Это будет обычно 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();

11 В зависимости от того, создано ли меню уже, или создает новое всплывающее меню или удаляют предварительно созданный. Следующий код заканчивает пример:

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



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;

CLSID clsid;

LPUNKNOWN pUnk = NULL;

LPDISPATCH pAcadDisp = NULL;

hr = ::CLSIDFromProgID(L"AutoCAD.Application", &clsid);

if (SUCCEEDED(hr))

{

if(::GetActiveObject(clsid, NULL, &pUnk) == S_OK)

{

if (pUnk->QueryInterface(IID_IDispatch, (LPVOID*) &pAcadDisp) != S_OK)

return;

pUnk->Release();

}

}

if (SUCCEEDED(pAcadDisp->QueryInterface (AutoCAD::IID_IAcadApplication,(void**)&pAcad))) {

pAcad->put_Visible(true);

}

else {

acutPrintf("\nQueryInterface trouble.");

return;

}

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

bIsMenuLoaded = false;

}

pPopUpMenus->Release();

}

Оба из этих примеров могут быть найдены в ObjectARX SDK. Они расположены в docsamps\COM каталоге. Каждая выборка содержит код для добавления круга и меню, используя или Win32 API или MFC программирование методов.

Так как эти методы обращаются К AutoCAD через COM, связывает с помощью интерфейса, эти методы программирования могут использоваться от других программ C++ (не только ObjectARX). Также, другие языки типа Java и Visual Basic могут использоваться.


Содержание раздела