发新话题
打印

objectARX 常用功能实现集合

本主题被作者加入到个人文集中

objectARX 常用功能实现集合

一 在ARX中禁用AutoCAD的某个命令
以LINE命令为例,在程序中加入下面的一句即可禁用LINE命令:

acedCommand(RTSTR, "undefine",

RTSTR, "line",

RTNONE);

下面的语句则可恢复LINE命令的定义:

acedCommand(RTSTR, "redefine",

RTSTR, "line",

RTNONE);

二 在对话框中预览DWG文件
使用acdbDisplayPreviewFromDwg函数,具体的方法为:
char fileName[100];
strcpy(fileName, "C:\\test.dwg");
bool es;
HWND pWnd;
CFrameWnd *pFrame. = (CFrameWnd*)GetDlgItem(IDC_PICTURE);

es = acdbDisplayPreviewFromDwg(fileName, pFrame->m_hWnd);
上面的代码将在一个Picture控件中显示指定的图形。
另外,需要包含“dbmain.h”头文件。

三 通过ARX更改AutoCAD窗口的标题名称
CMDIFrameWnd *pp;
pp=acedGetAcadFrame();
pp->SetWindowText ("yourName");
pp->UpdateWindow ();

四 获得当前数据库
在ARX编程中,经常需要使用当前数据库,例如需要获得当前图形中设置的文字样式、标注样式等。
要获得当前数据库,都可以直接使用下面的方法:
AcDbTextStyleTable *pTextStyleTAble;
AcDbObjectId textstyleId;
textstyleId=acdbHostApplicationServices()->workingDatabase()->textstyle();
如果用acadCurDwg来代替acdbHostApplicationServices()->workingDatabase(),也能得到同样的结果。


五 将一个图插入另一个图(两种方法)
在实践中常常要将外部的图形文件source.dwg中插入到另外一个图形中或者当前图形中.以插入到当前图形dest.dwg为例.
为了将一个source.dwg插入dest.dwg中,首先要找到source.dwg这个文件. 我们可以使用各种基本的技术和相应的规则从你的机器上或PDM数据库中检索到你要插入的source.dwg, 返回来一个字符窜sFileName代表整个文件及其路径.
然后创建一个空的数据库pNewDb读入source.dwg.
AcDbDatabase *pNewDb =new AcDbDatabase(Adesk::kFalse);
//在这里一定要用Adesk::kFalse
acDocManager->lockDocument(acDocManager->curDocument()) ;//如果确定你不需要LockDocument, 这一行可以不要

es=pNewDb->readDwgFile(sFileName , _SH_DENYNO,false);
if (es!=Acad::eOk)
{
acutPrintf("\nThe file %s cannot be opend",sFileName);
return;
}

这样,source.dwg以经用pNewDb来表示了. 我们用pDb来表示当前数据库
AcDbDatabase *pDb;
pDb =acdbHostApplicationServices ()->workingDatabase () ;

现在,我们用Insert来插入数据库. Insert有两种用法,一种是直接insert, source.dwg中的图元实体被分散地插入pDb中
pDb->insert( AcGeMatrix3d::kIdentity, pNewDb );//这里假定不对source.dwg做比例和转角的变换. 如果我们在这里结束程序,我们能看到source.dwg已经被插入,但不是一个图块.

另外一种插入法是要求插入后source.dwg成为一个图块,图块的attribute也要从source.dwg中得到.这种方法要做大量的工作.首先运行insert()

CString pBlockName=”TestBlock”;
AcDbObjectId blockId;
if((es=pDb->insert(blockId, pBlockName,pNewDb, true))==Acad::eOk)
{
acutPrintf("\ninsert ok\n");
}
else
{
AfxMessageBox("Insert failed");
delete pNewDb;
return;
}

//这里blcokId是insert运行后产生的,它代表的是一个块表记录AcDbBlockRecord的ID. pBlockName是记录名,要在insert运行前设定其值.
如果我们在这里结束程序,我们看不到任何东西,因为source并没有真正被插入.我们还要做一些事,首先是创建一个AcDbBlockReference, 并将它指向blockId所代表的AcDbBlockRecord, 然后将这个AcDbBlockReference加入pDb所代表的图形数据库中.
AcDbBlockReference *pBlkRef = new AcDbBlockReference;
pBlkRef->setBlockTableRecord(blockId);//指向blockId;
pBlkRef->setPosition(Pt);//设定位置
pBlkRef->setRotation(Angle);//设定转角
pBlkRef->setScaleFactors( XrefScale);//设定放大比例

