|
[code]
void setView(AcGePoint2d Pt1, AcGePoint2d Pt2, double ex_ratio)
{
AcGePoint2d CenterPt;
//若X坐标或Y坐标重合,判为意外,不进行SetView操作
if ((fabs(Pt1.x-Pt2.x)<1e-6)||(fabs(Pt1.y-Pt2.y)<1e-6))
return;
//确保两个坐标点分别为左上角和右下角
if (Pt1.x>Pt2.x) {
double tmp;
tmp = Pt1.x;
Pt1.x = Pt2.x;
Pt2.x = tmp;
}
if (Pt2.y>Pt1.y) {
double tmp;
tmp = Pt1.y;
Pt1.y = Pt2.y;
Pt2.y = tmp;
}
//获取当前DwgView的尺寸
CRect CADrect;
acedGetAcadDwgView()->GetClientRect(&CADrect);
double width,height,ratio;
ratio = (double)(CADrect.right-CADrect.left)/(double)(CADrect.bottom-CADrect.top);
if (fabs(ratio)<1e-6)
return;
if ((Pt2.x-Pt1.x)/(Pt1.y-Pt2.y) > ratio) {
width = Pt2.x-Pt1.x;
height = width/ratio;
}else{
height = Pt1.y-Pt2.y;
width = height * ratio;
}
//设置当前视图中心点
CenterPt.x = (Pt1.x+Pt2.x)/2;
CenterPt.y = (Pt1.y+Pt2.y)/2;
//改变当前视图
AcDbViewTableRecord pVwRec;
pVwRec.setCenterPoint(CenterPt);
pVwRec.setWidth(width * ex_ratio);
pVwRec.setHeight(height * ex_ratio);
acedSetCurrentView( &pVwRec, NULL );
}
///////////////////////////////////////////////////////////////
// 函 数 名 : oxaGetVar
// 函数功能 :
// 处理过程 :
// 备 注 :
// 作 者 : user
// 时 间 : 2004年6月16日
// 返 回 值 : int
// 参数说明 : const CString strSym,
// AcGePoint3d &vOut
///////////////////////////////////////////////////////////////
int oxaGetVar(const CString strSym, AcGePoint3d &vOut )
{
resbuf rbVar ;
int iRt=acedGetVar(strSym, &rbVar) ;
if (iRt!=RTNORM)
{
return iRt;
}
//oxaPrint(&rbVar);
if (rbVar.restype==RTPOINT)
{
vOut.x=rbVar.resval.rpoint[0];
vOut.y=rbVar.resval.rpoint[1];
}
if (rbVar.restype==RT3DPOINT)
{
vOut.x=rbVar.resval.rpoint[0];
vOut.y=rbVar.resval.rpoint[1];
vOut.z=rbVar.resval.rpoint[2];
}
return RTNORM;
}
/////////////////////////////////////////////////////////////////////////////////
//# DOC.BEGIN
//# 函数名称: oxaGetVar
//# 函数编号: OXA
//# 函数声明:
//# 函数参数: const CString strSym,
// int &vOut
//# 返回值: int
//# 函数分类:
//# 函数功能: 获取系统变量, 封装acedGetVar()
//# 注意事项:
//# 涉及的全局变量:
//# 调用的OXARX函数:
//# 函数算法:
//# ACAD版本:R14 R15 R16
//# 配合函数:
//# 类似函数:
//# 替换函数:
//# 现存缺陷:
//# 示例程序:
//# 测试要求:
//# 历史记录: 2003年11月10日 , zjw ,完成
//
//# DOC.END
//////////////////////////////////////////////////////////////////////////
int oxaGetVar(const CString strSym, int &vOut )
{
resbuf rbVar;
int iRt=acedGetVar(strSym, &rbVar) ;
if (iRt!=RTNORM)
{
return iRt;
}
if (rbVar.restype==RTLONG)
{
vOut=rbVar.resval.rlong;
}
if (rbVar.restype==RTSHORT)
{
vOut=rbVar.resval.rint;
}
return RTNORM;
}
/////////////////////////////////////////////////////////////////////////////////
//# DOC.BEGIN
//# 函数名称: oxaGetVar
//# 函数编号: OXA
//# 函数声明:
//# 函数参数: const CString strSym,
// double &vOut
//# 返回值: int
//# 函数分类:
//# 函数功能: 获取系统变量, 封装acedGetVar()
//# 注意事项:
//# 涉及的全局变量:
//# 调用的OXARX函数:
//# 函数算法:
//# ACAD版本:R14 R15 R16
//# 配合函数:
//# 类似函数:
//# 替换函数:
//# 现存缺陷:
//# 示例程序:
//# 测试要求:
//# 历史记录: 2003年11月24日 , zjw ,完成
//
//# DOC.END
int oxaGetVar(const CString strSym, double &vOut )
{
resbuf rbVar;
int iRt=acedGetVar(strSym, &rbVar) ;
if (iRt!=RTNORM)
{
return iRt;
}
if (rbVar.restype==RTREAL)
{
vOut=rbVar.resval.rreal;
}
return RTNORM;
}
/////////////////////////////////////////////////////////////////////////////////
//# DOC.BEGIN
//# 函数名称: oxaGetVar
//# 函数编号: OXA
//# 函数声明:
//# 函数参数: const CString strSym,
// CString &vOut
//# 返回值: int
//# 函数分类:
//# 函数功能:获取系统变量, 封装acedGetVar()
//# 注意事项:
//# 涉及的全局变量:
//# 调用的OXARX函数:
//# 函数算法:
//# ACAD版本:R14 R15 R16
//# 配合函数:
//# 类似函数:
//# 替换函数:
//# 现存缺陷:
//# 示例程序:
//# 测试要求:
//# 历史记录: 2003年11月24日 , zjw ,完成
//
//# DOC.END
int oxaGetVar(const CString strSym, CString &vOut )
{
resbuf rbVar;
int iRt=acedGetVar(strSym, &rbVar) ;
if (iRt!=RTNORM)
{
return iRt;
}
if (rbVar.restype==RTSTR)
{
vOut=rbVar.resval.rstring;
}
return RTNORM;
}
// 函数名 : SetCurTextStyle
// 描述 : 设置当前TextStyle
// 返回 : Acad::ErrorStatus
// 参数 : const char* lpStyleName
// 参数 : AcDbDatabase* pDb
Acad::ErrorStatus SetCurTextStyle(const char* lpStyleName, AcDbDatabase* pDb)
{
AcDbDatabase* pCurDb = pDb;
if (pCurDb == NULL)
pCurDb = acdbHostApplicationServices()->workingDatabase();
AcDbTextStyleTableRecordPointer spRecord(lpStyleName, pCurDb, AcDb::kForRead);
Acad::ErrorStatus es = spRecord.openStatus();
if (es == Acad::eOk)
{
es = pCurDb->setTextstyle(spRecord->objectId());
}
return es;
}
// Function name : SetCurLayer
// Descrīption : 设置当前层
// Return type : Acad::ErrorStatus
// Argument : const char* lpLayerName
// Argument : AcDbDatabase* pDb
Acad::ErrorStatus SetCurLayer(const char* lpLayerName, AcDbDatabase* pDb)
{
AcDbDatabase* pCurDb = pDb;
if (pCurDb == NULL)
pCurDb = acdbHostApplicationServices()->workingDatabase();
AcDbLayerTableRecordPointer spRecord(lpLayerName, pCurDb, AcDb::kForRead);
Acad::ErrorStatus es = spRecord.openStatus();
if (es == Acad::eOk)
{
es = pCurDb->setClayer(spRecord->objectId());
}
return es;
}
//获取属性块中所有属性的字符串值,并且存于链表中
CODE:
void FEGroups::iterateDictionary()
{
//obtain the GROUP dictionary by looking up "ACAD_GROUP" in the named object dictionary
//
// Get a pointer to the ACAD_GROUP dictionary
AcDbDictionary *pDict;
acdbHostApplicationServices()->workingDatabase()
->getGroupDictionary(pDict, AcDb::kForRead);
// Get an iterator for the ASDK_DICT dictionary.
//
AcDbDictionaryIterator* pDictIter = pDict->newIterator();
AcDbGroup *pGroup;
char* name;
for (; !pDictIter->done(); pDictIter->next()) {
// Get the current record, open it for read, and
// print its name.
//
pDictIter->getObject((AcDbObject*&)pGroup,
AcDb::kForRead);
pGroup->getName(name);
pGroup->close();
acutPrintf("nintval is: %s", name);
}
delete pDictIter;
pDict->close();
}
//检测AutoCAD是否已经运行
CODE:
void Autocadtest()
{
// TODO: Add your control notification handler code here
IAcadApplication m_autocad;
IAcadDocuments m_acaddocs;
IAcadDocument m_acaddoc;
IAcadModelSpace m_acadmodel;
LPDISPATCH pDisp;
LPUNKNOWN pUnk;
CLSID clsid;
BeginWaitCursor();
::CLSIDFromProgID(L"AutoCAD.Application",&clsid);
if(::GetActiveObject(clsid,NULL,&pUnk)==S_OK)
{
VERIFY(pUnk->QueryInterface(IID_IDispatch,(void**) &pDisp)==S_OK);
m_autocad.AttachDispatch(pDisp);
pUnk->Release();
}
else
{
if(!m_autocad.CreateDispatch("AutoCAD.Application"))
{
AfxMessageBox("Autocad program not foundn");
exit(1);
}
}
m_autocad.SetVisible(true);
m_acaddocs.AttachDispatch(m_autocad.GetDocuments(),true);
m_acaddoc.AttachDispatch(m_acaddocs.Add(vtMissing),true);
m_acadmodel.AttachDispatch(m_acaddoc.GetModelSpace(),true);
m_acadmodel.AddCircle(pVal,100);
m_acadmodel.ReleaseDispatch();
m_acaddoc.ReleaseDispatch();
m_acaddocs.ReleaseDispatch();
m_autocad.ReleaseDispatch();
}
//计算多边形的形心坐标
BOOL GetPolyCentroid(AcDbPolyline * pPline, ads_point CenPt)
{
unsigned int i, iCount = 0;
AcDbVoidPtrArray curveSegments, regions;
AcGePoint3d LinePt0, LinePt1;
AcGePoint3d origin;
AcGeVector3d xAxis, yAxis;
double perimeter, area, prodInertia;
double momInertia[2], prinMoments[2], radiiGyration[2];
AcGePoint2d centroid;
AcGeVector2d prinAxes[2];
AcGePoint2d extentsLow, extentsHigh;
if (pPline->isClosed() != Adesk::kTrue) {
ads_printf("n折线不封闭, 无法形成正确的区域。");
return FALSE;
}
curveSegments.append((AcDbCurve *) pPline);
if (AcDbRegion::createFromCurves(curveSegments, regions) != Acad::eOk){
ads_printf("n创建临时区域对象失败!");
//清除Region, 应第9 贴的指点,即使createFromCurves错误,也应清除之;
iCount = regions.length();
for(i = 0; i < iCount; i++)
delete (AcDbRegion *)regions.at(i);
return FALSE;
}
AcDbRegion * pRegion;
if ((iCount = regions.length()) == 0){
ads_printf("n创建临时区域对象为空!");
return FALSE;
}
if (iCount > 1){
// 多个 AcDbRegion , 无法确定应该返回哪一个,干脆返回NULL;
ads_printf("n多个区域实体。");
for(i = 0; i < iCount; i++)
delete (AcDbRegion *)regions.at(i);
return FALSE;
}
pRegion = (AcDbRegion *) regions.at(0);
origin.set(0,0,0); //设置原点坐标
xAxis.set(1,0,0); //设置X Y轴,
yAxis.set(0,1,0);
if (pRegion->getAreaProp(
origin, xAxis, yAxis,
perimeter, area, centroid, momInertia, prodInertia, prinMoments, prinAxes, radiiGyration,
extentsLow, extentsHigh) != Acad::eOk ){
ads_printf("n区域面积: %.3f, 周长:%.3f", area, perimeter);
ads_printf("n获取区域对象属性失败!");
delete pRegion;
return FALSE;
}
XYZ_POINT(CenPt, centroid.x, centroid.y, 0); //得到形心坐标
ads_printf("n区域面积: %.3f, 周长:%.3f", area, perimeter);
pRegion->close();
delete pRegion;
return TRUE;
}
AcDbObjectId CreateHatch(
AcDbObjectId dbOId,
char cLayer[],
char cPattern[] = "SOLID",
int nColor = 256,
double dAngle = 0.0,
double dScale = 1.0,
AcDbDatabase * pDbDatab = acdbHostApplicationServices()->workingDatabase())
{
AcCmColor CmC;
AcDbObjectId DbOId;
AcDbObjectIdArray DbOIdA(0, 2);
AcDbBlockTable * pDbBT;
AcDbBlockTableRecord * pDbBTR;
AcGeVector3d normal(0.0, 0.0, 1.0);
DbOIdA.append(dbOId);
AcDbHatch* pDbHat = new AcDbHatch();
pDbHat->setDatabaseDefaults();
pDbHat->setAssociative(Adesk::kTrue); // BUG: doesn't do squat! have to set the reactor yourself to get associativity!
pDbHat->appendLoop(AcDbHatch::kExternal, DbOIdA);
pDbHat->setPatternScale(dScale);
pDbHat->setPatternAngle(dAngle);
pDbHat->setPattern(AcDbHatch::kPreDefined, cPattern);
pDbHat->setNormal(normal);
pDbHat->evaluateHatch(); // crucial call or nothing gets displayed!
pDbDatab->getSymbolTable(pDbBT, AcDb::kForRead);
pDbBT->getAt(ACDB_MODEL_SPACE, pDbBTR, AcDb::kForWrite);
pDbBTR->appendAcDbEntity(DbOId, pDbHat);
pDbHat->setLayer(cLayer);
CmC.setColorIndex(nColor);
((AcDbEntity *)pDbHat)->setColor(CmC);
pDbBT->close();
pDbBTR->close();
pDbHat->close();
return DbOId;
}
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 okn");
}
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);
}
void ProgressBarTest()
{
acutPrintf("启动进度条..........n");
acedSetStatusBarProgressMeter("测试进度条", 0, 100);
for (int value=0; value<=100; value++) {
Sleep(100); // 暂停, 释放控制权
acedSetStatusBarProgressMeterPos(value);
}
acedRestoreStatusBar();
return;[/code] |
|