|
一、使用"acdbDisplayPreviewFromDwg"函数
1. 引用说明
/*
此功能获取由指定的图形的预览图像(如果有)pszDwgfilename,将其显示在由HWND参数pPreviewWnd标识的窗口中。图像尺寸最大变化不超过256 x 188像素。
如果pPreviewWnd窗口大于图像,则图像将被拉伸以适合图像。但是,如果窗口小于图像,则图像将不会被调整,并且会溢出到窗口的边界之外。
如果非空,pBgColor必须是代表RGB颜色的长整数。长格式是Windows SDK使用的格式颜色参考类型。
返回true表示成功;否则返回false。
*/
ACDB_PORT bool acdbDisplayPreviewFromDwg(
const ACHAR * pszDwgfilename, // 输入路径文件名字符串
void* pPreviewWnd, // 输入要在其中显示预览的窗口的HWND
const Adesk::UInt32* pBgColor = nullptr // 输入RGB颜色作为预览背景
);
2. 使用案例
HWND pWnd;
CFrameWnd *pFrame = (CFrameWnd*)GetDlgItem(IDC_PICTURE);
bool bResult = acdbDisplayPreviewFromDwg(_T("填入文件路径"), pFrame->m_hWnd);
二、结合AcGs库,重载静态文本,用以预览图形
1. 引用说明
AcGsManager::AcGsManager界面提供的服务有助于隐藏将AutoCAD和ARX应用程序连接到图形系统(GS)的详 细信息。每个AutoCAD
AcDisplay对象都有一个AcGsManager。因此,AcGsManager对象与MDI客户端窗口以及AcDbDatabase对象具有一对一的关系。函数acgsGetGSManager()提供对AcGsManager对象的访问。
AcGsDevice:AcGsDevice是绘图表面的抽象,并封装了向其渲染图形的基础设备。 目前,AcGsDevice对应于GUI显示窗口。
最终,将支持其他类型的设备(例如,硬拷贝,文件[.bmp,.wmf,.dwf]和剪贴板)。一个AcGsDevice拥有一个或多个AcGsView,并且必须管理损坏的区域并将更新委派给这些视图。
此外,它还响应操作系统通知,例如图形系统(GS)客户端从基础设备转发的窗口大小更改。
AcGsView:AcGsView对象对应于GUI窗口的一部分,定义视图的一组相机参数以及要查看的对象的集合。更具体地说,AcGsView可用于表示AutoCAD视口。将AcGsView添加到AcGsDevice。一个视图一次只能属于一个设备。需要告知视图正在查看的内容。客户端添加和删除对应于指定模型的已查看部分的(AcGiDrawable,AcGsModel)对。每个AcGsView都有一个RenderMode,它对应于在该视图中绘制几何图形时采用的算法…
AcGsView具有两种状态:交互式和非交互式。默认情况下,AcGsView是非交互式的。这意味着所有方法在调用时立即执行,仅在完成时返回。所有返回值都是可信赖的,并且可以调用所有方法。
AcGsModel:AcGsModel类是数据库的抽象。 该数据库可以是AcDbDatabase,它可以是瞬时图形的容器(例如Icon和Grid),或者可以表示另一种持久数据库格式,例如DWF。
最重要的是,AcGsModel为数据库提供了一种机制,可将更改(添加,删除和修改)通知图形系统(GS)。每个AcGsModel都有一个RenderType,它向GS提供有关如何渲染此模型的几何图形的提示。
2. 使用案例
#pragma once
/**
* @brief 预览DWG图形的静态文本类
*/
class IMechGsPreviewCtrl : public CStatic
{
public:
IMechGsPreviewCtrl();
~IMechGsPreviewCtrl();
private:
AcDbExtents m_Extents; /**< 图纸范围 */
AcGsView *m_pView; /**< 图形系统中的视图,用来绘制图形的区域 */
AcGsDevice *m_pDevice; /**< 图形系统中的设备 */
AcGsModel *m_pModel; /**< 临时数据库 */
AcDbDatabase *m_pDb; /**< 该预览空间绑定的数据库 */
protected:
/**
* @brief 绘制消息处理程序
*/
afx_msg void OnPaint();
/**
* @brief 大小改变消息处理程序
*/
afx_msg void OnSize(UINT nType, int cx, int cy);
DECLARE_MESSAGE_MAP()
public:
/**
* @brief 传入DWG文件预览图形
*
* @param strFilePath 路径
*/
bool Init(const CString& strFilePath);
/**
* @brief 传入数据库指针预览图形
*
* @param pDb 数据库指针
*/
bool Init(AcDbDatabase *pDb);
protected:
/**
* @brief 缩放到图纸可见
*/
void ZoomWindow();
/**
* @brief 清除
*/
void Clear();
/**
* @brief 初始化图形系统
*/
void InitGS(/*HINSTANCE hRes*/);
/**
* @brief 内部初始化
*
* @param pDb 数据库指针
*/
bool InitInner(AcDbDatabase *pDb);
/**
* @brief 获得当前视口的信息
*
* @param dHeight 视口高度
* @param dWidth 视口宽度
* @param ptViewCenter 视口中心点
* @param vecViewDir 视口的观察向量
* @param dTwist 视口中视图的扭曲角度
* @return true/false
*/
bool GetActiveViewPortInfo(double& dHeight, double& dWidth, AcGePoint3d& ptViewCenter,
AcGeVector3d& vecViewDir, double& dTwist, bool bViewCenter);
/**
* @brief 获取块中所有实体Id
*
* @param pBlockTableRecord 块表记录
* @param EntIdArr 传出的实体集
*/
void GetAllEnt(AcDbBlockTableRecord *pBlockTableRecord, AcDbObjectIdArray& EntIdArr);
/**
* @brief 获取实体包围盒
*
* @param EntId 实体Id
* @param Extents 传出的包围盒
*/
Acad::ErrorStatus GetEntExtents(const AcDbObjectId& EntId, AcDbExtents& Extents);
/**
* @brief 获取实体集整体包围盒
*
* @param EntIdArr 实体集
* @param Extents 传出的包围盒
*/
void GetEntExtents(const AcDbObjectIdArray& EntIdArr, AcDbExtents& Extents);
/**
* @brief 获取两点的中心点
*
* @param pt1 点1
* @param pt2 点2
* @param ptMid 传出的中心点
*/
void GetMidPoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2, AcGePoint3d& ptMid);
};
#include "stdafx.h"
#include "resource.h"
#include "IMechGsPreviewCtrl.h"
IMechGsPreviewCtrl::IMechGsPreviewCtrl()
{
m_pView = nullptr;
m_pDevice = nullptr;
m_pModel = nullptr;
m_pDb = nullptr;
}
IMechGsPreviewCtrl::~IMechGsPreviewCtrl()
{
Clear();
}
BEGIN_MESSAGE_MAP(IMechGsPreviewCtrl, CStatic)
ON_WM_PAINT()
ON_WM_SIZE()
END_MESSAGE_MAP()
void IMechGsPreviewCtrl::OnPaint()
{
CPaintDC dc(this);
if (m_pView)
{
m_pView->invalidate();
m_pView->update();
}
}
void IMechGsPreviewCtrl::OnSize(UINT nType, int cx, int cy)
{
CRect rect;
if (m_pDevice)
{
GetClientRect(&rect);
m_pDevice->onSize(rect.Width(), rect.Height());
}
}
void IMechGsPreviewCtrl::Clear()
{
AcGsManager *pGsManager = acgsGetGsManager();
ASSERT(pGsManager);
if (m_pView)
{
m_pView->eraseAll();
if (m_pDevice)
{
bool b = m_pDevice->erase(m_pView);
ASSERT(b);
}
AcGsClassFactory *pFactory = pGsManager->getGSClassFactory();
ASSERT(pFactory);
pFactory->deleteView(m_pView);
m_pView = nullptr;
}
if (m_pModel)
{
pGsManager->destroyAutoCADModel(m_pModel);
m_pModel = nullptr;
}
if (m_pDevice)
{
pGsManager->destroyAutoCADDevice(m_pDevice);
m_pDevice = nullptr;
}
if (m_pDb)
{
delete m_pDb;
m_pDb = nullptr;
}
}
bool IMechGsPreviewCtrl::Init(const CString& strFilePath)
{
Clear();
m_pDb = new AcDbDatabase(false, true);
Acad::ErrorStatus es = m_pDb->readDwgFile(strFilePath);
if (es != Acad::eOk)
{
delete m_pDb;
m_pDb = NULL;
}
return InitInner(m_pDb);
}
bool IMechGsPreviewCtrl::Init(AcDbDatabase *pDb)
{
Clear();
return InitInner(pDb);
}
bool IMechGsPreviewCtrl::GetActiveViewPortInfo(double& dHeight, double& dWidth, AcGePoint3d& ptViewCenter,
AcGeVector3d& vecViewDir, double& dTwist, bool bViewCenter)
{
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
if (pDb == NULL)
{
return false;
}
AcDbViewportTable *pVTable = NULL;
Acad::ErrorStatus es = pDb->getViewportTable(pVTable, AcDb::kForRead);
if (es == Acad::eOk)
{
AcDbViewportTableRecord *pViewPortRec = NULL;
es = pVTable->getAt(_T("*Active"), pViewPortRec, AcDb::kForRead);
if (es == Acad::eOk)
{
dHeight = pViewPortRec->height();
dWidth = pViewPortRec->width();
if (bViewCenter == true)
{
struct resbuf rb;
memset(&rb, 0, sizeof(struct resbuf));
acedGetVar(_T("VIEWCTR"), &rb);
ptViewCenter = AcGePoint3d(rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]);
}
else
{
ptViewCenter = pViewPortRec->target();
}
vecViewDir = pViewPortRec->viewDirection();
dTwist = pViewPortRec->viewTwist();
}
pVTable->close();
pViewPortRec->close();
}
return (true);
}
void IMechGsPreviewCtrl::InitGS(/*HINSTANCE hRes*/)
{
// 获取数据库的图形管理系统:函数acgsGetGSManager()提供对AcGsManager对象的访问
AcGsManager *pGsManager = acgsGetGsManager();
ASSERT(pGsManager);
// 图形管理系统的基类
AcGsClassFactory *pFactory = pGsManager->getGSClassFactory();
ASSERT(pFactory);
// 创建GUI显示窗口:使用指定的内核和窗口创建屏幕上的AcGsDevice
m_pDevice = pGsManager->createAutoCADDevice(m_hWnd);
ASSERT(m_pDevice);
// 设置GUI显示大小
CRect rect;
GetClientRect(&rect);
m_pDevice->onSize(rect.Width(), rect.Height());
// 创建CAD视图:使用用于创建指定设备的相同内核创建一个AcGsView
m_pView = pFactory->createView();
ASSERT(m_pView);
// 创建一个临时数据库
m_pModel = pGsManager->createAutoCADModel();
ASSERT(m_pModel);
// 将视图绑定到GUI显示窗口
m_pDevice->add(m_pView);
double dHeight = 0.0, dWidth = 0.0, dTwist = 0.0;
AcGePoint3d ptViewCenter;
AcGeVector3d vecViewDir;
GetActiveViewPortInfo(dHeight, dWidth, ptViewCenter, vecViewDir, dTwist, true);
// 设置视图
m_pView->setView(ptViewCenter + vecViewDir, ptViewCenter, AcGeVector3d(0.0, 1.0, 0.0), 1.0, 1.0);
}
bool IMechGsPreviewCtrl::InitInner(AcDbDatabase *pDb)
{
if (pDb == nullptr)
{
m_pDb = new AcDbDatabase(true, true);
}
else
{
m_pDb = pDb;
}
if (m_pDb == nullptr)
{
return false;
}
Acad::ErrorStatus es = Acad::eOk;
AcDbBlockTable *pBlockTable = nullptr;
AcDbBlockTableRecord *pBlockTableRecord = NULL;
if ((es = m_pDb->getBlockTable(pBlockTable, AcDb::kForRead)) != Acad::eOk)
{
return false;
}
if ((es = pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForRead)) != Acad::eOk)
{
pBlockTableRecord->close();
return false;
}
pBlockTable->close();
AcDbObjectIdArray EntIdArr;
GetAllEnt(pBlockTableRecord, EntIdArr);
// 获取图纸中实体的最小包围盒
GetEntExtents(EntIdArr, m_Extents);
InitGS();
// 指定视图可以查看临时数据库中的模型空间块
m_pView->add(pBlockTableRecord, m_pModel);
pBlockTableRecord->close();
// 缩放窗口
ZoomWindow();
return TRUE;
}
void IMechGsPreviewCtrl::ZoomWindow()
{
AcGePoint3d ptViewCenter;
GetMidPoint(m_Extents.maxPoint(), m_Extents.minPoint(), ptViewCenter);
double dLenght = m_Extents.maxPoint().x - m_Extents.minPoint().x;
double dWidth = m_Extents.maxPoint().y - m_Extents.minPoint().y;
m_pView->setView(ptViewCenter + AcGeVector3d::kZAxis, ptViewCenter, AcGeVector3d::kYAxis, dLenght * 1.05, dWidth * 1.05);
OnPaint();
}
void IMechGsPreviewCtrl::GetMidPoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2, AcGePoint3d& ptMid)
{
ptMid.x = 0.5 *(pt1.x + pt2.x);
ptMid.y = 0.5 *(pt1.y + pt2.y);
ptMid.z = 0.5 *(pt1.z + pt2.z);
}
void IMechGsPreviewCtrl::GetAllEnt(AcDbBlockTableRecord *pBlockTableRecord, AcDbObjectIdArray& EntIdArr)
{
EntIdArr.setPhysicalLength(0);
AcDbBlockTableRecordIterator *pIter = nullptr;
if (pBlockTableRecord->newIterator(pIter) == Acad::eOk)
{
for (pIter->start(); !pIter->done(); pIter->step())
{
AcDbObjectId EntId;
if (Acad::eOk == pIter->getEntityId(EntId))
{
EntIdArr.append(EntId);
}
}
delete pIter;
pIter = nullptr;
}
return;
}
Acad::ErrorStatus IMechGsPreviewCtrl::GetEntExtents(const AcDbObjectId& EntId, AcDbExtents& Extents)
{
Acad::ErrorStatus es;
AcDbEntityPointer pEntity(EntId, AcDb::kForRead);
if (pEntity.openStatus() == Acad::eOk)
{
AcDbBlockReference *pBlkRef = AcDbBlockReference::cast(pEntity);
if (pBlkRef)
{
es = pBlkRef->geomExtentsBestFit(Extents);
}
else
{
es = pEntity->getGeomExtents(Extents);
}
}
return (es);
}
void IMechGsPreviewCtrl::GetEntExtents(const AcDbObjectIdArray& EntIdArr, AcDbExtents& Extents)
{
for (int i = 0; i < EntIdArr.length(); i++)
{
AcDbExtents ExtentsTemp;
if (GetEntExtents(EntIdArr[i], ExtentsTemp) == Acad::eOk)
{
Extents.addExt(ExtentsTemp);
}
}
}
|
|