AcDbBlockTable *pBlockTable;
pDb->getSymbolTable(pBlockTable, AcDb::kForRead);

AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId newEntId;
pBlockTableRecord->appendAcDbEntity(newEntId, pBlkRef);
pBlockTableRecord->close();

如果我们在这里结束程序,我们将看到当前图形中source.dwg已经被作为图块插入.但是图块中没有source.dwg所定义的Attibute. 因此我们还要做工作.后面的事情就简单了.

AcDbBlockTableRecord *pBlockDef;
acdbOpenObject(pBlockDef, blockId, AcDb::kForRead);

AcDbBlockTableRecordIterator *pIterator;
pBlockDef->newIterator(pIterator);
AcGePoint3d basePoint;
AcDbEntity *pEnt;
AcDbAttributeDefinition *pAttdef;
for (pIterator->start(); !pIterator->done();
pIterator->step())//将source.dwg中所有的Attibute进行遍历
{
pIterator->getEntity(pEnt, AcDb::kForRead);
pAttdef = AcDbAttributeDefinition::cast(pEnt);
if (pAttdef != NULL && !pAttdef->isConstant()) {
AcDbAttribute *pAtt = new AcDbAttribute();
pAtt->setPropertiesFrom(pAttdef);
pAtt->setInvisible(pAttdef->isInvisible());
basePoint = pAttdef->position();
basePoint += pBlkRef->position().asVector();
pAtt->setPosition(basePoint);
pAtt->setHeight(pAttdef->height());
pAtt->setRotation(pAttdef->rotation());
pAtt->setTag("Tag");
pAtt->setFieldLength(25);
char *pStr = pAttdef->tag();
pAtt->setTag(pStr);
acutDelString(pStr);
pAtt->setFieldLength(pAttdef->fieldLength());
pAtt->setTextString("-");

AcDbObjectId attId;

pBlkRef->appendAttribute(attId, pAtt);
pAtt->close();
}
pEnt->close(); // use pEnt... pAttdef might be NULL
}
delete pIterator;



六 在ARX打开文件
在AutoCAD中打开图形,并且显示在图形窗口中,可以使用acedSyncFileOpen()函数。需要注意的是,这个函数只能在单文档模式中工作,

用户可以在AutoCAD“选项”对话框的“系统”选项卡中进行设置,或者在主函数中添加下面的语句:
acrxDynamicLinker->registerAppNotMDIAware(pkt);
具体的函数如下:

//加载模板文件
void LoadTemplate()
{
char fname[50];
strcpy(fname,"E:\\TMCAD\\TMCADtukuang\\A3.DWG");

#ifndef _ACAD2000
Acad::ErrorStatuses;
es = acedSyncFileOpen(fname);
#else
acDocManager->appContextOpenDocument(fname);
#endif
}




如果在多文档模式下,下面的方法可以在执行时弹出“选择文件”对话框,用户选择所要打开的文件后,在图形窗口中显示该图形。
void ZffOPENOpenDwg()
{
// 使用“选择文件”对话框选择所要打开的文件
acDocManager->openDocument();
}


下面的方法则打开指定位置的DWG文件。
void OpenDoc( void *pData)
{
AcApDocument* pDoc = acDocManager->curDocument();
if (acDocManager->isApplicationContext())
{
acDocManager->appContextOpenDocument((const char *)pData);
}
else
{
acutPrintf("\nERROR To Open Doc!\n");
}
}

// This is command 'OPEN1'
void ZffOPENopen1()
{
// 直接打开系统中存在的某个图形文件G:\AutoCAD图形\wen2.dwg
static char pData[] = "G:\\AutoCAD图形\\wen2.dwg";
acDocManager->executeInApplicationContext(OpenDoc, (void *)pData);
}
查看(43) 评论(0) 收藏 分享 圈子 管理
AcEdInputPointManager类2007-07-22 22:00:47
AcEdInputPointManager类

[折叠]
输入点管理器对AutoCAD中每个激活的文件实例化一次,而且通过一个AcApDocument成员函数输出。
每个实例管理文件编辑工作任务的下列任务:

