自定义动态快属性设置问题
大佬们,请教一个问题,我new了一个AcDbBlockReference,是个动态块,添加到模型空间再修改new的动态块的翻转属性值,结果源块就变了1是源块,2是NEW的块,有知道的大佬能指点一下吗?
代码如下
//插入新的动态块
AcDbBlockReference* pBlkRef = new AcDbBlockReference(point, idBlkDef);
//写入模型空间中
AcDbObjectId idClonedBlock = EntityUtil::AddToModelSpace(pBlkRef);
if (AcDbObjectId::kNull == idClonedBlock)
{
delete pBlkRef;
return;
}
//设置属性
Acad::ErrorStatus es = acdbOpenObject(pBlkRef, idClonedBlock, AcDb::kForWrite);
if (Acad::eOk == es)
{
AcDbDynBlockReference dynBlock(pBlkRef);
if (dynBlock.isDynamicBlock())
{
AcDbDynBlockReferencePropertyArray DynBlkRefPropArray;//动态块参照属性数组
dynBlock.getBlockProperties(DynBlkRefPropArray);
AcDbDynBlockReferenceProperty DynBlockReferenceProp;//动态块参照属性
for (int i = 0; i < DynBlkRefPropArray.length(); i++)
{
DynBlockReferenceProp = DynBlkRefPropArray.at(i);
bool bShow = DynBlockReferenceProp.show(); //是否在面板中显示
auto type = DynBlockReferenceProp.propertyType();//属性类型
CString strName = DynBlockReferenceProp.propertyName().kwszPtr();//属性名
if (strName.Find(_T("翻转")) >= 0)
{
Acad::ErrorStatus es = DynBlockReferenceProp.setValue(short(1));
if (Acad::eOk != es)
{
acutPrintf(_T("\n设置【%s】属性值失败,错误代码:%s"), strName, acadErrorStatusText(es));
}
break;
}
}
}
pBlkRef->downgradeOpen();
pBlkRef->close();
}
本帖最后由 520key 于 2023-9-10 17:06 编辑
gzxl 发表于 2023-9-10 15:36
在for下面加上一行更新代码,试下什么结果。
for (int i = 0; i < DynBlkRefPropArray.length(); i++)
{
...
加上这句后,源块没有问题了,但是New的块有问题了,1是源块,2是NEW后的块,附上文件和代码
void CopyDynBlockRef()
{
//提示用户选择一个动态块
struct resbuf* rb = acutBuildList(RTDXF0, _T("INSERT"), RTNONE);
ads_name ss;
CString arPrompt = { _T("\n请选择一个块参照对象"),_T("\n删除了一个块参照对象") };
if (RTNORM == acedSSGet(_T(":S:$-M"), &arPrompt, NULL, rb, ss))
{
//查看此块参照是否是动态块参照
ads_name ent;
acedSSName(ss, 0, ent);
AcDbObjectId idBlk;
acdbGetObjectId(idBlk, ent);
//查看是否为动态块参照
AcDbDynBlockReference cDynBlkRef(idBlk);
if (cDynBlkRef.isDynamicBlock())
{
//打开块参照对象
AcGeMatrix3d mat;
AcGePoint3d ptInset;
AcDbEntity* pEnt = NULL;
if (Acad::eOk != acdbOpenObject(pEnt, idBlk, AcDb::kForRead))
{
acedSSFree(ss);
acutRelRb(rb);
return;
}
AcDbBlockReference* pRef = AcDbBlockReference::cast(pEnt);
if (pRef)
{
mat = pRef->blockTransform();
ptInset = pRef->position();
}
pEnt->close();
//取出动态块定义的ID
AcDbObjectId idBlkDef = AcDbObjectId::kNull;
idBlkDef = cDynBlkRef.dynamicBlockTableRecord();
if (idBlkDef)
{
//插入新的动态块
AcDbBlockReference* pBlkRef = new AcDbBlockReference(AcGePoint3d(0, 0, 0), idBlkDef);
pBlkRef->transformBy(mat);
pBlkRef->setPosition(ptInset);
AcDbDynBlockReference dynBlock(pBlkRef);
if (dynBlock.isDynamicBlock())
{
AcDbDynBlockReferencePropertyArray DynBlkRefPropArray;//动态块参照属性数组
dynBlock.getBlockProperties(DynBlkRefPropArray);
AcDbDynBlockReferenceProperty DynBlockReferenceProp;//动态块参照属性
for (int i = 0; i < DynBlkRefPropArray.length(); i++)
{
DynBlockReferenceProp = DynBlkRefPropArray.at(i);
bool bShow = DynBlockReferenceProp.show(); //是否在面板中显示
auto type = DynBlockReferenceProp.propertyType();//属性类型
CString strName = DynBlockReferenceProp.propertyName().kwszPtr();//属性名
if (strName.Find(_T("翻转")) >= 0)
{
Acad::ErrorStatus es = DynBlockReferenceProp.setValue(short(1));
if (Acad::eOk != es)
{
acutPrintf(_T("\n设置【%s】属性值失败,错误代码:%s"), strName, acadErrorStatusText(es));
}
continue;
}
}
pBlkRef->recordGraphicsModified();
}
if (AcDbObjectId::kNull == Database::PostToModelSpace(pBlkRef))
{
delete pBlkRef;
//acedSSFree(ss);
//acutRelRb(rb);
//return;
}
}
}
acedSSFree(ss);
}
acutRelRb(rb);
}
我用以下代码,测试好像是可以的
ads_name ename;
ads_point pt;
if (acedEntSel(_T("\n选择一个动态块对象:"), ename, pt) != RTNORM)
return;
Acad::ErrorStatus es = Acad::eOk;
AcDbObjectId eId;
es = acdbGetObjectId(eId, ename);
if (es != Acad::eOk) return;
AcDbEntity* pEnt = NULL;
es = acdbOpenObject(pEnt, eId, AcDb::kForRead);
if (es != Acad::eOk) return;
if (pEnt->isA() != AcDbBlockReference::desc())
{
acutPrintf(_T("\n选择的对象不是块参照."));
pEnt->close();
return;
}
AcDbBlockReference *pBlkRef = AcDbBlockReference::cast(pEnt);
// 从块参照的对象id初始化动态块
AcDbDynBlockReference* pDynBlkRef = new AcDbDynBlockReference(pBlkRef->objectId());
// 关闭实体对象,不关闭将无法修改属性
pEnt->close();
if (pDynBlkRef)
{
// 打开块参照对象
AcGeMatrix3d mat;
AcGePoint3d ptInset;
mat = pBlkRef->blockTransform();
ptInset = pBlkRef->position();
AcDbDynBlockReferencePropertyArray DynBlkRefPropArray; // 动态块参照属性数组
pDynBlkRef->getBlockProperties(DynBlkRefPropArray);
AcDbDynBlockReferenceProperty DynBlockReferenceProp; // 动态块参照属性
for (int i = 0; i < DynBlkRefPropArray.length(); ++i)
{
DynBlockReferenceProp = DynBlkRefPropArray.at(i);
CString strName = DynBlockReferenceProp.propertyName().kwszPtr();// 属性名
if (strName.Find(_T("翻转")) == -1)
continue;
es = DynBlockReferenceProp.setValue(short(1));
if (Acad::eOk != es)
{
acutPrintf(_T("\n设置【%s】属性值失败,错误代码:%s"), strName, acadErrorStatusText(es));
}
}
AcDbObjectId idBlkDef = pDynBlkRef->dynamicBlockTableRecord();
delete pDynBlkRef; // 记得删除
// 插入新的动态块
AcDbBlockReference* pNewBlkRef = new AcDbBlockReference(ptInset, idBlkDef);
Database::PostToModelSpace(pNewBlkRef);
}
gzxl 发表于 2023-9-12 14:40
我用以下代码,测试好像是可以的
我用大佬的代码测试,是下面这个结果,1为源块,2为执行代码后的源块,3是NEW之后的块,属性刚好反了,想要达到的效果是执行代码后1 2应该是相同的基点都在左下角,New出后的块3的属性应该是2的那样基点在左上角, 我的环境是VS2022 CAD2022
在for下面加上一行更新代码,试下什么结果。
for (int i = 0; i < DynBlkRefPropArray.length(); i++)
{
//...
}
pBlkRef->recordGraphicsModified();
如果不行的话,可能要上传个dwg。 520key 发表于 2023-9-10 17:04
加上这句后,源块没有问题了,但是New的块有问题了,1是源块,2是NEW后的块,附上文件和代码
那就再加一句代码
dynBlock.resetBlock();
pBlkRef->recordGraphicsModified(); gzxl 发表于 2023-9-10 19:07
那就再加一句代码
dynBlock.resetBlock();
pBlkRef->recordGraphicsModified();
加上dynBlock.resetBlock();后就重置了,设置的值也没有了,加在for前面问题也是一样的 本帖最后由 gzxl 于 2023-9-12 11:52 编辑
建议您再过一遍代码。 这个代码好高端 gzxl 发表于 2023-9-12 11:34
建议您再过一遍代码。
大佬是我的代码写的有问题吗? gzxl 发表于 2023-9-12 14:40
我用以下代码,测试好像是可以的
大佬这里为什么要New两次呢,第一次是objectid 每二次才是动态块的块表记录
页:
[1]
2