Hi sorry about that,
@Alexander.Rivilis found a issue with the code, until further investigation I have made blog to private mode.
Anyway you can have a look the code structure.
using namespace std;
static void closeOrDeleteDbObj(AcDbObject *pObj)
{ if (pObj->objectId().isNull()) delete pObj; else pObj->close(); }
template <class T> struct unique_db_ptr : public unique_ptr<T, void(*)(AcDbObject*)>
{ unique_db_ptr<T>(T*& t) : unique_ptr<T,void(*)(AcDbObject*)>(t, closeOrDeleteDbObj) { } };
static AcDbObjectId addToDb(AcDbEntity *pEnt, AcDbDatabase *pDb = nullptr)
{
AcDbObjectId newEntId;
if (nullptr == pEnt)
return newEntId;
if (nullptr == pDb)
pDb = acdbHostApplicationServices()->workingDatabase();
if (nullptr == pDb)
return newEntId;
unique_db_ptr<AcDbEntity> ent(pEnt);
AcDbBlockTable *pBt;
if (eOk != pDb->getBlockTable(pBt, kForRead))
return newEntId;
unique_db_ptr<AcDbBlockTable> bt(pBt);
AcDbBlockTableRecord *pMs;
if (eOk == pBt->getAt(ACDB_MODEL_SPACE, pMs, kForWrite))
unique_db_ptr<AcDbBlockTableRecord>(pMs)->appendAcDbEntity(newEntId, pEnt);
return newEntId;
}
/*Globals*/
typedef std::tuple<CString, CString, CString> _CopyTuples;
typedef std::tuple<CString, CString, CString> _PasteTuples;
std::vector <_CopyTuples> vCopy;
std::vector <_PasteTuples> vPaste;
/*Utils*/
CString getObjectIdToStr(const AcDbObjectId& id)
{
CString str = _T("");
ads_name ent;
acdbGetAdsName(ent, id);
str.Format(_T("%lx"), ent[0]);
return str;
}
CString objToHandleStr(const AcDbObject* obj)
{
ASSERT(obj != NULL);
AcDbHandle handle;
obj->getAcDbHandle(handle);
TCHAR tmpStr[256];
handle.getIntoAsciiBuffer(tmpStr);
CString str = tmpStr;
return str;
}
CString intDbIdToStr(const Adesk::IntDbId intVal)
{
CString str = _T("");
#if !defined(_WIN64) && !defined (_AC64)
str.Format(_T("%d"), intVal);
#else
str.Format(_T("%I64d"), intVal);
#endif
return str;
}
CString booleanToStr(bool b)
{
CString str = _T("");
if (b)
str = _T("True");
else
str = _T("False");
return str;
}
CString objToClassStr(const AcRxObject* obj)
{
ASSERT(obj != NULL);
AcRxClass* rxClass = obj->isA();
if (rxClass == NULL) {
ASSERT(0);
acedAlert(_T("AcRxObject class has not called rxInit()!"));
return _T("*Unknown*");
}
return obj->isA()->name();
}
void tupes()
{
typedef std::pair<CString, CString> _MapPairs;
std::vector <_MapPairs> pairs;
/*Get Mapping Relation*/
acutPrintf(_T("*******Mapping Relation Between Handles of Source and Destination Objects*******"));
auto iterA = vCopy.begin();
auto iterB = vPaste.begin();
int i = 0;
while (iterA != vCopy.end() || iterB != vPaste.end())
{
_CopyTuples t;
_PasteTuples p;
if (iterA != vCopy.end())
{
t = vCopy.at(i);
++iterA;
}
if (iterB != vPaste.end())
{
p = vPaste.at(i);
++iterB;
}
/*Check if Source item's Value is same as Destination Item's Key*/
if (!std::get<2>(t).CompareNoCase(std::get<1>(p)))
{
pairs.push_back(_MapPairs(std::get<0>(t), std::get<0>(p)));
}
i++;
}
for (_MapPairs p : pairs)
{
acutPrintf(_T("\n%s <------------> %s"), p.first, p.second);
}
vCopy.clear();
vPaste.clear();
}
class AcEdReactor :public AcEditorReactor
{
/*To watch for _PASTECLIP*/
void virtual otherInsert(AcDbDatabase* pTo, AcDbIdMapping& idMap, AcDbDatabase* pFrom)
{
CString str;
_PasteTuples pasteClipEntities;
AcDbIdPair idPair;
AcDbIdMappingIter mapIter(idMap);
for (mapIter.start(); !mapIter.done(); mapIter.next())
{
if (mapIter.getMap(idPair))
{
AcDbSmartObjectPointer<AcDbEntity> pEnt(idPair.value(), AcDb::kForRead);
if (pEnt != NULL && pEnt.openStatus() == Acad::eOk)
{
acutPrintf(_T("\n%s"),objToClassStr(pEnt));
acutPrintf(_T("\n%s : Handle"),objToHandleStr(pEnt));
acutPrintf(_T("\n%s : Key"), intDbIdToStr(idPair.key().asOldId()));
acutPrintf(_T("\n%s : Value"),intDbIdToStr(idPair.value().asOldId()));
pasteClipEntities = std::make_tuple(objToHandleStr(pEnt),
intDbIdToStr(idPair.key().asOldId()),
intDbIdToStr(idPair.value().asOldId())
);
vPaste.push_back(pasteClipEntities);
}
}
}
}
void virtual otherWblock(AcDbDatabase* pTo, AcDbIdMapping& idMap, AcDbDatabase* pFrom)
{
/*To Watch For _COPYCLIP*/
CString str;
_CopyTuples copyCLipEntities;
AcDbIdPair idPair;
AcDbIdMappingIter mapIter(idMap);
for (mapIter.start(); !mapIter.done(); mapIter.next()) {
if (mapIter.getMap(idPair))
{
if(idPair.isCloned())
{
AcDbSmartObjectPointer<AcDbEntity> pEnt(idPair.key(), AcDb::kForRead);
if (pEnt != NULL && pEnt.openStatus() == Acad::eOk)
{
acutPrintf(_T("\n%s"),objToClassStr(pEnt));
acutPrintf(_T("\n%s : Handle"),objToHandleStr(pEnt));
acutPrintf(_T("\n%s : Key"),intDbIdToStr(idPair.key().asOldId()));
acutPrintf(_T("\n%s : Value"),intDbIdToStr(idPair.value().asOldId()));
copyCLipEntities = std::make_tuple(
objToHandleStr(pEnt),
intDbIdToStr(idPair.key().asOldId()),
intDbIdToStr(idPair.value().asOldId())
);
vCopy.push_back(copyCLipEntities);
}
}
}
}
}
};
static AcEdReactor* testReactor = NULL;
//**************************************************************
extern "C"
AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void *pkt)
//**************************************************************
{
switch (msg)
{
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(pkt);
acrxDynamicLinker->registerAppMDIAware(pkt);
testReactor = new AcEdReactor();
acedEditor->addReactor(testReactor);
acedRegCmds->addCommand(_T("TestCmd"), _T("MPL"), _T("MPL"), ACRX_CMD_TRANSPARENT, tupes);
break;
case AcRx::kUnloadAppMsg:
acedRegCmds->removeGroup(_T("TestCmd"));
acedEditor->removeReactor(testReactor);
break;
default:
break;
}
return AcRx::kRetOK;
}