输入点过滤器和输入点监视器的注册和取消注册
输入环境反应器的注册和取消注册
使失效和重生效系统产生的光标图形,它是图形自定义光标图形的关键元素
在要求选择必须完成的输入事件中请求强制的实体选择。这用在光标追踪穿过当前的视口时追踪光标下的实体。
继承自

包含文件
acedinpt.h
成员
AcEdInputPointManager函数
AcEdInputPointManager::addInputContextReactor函数
virtual Acad::ErrorStatus
addInputContextReactor(
AcEdInputContextReactor* pReactor) = 0;
pReactor
输入一个要增加的输入环境反应器对象
此函数增加一个输入环境反应器。找出通过AutoCAD输入机制(窗口对话框除外)提示用户的内容。任何可以增加的反应器的数量,除了每个只能被增加一次的反应器,与输入点监视器相同。
增加相同的反应器两次(用地址进行比较)将返回 Acad::eDuplicateKey。否则,则返回Acad::eOk。
AcEdInputPointManager::addPointMonitor函数
virtual Acad::ErrorStatus
addPointMonitor(
AcEdInputPointMonitor* pMonitor) = 0;
pMonitor
输入要增加的输入点监视器
此函数增加一个点监视器至当前集合。每个监视器在每个输入点事件中只被调用一次。
增加相同的监视器两次(用地址进行比较)将返回Acad::eDuplicateKey。否则,则返回Acad::eOk。
AcEdInputPointManager::currentPointFilter函数

virtual AcEdInputPointFilter *

currentPointFilter() const = 0;

返回当前的点过滤器(如果有),否则返回NULL。

AcEdInputPointManager::disableSystemCursorGraphics函数

virtual Acad::ErrorStatus

disableSystemCursorGraphics() = 0;

使光标图形对关联的文件失效。与自定义的光标图形一起使用。这个函数与enableSystemCursorGraphics()成对地作用于一个内部的计数器上,因此系统可知道要禁止系统光标的多重应用程序。

如果成功返回Acad::eOk,如果光标因某种原因不能被禁止则返回Acad::eInvalidContext。

AcEdInputPointManager::enableSystemCursorGraphics函数

virtual Acad::ErrorStatus

enableSystemCursorGraphics() = 0;

使光标图形对关联的文件生效。与自定义的光标图形一起使用。这个函数与disableSystemCursorGraphics()成对地作用于一个内部的计数器上,因此系统可知道要禁止系统光标的多重应用程序。

如果成功返回Acad::eOk,如果失效计数已经为0则返回Acad::eInvalidContext。

AcEdInputPointManager::forcedPickCount函数

virtual int

forcedPickCount() const = 0;

如果强制选择为打开的调用者数量。

AcEdInputPointManager::mouseHasMoved函数

virtual int

mouseHasMoved() const = 0;

此函数提供一种方法让输入点监视器和过滤器检查鼠标移动并可尽快地从回调中返回,而无需做任何耗时的计算。

如果序列中没有任何数字化设备事件则返回1,否则返回0。

AcEdInputPointManager::registerPointFilter函数

virtual Acad::ErrorStatus

registerPointFilter(

AcEdInputPointFilter* pFilter) = 0;

pFilter
输入要注册的输入点过滤器对象


使用这个函数注册一个点过滤器。确认在完成时清空过滤器槽,因为在一个时间只能有一个过滤器被注册。

如果当前没有使用任何过滤器,则返回Acad::eOk;否则返回Acad::eIllegalReplacement。

AcEdInputPointManager::removeInputContextReactor函数

virtual Acad::ErrorStatus

removeInputContextReactor(

AcEdInputContextReactor* pReact) = 0;

pReact
输入要删除的输入环境反应器


用于从激活的集合中删除一个输入的环境反应器。

如果反应器在集合中,则返回Acad::eOk,否则返回Acad::eInvalidKey。

AcEdInputPointManager::removePointMonitor函数

virtual Acad::ErrorStatus

removePointMonitor(

AcEdInputPointMonitor* pMonitor) = 0;

pMonitor
输入要删除的输入点监视器


此函数用于从激活的集合中删除一个点监视器。

如果监视器在集合中,则返回Acad::eOk;否则返回Acad::eInvalidKey。

AcEdInputPointManager::revokePointFilter函数

virtual Acad::ErrorStatus

revokePointFilter() = 0;

此函数用于取消当前的点过滤器。最好不要取消另一个应用程序的过滤器;然而如果必须这样做,可使用currentPointFilter()取得当前的这个过滤器并将其放在台面。

如果有一个激活的点过滤器,则返回Acad::eOk;否则返回Acad::eNullObjectPointer。

AcEdInputPointManager::systemCursorDisableCount函数

virtual int

systemCursorDisableCount() const = 0;

返回禁止光标的调用者的数量。

AcEdInputPointManager::turnOffForcedPick函数

virtual Acad::ErrorStatus

turnOffForcedPick() = 0;

这个函数减少强制的选择计数器,如果计数器达到0则禁止强制的选择,这表示实体选择发生在通常的AutoCAD条件下,如当输入点正被请求和OSNAP模式被激活或正常的实体选择操作时。

强制的选择计数已经为0则返回Acad::eInvalidContext,否则返回Acad::eOk。

AcEdInputPointManager::turnOnForcedPick函数

virtual Acad::ErrorStatus

turnOnForcedPick() = 0;

此函数使AutoCAD输入事件机制在所有数据化设备事件中在当前选择靶框下进行选择,无论是否请求一个点或任何OSNAP模式当前被激活。如果一个点被请求且OSNAP模式被激活,对象捕捉靶框尺寸(系统变量:APERTURE)定义了选择框尺寸。否则将使用系统变量PICKBOX。在Acad:ointHistory枚举中,以下的枚举值与功能相关,正如它们相关的注解:eForcedPick, ePickMask, eDidNotPick, eUsedPickBox, eUsedOsnapBox。

在不处理的环境(bypassed context)中(如一个ads_grread()调用)不会发生强制的选择。

计数将被保持,因此如果多重应用程序要强制选择,它会发生直至所有的都完成。

返回Acad::eOk。



查看(28) 评论(0) 收藏 分享 圈子 管理
cad-com接口2007-07-22 21:59:38
cad-com接口

[折叠]
//得到路径,并且设置为支持路径
   IAcadApplication IApp;
   IDispatch *pDisp = acedGetAcadWinApp()->GetIDispatch(false);
   IApp.AttachDispatch(pDisp);
   IAcadPreferences Pref(IApp.GetPreferences());
   IAcadPreferencesFiles PrefFiles(Pref.GetFiles());
   CString sSupportPath = PrefFiles.GetSupportPath();
   sSupportPath = sSupportPath + ";" + sPath;
   PrefFiles.SetSupportPath(sSupportPath);
   PrefFiles.DetachDispatch();
   Pref.DetachDispatch();
   IApp.DetachDispatch();




查看(33) 评论(0) 收藏 分享 圈子 管理
ARX中几个未公开的函数2007-07-22 21:58:40

ARX中几个未公开的函数


//声明函数用来执行lisp命令
extern "C" int ads_queueexpr(char* lisp_expr);
//设置数据库的是否已经修改的标志,可以用来屏蔽保存对话
extern long acdbSetDbmod(AcDbDatabase * pDb, long newVal);


查看(33) 评论(0) 收藏 分享 圈子 管理
利用brep读取region实体边界2007-07-22 21:58:07
利用brep读取region实体边界

[折叠]

cad的arx开发包没有提供读取region边界的函数,事实上利用arx开发包中提供的brep类库可以读取其边界,并得到边界关系(实心边界还是空洞边界)..经测试完全可行,现贴出思路一般来讲认为region是由体->面->边组成我们先得到体,然后由体枚举面,由面枚举边即可 //以下显示了主要思路。。。。 //先得到三维/二维体 AcBrBrep brp; brp.set(*pRegion); //由AcBrBrepFaceTraverser遍历这个体的所有面 AcBrBrepFaceTraverser brpIter; brpIter.setBrep(brp); // //开始遍历体得到面 for( ; !brpIter.done() ; brpIter.next()) { AcBrFace face; if (brpIter.getFace(face) != AcBr::eOk) { continue; } //开始遍历面得到边界 AcBrFaceLoopTraverser faceloop; faceloop.setFace(face); for( ; !faceloop.done() ; faceloop.next()) { AcBrLoop brloop; faceloop.getLoop(brloop); int nHole; AcGePoint3dArray ary; GetEdges(brloop,nHole,ary); } }





查看(32) 评论(0) 收藏 分享 圈子 管理
arx程序2007-07-22 21:48:41

查看(26) 评论(0) 收藏 分享 圈子 管理

TOP

发新话题