기본 콘텐츠로 건너뛰기

라벨이 ObjectARX인 게시물 표시

ObjectArx2000과 ObjectArx2005 ~ 2006에서 바뀐 점

아시다 시피 ObjectArx2000으로는 AutoCAD2000과 AutoCAD2002밖에 지원하지 못합니다. AutoCAD2004 ~ AutoCAD2006을 지원하기 위해서는 ObjectArx2005 ~ ObjectArx2006을 .NET2002를 사용하여 컴파일해야만 합니다. .NET2003이 아니고 .NET2002입니다.( arx가 안 좋은게 버전마다 틀리게 컴파일을 해줘야 한다는 겁니다.) 자 바뀐점을 살펴보면 우선 눈에 띄는게 entry point 부분의 변경입니다. AcRxArxApp클래스를 상속받은 클래스의 가상함수로 메세지를 처리하고 있습니다. 아래는 AcRx::kInitAppMsg 메세지와 대응됩니다. virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) { // TODO: Load dependencies here // You *must* call On_kInitAppMsg here AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ; // TODO: Add your initialization code here return (retCode) ; } 아래는 AcRx::kUnloadAppMsg메세지와 대응됩니다. virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) { // TODO: Add your code here // You *must* call On_kUnloadAppMsg here AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ; // TODO: Unload dependencies here return (retCode) ; } AutoCAD 명령을 등록하는 방법도 UI를 통하여 쉽게 등록할수 있게 하였습니다. 등록한 명령에 대응하는 함수는 static 멤...

Preventing AutoCAD from entering a zero doc state

Preventing AutoCAD from entering a zero doc state Published date: 2005-03-04 ID: TS46546 Applies to: AutoCAD® 2005 Issue How do I prevent AutoCAD from entering a zero document state? Solution When AutoCAD is in a zero document state, you have very limited access to AutoCAD's functionality. In addtion, there are additional complications. One straightforward method of solving this problem is to prevent AutoCAD from entering the zero document state. You can plant an AcApDocManagerReactor and override documentToBeDestroyed(), and call AcApDocManager::appContextNewDocument{}. But this combination will not work because using document manipulation functions within a reactor callback is unsafe. You cannot determine what state AutoCAD is in. A workaround, is to install a timer. Make a reasonable estimate about how long it will take AutoCAD to close a drawing, then set the timer accordingly. Within the timer callback function, you can safely create a new drawing.The fol...

CSaveStatus

대화상자에서 작업을 하다 AutoCAD에서 작업을 하기 위해 포커스를 AutoCAD에 주고 AutoCAD에서의 작업이 끝이나면 다시 포커스를 대화상자에 주는 식의 코딩을 합니다. 물론 대화상자는 모달리스형식으로 생성을 해야되겠죠. 아래와 같은 대략적인 코드가 될것입니다. m_bFocus = FALSE; .... /// AutoCAD에서의 작업 m_bFocus = TRUE; 일반적으로 위는 잘 작동합니다. 하지만 코드 중간에서(AutoCAD에서의 작업) 함수를 빠져나가는 부분이 있다면 그 부분마다 m_bFocus = TRUE라는 코드를 삽입해줘야 합니다. 이 얼마나 지저분하고 손이 많이 가는 작업입니까? 피곤할 노릇이죠. 그래서 클래스로 m_bFocus의 값을 저장해 두었다가 함수를 빠져 나갈때 즉 클래스의 소멸자에서 m_bFocus에 저장해 두었던 값을 되돌려주는 클래스 를 만들게 되었습니다. template<class T> class CSaveStatus { CSaveStatus(const CSaveStatus<T>&){} public: CSaveStatus(T& t) : unnamed(t) { value = t; } CSaveStatus<T>::~CSaveStatus() { unnamed = value; } private: T& unnamed; T value; };

How to remove anonymous groups with ARX?

Published date: 2005-02-08 ID: TS27355 Applies to: AutoCAD® 2005 Issue How do I remove anonymous groups from my drawing using ObjectARX? Solution When an end user creates a 'group' in AutoCAD, it may be an anynonmus group. However, all group (anonymous or otherwise) are stored in the Named Objects Dictionary under the key 'ACAD_GROUP'. If the group is anonymous, AutoCAD assigns it a value such as '*A1', '*A2' and so on. Although to the end user it's anonymous, the goup has a unique key name in the AutoCAD database. Users may add or remove entities from groups so it is possible to have empty groups. To remove an anonyomus group, consider the following code fragment - rmvAnonGrp(). Before running the code given below, creat few unnamed groups(anonymous groups). // Remove anonymous groups. // Note: No error cheking in following code void rmvAnonGrps() { // TODO: Implement the command Acad::ErrorStatus es; AcDbDictionary *...

AcDbSmartObject

엔터티의 속성을 변경하고자 할 경우, 엔터티를 AcDb::kForWrite로 열어서 속성을 변경시킵니다. 하지만 막상 도큐먼터를 락걸지 않고 여는 바람에 autocad가 에러를 내며 튕겨버립니다. 이런 현상을 프로그램을 실행시켜보아야만 락을 걸지 않고 열었다는 것을 알게 됩니다. 자주 이런 실수를 되풀이 해서 겪다보니 조그마한 클래스를 하나 만들었습니다. 생성자 인자로 열기 모드를 받아 쓰기모드이면 도큐먼트를 락겁니다. 소멸자에서는 쓰기모드로 연 엔터티일 경우에 락을 해제하고, 엔터티를 닫아 줍니다. #ifndef __ACDB_SMART_OBJECT_H__ #define __ACDB_SMART_OBJECT_H__ ////////////////////////////////////////////////////////////////////////// #define USES_OKEYS Acad::ErrorStatus __es #define ARXOK(what) if ( (__es =(what)) != Acad::eOk ) throw acadErrorStatusText (__es) #define ARXNULL(what) if ( (what) == NULL ) throw "" #define ARXCLOSE(what) if ( what != NULL && what->objectId () != AcDbObjectId::kNull ) { what->close () ; }\ else if ( what != NULL ) { delete what ; what =NULL ; } #define ARXERROR(msg) acutPrintf("%s/%d : %s\n",__FILE__,__LINE__,msg); template<class T> class AcDbSmartObject { public: explicit AcDbSmartObject(const AcDbObjec...

acedSSGet으로 entity 선택할 때의 고려사항

acedSSGet 함수는 단적으로 말해서 화면에 보이는 entity만을 선택합니다. 예를 들어 "W"로 해서 선택할때 영역을 설정하게 되는데 영역이 드로잉의 모든 entity를 포함하더라도 화면에 보이지 않는 entity들은 선택되지 않습니다. 물론 자세한 내용은 도움말 파일에 나와 있습니다. 도움말 파일을 읽는 습관을 기르자...

블럭의 색상 변경하기

사용 함수 : ArxSetBlockRefColor(AcDbBlockReference* pBlkRef , const int& colorIndex) /** \brief The ArxSetBlockDefColor function \param objId a parameter of type const AcDbObjectId& \param colorIndex a parameter of type const int& \return void */ void ArxSetBlockDefColor(const AcDbObjectId& objId , const int& colorIndex) { USES_OKEYS; AcDbBlockTableRecord* pRcd; try { ARXOK(acdbOpenObject(pRcd,objId,AcDb::kForRead)); ////////////////////////////////////////////////////////////////////////// AcDbBlockTableRecordIterator* pIterator; if(Acad::eOk == pRcd->newIterator(pIterator)) { for(;pIterator && !pIterator->done();pIterator->step()) { AcDbEntity* pEnt; try { ARXOK(pIterator->getEntity(pEnt,AcDb::kForWrite)); if(pEnt->isKindOf(AcDbBlockReference::desc())) { AcDbObjectId blockId = AcDbBlockReference::cast(pEnt)->blockTableRecord(); pEnt->setColorIndex(c...

어떤 좌표에 위치한 엔터티 구하기

샘플 코드 int ArxGetEntUnderPos(AcDbObjectIdArray& ids , const AcGePoint3d& pt) { ads_point ptUnder = {pt.x, pt.y, pt.z}; ads_name ss; int res; if (RTNORM != (res = acedSSGet(":E", ptUnder, NULL, NULL, ss))) { // There is probably nothing under the cursor, // so return and let AutoCAD process the message return RTFAIL; } long length = 0L; acedSSLength(ss, &length); if (0 == length) { // There is nothing under the cursor, // so there is no need to show the context menu. // Let AutoCAD process the message. acedSSFree(ss); return RTFAIL; } ads_name ename; for(int i = 0;i < length;i++) { acedSSName(ss, i, ename); AcDbObjectId entId; if(Acad::eOk != acdbGetObjectId(entId, ename)) continue; ids.append(entId); } acedSSFree(ss); return RTNORM; }

WBLOCK 예제

현재 열려진 Database를 사용하지 않고. 임의의 Database를 생성하여 블럭을 만들 Entity들을 추가한 후 블럭을 만든다. 이런 방법을 사용하면 현재의 Drawing,에 Entity들을 그리지 않고서도 블럭을 만들기가 가능합니다. void Command_Block() { AcDbDatabase* pDatabase = new AcDbDatabase; AcGePoint3d ptStart; ptStart.x = ptStart.y = ptStart.z = 0; AcGePoint3d ptEnd; ptEnd.x = ptEnd.y = ptEnd.z = 100; AcDbLine* pLine = new AcDbLine(ptStart , ptEnd); AcDbBlockTable *pBlockTable; Acad::ErrorStatus es; es = pDatabase->getBlockTable(pBlockTable, AcDb::kForRead); if (es != Acad::eOk) { ads_alert("Failed to get the block table!"); pBlockTable->close(); return; } AcDbBlockTableRecord *pBlockRec; es = pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockRec, AcDb::kForWrite); if (es != Acad::eOk) { ads_alert("Failed to get the block table record!"); pBlockRec->close(); return; } AcDbObjectId retId; if(pBlockRec->appendAcDbEntity(retId, pLine) != Acad::eOk) { ads_alert("Can't add entity to the blockTableR...

메뉴 생성 예

아래는 메뉴를 생성하는 샘플코드입니다. try { CComPtr pDisp; pDisp = acedGetAcadWinApp()->GetIDispatch(TRUE); CComPtr pComApp; HRESULT hr = pDisp->QueryInterface(IID_IAcadApplication,(void**)&pComApp); if(FAILED(hr)) return; CComPtr pMenuGrps = NULL; if(FAILED(pComApp->get_MenuGroups(&pMenuGrps))) return; CComPtr pMenuGrp = NULL; if(FAILED(pMenuGrps->Item(_variant_t((short)0),&pMenuGrp))) return; CComPtr pPopupMenus = NULL; //add a menu item to the first loaded menu group by name "AddedFromArx" if(FAILED(pMenuGrp->get_Menus(&pPopupMenus))) return; CComPtr pPopupMenu = NULL; if(FAILED(pPopupMenus->Add(_bstr_t("PWPID"),&pPopupMenu))) return; CComPtr pPopupMenuItem = NULL; pPopupMenu->AddMenuItem(_variant_t((short)0),_bstr_t("New Project"),_bstr_t("PWPID_NEWPROJECT\n"),&pPopupMenuItem); pPopupMenu->AddMenuItem(_variant_t((short)1),_bstr_t("Open Project"),_bstr_t("PWPID_OPENPRO...

메뉴 제거 예

aaa라는 메뉴를 제거한다. try{ CComPtr pDisp; pDisp = acedGetAcadWinApp()->GetIDispatch(TRUE); CComPtr pComApp; HRESULT hr = pDisp->QueryInterface(IID_IAcadApplication,(void**)&pComApp); if(FAILED(hr)) return; CComPtr pMenuGrps = NULL; if(FAILED(pComApp->get_MenuGroups(&pMenuGrps))) return; CComPtr pMenuGrp = NULL; if(FAILED(pMenuGrps->Item(_variant_t((short)0),&pMenuGrp))) return; CComPtr pPopupMenus = NULL; //add a menu item to the first loaded menu group by name "AddedFromArx" if(FAILED(pMenuGrp->get_Menus(&pPopupMenus))) return; //_variant_t index=1L; //pPopupMenus->RemoveMenuFromMenuBar(index); CComPtr pPopupMenu = NULL; long lCount=0L; pPopupMenus->get_Count(&lCount); for(long l=0;l < lCount;l++){ pPopupMenus->Item(_variant_t((long)l),&pPopupMenu); BSTR name; pPopupMenu->get_Name(&name)...

Entity 생성 예

샘플 코드 #include BOOL purePaperSpace() { struct resbuf res; int tilemode, cvport; ads_getvar("tilemode", &res); tilemode = res.resval.rint; ads_getvar("cvport", &res); cvport = res.resval.rint; if(tilemode == 0 && cvport == 1) return TRUE; else return FALSE; } // Helper to posts an entity to the database Adesk::Boolean PostToDb(AcDbEntity* pEnt, AcDbObjectId& objId) { AcDbBlockTable *pBlockTable; Acad::ErrorStatus es; es = acdbCurDwg()->getBlockTable(pBlockTable, AcDb::kForRead); if (es != Acad::eOk) { ads_alert("Failed to get the block table!"); pBlockTable->close(); return Adesk::kFalse; } AcDbBlockTableRecord *pBlockRec; if(purePaperSpace()) es = pBlockTable->getAt(ACDB_PAPER_SPACE, pBlockRec, AcDb::kForWrite); else es = pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockRec, AcDb::kForWrite); if (es != Acad::eOk) { ads_alert("Failed to get the block table record!"); pBlockRec-...

Rectangle Jig Class

샘플 코드 // AsdkRectangleJig.h: interface for the AsdkRectangleJig class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_ASDKRECTANGLEJIG_H__B797B881_525A_491D_B14C_F2B9ACA711A8__INCLUDED_) #define AFX_ASDKRECTANGLEJIG_H__B797B881_525A_491D_B14C_F2B9ACA711A8__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include #include #include // asDblArray() #include // acdbWcs2Ecs() & acdbUcs2Ecs() #include // lwpoly stuff. #include "DataMgr.h" #include "ViewCreator.h" //----------------------------------------------------------------------------- // class CRectInfo { public: CRectInfo(); AcGePoint3d m_topLeftCorner; // First point selection. double m_first; // First Chamfer distance. double m_second; // Second Chamfer distance. double m_bulge; // Bulge value. double m_elev; ...

explode block reference

샘플 코드 /* objIds : 블럭이 explode되고나서 생성되는 entity의 object id들 pBlkRef : block reference bErase : 블럭을 지울것인가 말것인가? */ bool explodeBlockReference(AcDbObjectIdArray& objIds,AcDbBlockReference *pBlkRef,const bool bErase) { assert(pBlkRef && "pBlkRef is NULL"); bool bRet=false; if(pBlkRef) { CString rLayer=pBlkRef->layer(); AcDbVoidPtrArray entitySet; // explode the block, this will return a load of pre-transfromed entities for our perusal USES_OKEYS; try { ARXOK(pBlkRef->explode(entitySet)); } catch(const char* ex) { ARXERROR(ex); return bRet; } if(true == bErase) pBlkRef->erase(); pBlkRef->close(); AcDbDatabase *pDb=acdbHostApplicationServices()->workingDatabase(); AcDbBlockTable *pBT; pDb->getSymbolTable(pBT, AcDb::kForRead); AcDbBlockTableRecord *pBTR; pBT->getAt(ACDB_MODEL_SPACE, pBTR, AcDb::kForWrite); pBT->close(); // loop round getting each entity for (long i=0l; i<entitySet.len...

single documet off

샘플 코드 void DisableSinglenullMode(){ CWinApp* pWinApp = acedGetAcadWinApp(); if(!pWinApp) return; CComPtr<IDispatch> pDisp = pWinApp->GetIDispatch(TRUE); if(!pDisp) return; CComPtr<IAcadApplication> pComApp; HRESULT hr = pDisp->QueryInterface(IID_IAcadApplication,(void**)&pComApp); if(FAILED(hr)) return; CComPtr<IAcadPreferences> pPreferences; pComApp->get_Preferences(&pPreferences); CComPtr<IAcadPreferencesSystem> pPreferSystem; pPreferences->get_System(&pPreferSystem); _variant_t b(VARIANT_FALSE); pPreferSystem->put_SinglenullMode(b); }