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 могут использоваться.
AutoCAD ActiveX Выполнение Автоматизации
ActiveX модель Автоматизации AutoCAD становится все более и более видимой поперек всех сред программирования, которые это поддерживает. Понимание возможности Автоматизации AutoCAD позволит Вам формировать приложения, которые берут полное преимущество VBA и особенностей подобно OPM и AutoCAD DesignCenter.
Отношения между AcDbObjects и Объектами Автоматизации
AutoCAD осуществляет его модель объекта ActiveX Automation, создавая связь между объектом резидента базы (AcDbObject) и объектом COM, который представляет это. Эта связь составлена из с двух одним направленным указателей. Первый указатель - IUNKNOWN объекта COM, который сохранен, используя переходный реактор на AcDbObject. Второй указатель - AcDbObjectId объекта резидента базы, который сохранен как поле на объекте COM.

Эта связь позволяет Вам отыскивать существующий указатель IUnknown данного объекта COM указатель AcDbObject, как показано в следующем коде:
AcAxOleLinkManager* pOleLinkManager = AcAxGetOleLinkManager();
// pObject is an AcDbObject*
//
IUnknown* pUnk = pOleLinkManager->GetIUnknown(pObject);
// NOTE: AcAxOleLinkManager::GetIUnknown() does not AddRef()
// the IUnknown pointer.
Наоборот, Вы можете отыскивать AcDbObjectId объекта резидента базы, представляемого данным объектом COM указатель IUnknown, как показано в следующем коде:
IAcadBaseObject* pAcadBaseObject = NULL;
// pUnk is the IUnknown* of a COM object representing
// some object in the database
//
HRESULT hr = pUnk->QueryInterface(IID_IAcadBaseObject, (LPVOID*) &pAcadBaseObject);
AcDbObjectId objId;
if(SUCCEEDED(hr))
{
pAcadBaseObject->GetObjectId(&objId);
}
IAcadBaseObject
IAcadBaseObject - интерфейс, имел обыкновение управлять связью от объекта COM до объекта резидента базы. Это - ответственность объекта COM сбросить связь от AcDbObject до объекта COM, когда объект COM разрушается. Это сделано, используя AcAxOleLinkManager класс, обсужденный ниже, обычно в деструкторе класса COM:
interface DECLSPEC_UUID("5F3C54C0-49E1-11cf-93D5-0800099EB3B7")
IAcadBaseObject : public IUnknown
{
// IUnknown methods
//
STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE;
// IAcadBaseObject methods
//
STDMETHOD(SetObjectId)(THIS_ AcDbObjectId& objId,
AcDbObjectId ownerId = AcDbObjectId::kNull,
TCHAR* keyName = NULL) PURE;
STDMETHOD(GetObjectId)(THIS_ AcDbObjectId* objId) PURE;
STDMETHOD(Clone)(THIS_ AcDbObjectId ownerId,
LPUNKNOWN* pUnkClone) PURE;
STDMETHOD(GetClassID)(THIS_ CLSID& clsid) PURE;
STDMETHOD(NullObjectId)(THIS) PURE;
STDMETHOD(OnModified)(THIS) PURE;
};
SetObjectId ()
Этот метод используется, чтобы выделить, который объект резидентом базы объект COM представляет. Если objId параметр равен AcDbObjectId:: kNull, объект COM проинструктируется, чтобы создать новый объект AcDbObject-derived и добавлять это к базе данных. OwnerId и keyName параметры только определены в этой ситуации.
GetObjectId ()
Этот метод используется, чтобы отыскать AcDbObjectId представляемого объекта резидента базы.
Clone ()
Этот метод зарезервирован для будущего использования.
GetClassID ()
Этот метод возвращает CLSID объекта COM.
NullObjectId ()
Этот метод используется, чтобы сообщить объекту COM, что это больше не представляет объект резидента базы.
OnModified ()
Этот метод используется, чтобы сообщить объекту COM, что AcDbObject, который это представляет, изменился. Объект COM тогда ответствен за стреляющее уведомление всем его клиентам через установленные точки соединения.
AcAxOleLinkManager
AcAxOleLinkManager используется, чтобы управлять связью от объекта резидента базы до его объекта COM. Это сделано, прикрепляя переходный реактор к AcDbObject. Переходный реактор имеет одну переменную, содержащую IUNKNOWN объекта COM. Этот переходный реактор также используется, чтобы вызвать IACADBASEOBJECT:: OnModified () когда AcDbObject изменяется.
Получить указатель на OLE связывают менеджера, используют AcAxGetOleLinkManager (). AcAxOleLinkManager класс описан ниже:
// AcAxOleLinkManager используется, чтобы поддержать связь между объектами ARX и их соответствующей оберткой COM.
//
class AcAxOleLinkManager
{
public:
// Учитывая указатель на объект резидента базы, возвратите IUNKNOWN
// обертки COM. NULL возвращен, если никакая обертка не найдена.
//
virtual IUnknown* GetIUnknown(AcDbObject* pObject) = 0;
// Установить связь между объектом резидента базы и оберткой COM.
// Если IUNKNOWN - NULL, то связь удалена.
//
virtual Adesk::Boolean SetIUnknown(AcDbObject* pObject, IUnknown* pUnknown) = 0;
// Учитывая указатель на объект базы данных, возвратите IUNKNOWN
// обертки COM. NULL возвращен, если никакая обертка не найдена.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |


