ObjectARX实现CAD截图
Posted zeqi1991
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ObjectARX实现CAD截图相关的知识,希望对你有一定的参考价值。
最近有个人在群里面提出了一个需求,在cad中框选实体,然后将框选的内容截图,并且将框选的实体导出到一张dwg中
实现过程如下:
//框选区域
ads_point p1, p2;
if (RTNORM != ads_getpoint(NULL, _T("\\n第一角点"), p1))
return;
if (RTNORM != ads_getcorner(p1, _T("\\n第二角点"), p2))
return;
AcGePoint3d pt1, pt2;
pt1 = asPnt3d(p1);
pt2 = asPnt3d(p2);
//用户坐标系转世界坐标系
pt1 = PublicFunction::TransUcs2Wcs(pt1);
pt2 = PublicFunction::TransUcs2Wcs(pt2);
ads_name sset;
if (RTNORM != acedSSGet(_T("W"), p1, p2, NULL, sset))
{
return;
}
AcDbObjectIdArray idArray = PublicFunction::GetObjectids(sset);
ads_ssfree(sset);
if (idArray.isEmpty())
return;
//bmp
POINT cp1 = GetPointInAcadCoordinate(pt1);
POINT cp2 = GetPointInAcadCoordinate(pt2);
if (cp1.x > cp2.x)
std::swap(cp1, cp2);
WriteToBmp(cp1, cp2);
//wblock
AcDbDatabase* pShortCutDwg = NULL;
acdbCurDwg()->wblock(pShortCutDwg, idArray, AcGePoint3d(0.0, 0.0, 0.0));
pShortCutDwg->saveAs(_T("D:\\\\a.dwg"));
delete pShortCutDwg;
pShortCutDwg = NULL;
POINT GetPointInAcadCoordinate(const AcGePoint3d &pt)
{
ads_point pnt;
ads_point_set(asDblArray(pt), pnt);
//获取视口编号
int wndNum = 0;
struct resbuf v;
if (acedGetVar(_T("cvport"), &v) == RTNORM)
{
wndNum = v.resval.rint;
}
//将pt坐标转为pixel屏幕坐标
CPoint ptInScreen;
acedCoordFromWorldToPixel(wndNum, pnt, ptInScreen);
//将ptInScreen转为在view上的点p3
POINT p3;
p3.x = ptInScreen.x; p3.y = ptInScreen.y;
::ClientToScreen(acedGetAcadDwgView()->m_hWnd, &p3);
return p3;
}
void WriteToBmp(const POINT& pt1, const POINT& pt2)
{
//获得屏幕的HWND
HWND hWnd = ::GetDesktopWindow();
//获得屏幕的HDC
HDC hScreenDC = ::GetDC(hWnd);
HDC MemDC = ::CreateCompatibleDC(hScreenDC);
RECT rect;
::GetWindowRect(hWnd, &rect);
SIZE screensize;
screensize.cx = abs(pt1.x - pt2.x);
screensize.cy = abs(pt1.y - pt2.y);
HBITMAP hBitmap = ::CreateCompatibleBitmap(hScreenDC, screensize.cx, screensize.cy);
HGDIOBJ hOldBMP = ::SelectObject(MemDC, hBitmap);
::BitBlt(MemDC, 0, 0, screensize.cx, screensize.cy, hScreenDC, pt1.x, pt1.y, SRCCOPY);
::SelectObject(MemDC, hOldBMP);
::DeleteObject(MemDC);
::ReleaseDC(hWnd, hScreenDC);
HDC hDC = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
//当前分辨率下每个像素所占字节数
int iBits = ::GetDeviceCaps(hDC, BITSPIXEL) * ::GetDeviceCaps(hDC, PLANES);
::DeleteDC(hDC);
//位图中每个像素所占字节数
WORD wBitCount;
if (iBits <= 1)
wBitCount = 1;
else if (iBits <= 4)
wBitCount = 4;
else if (iBits <= 8)
wBitCount = 8;
else if (iBits <= 24)
wBitCount = 24;
else
wBitCount = iBits;
//调色板大小, 位图中像素字节大小
DWORD dwPaletteSize = 0;
if (wBitCount <= 8)
dwPaletteSize = (1 << wBitCount) * sizeof(RGBQUAD);
//位图属性结构
BITMAP bm;
::GetObject(hBitmap, sizeof(bm), (LPSTR)&bm);
//位图信息头结构
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
//BI_RGB表示位图没有压缩
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmBitsSize = ((bm.bmWidth * wBitCount + 31) / 32) * 4 * bm.bmHeight;
//为位图内容分配内存
HANDLE hDib = ::GlobalAlloc(GHND, dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
// 处理调色板
HANDLE hPal = ::GetStockObject(DEFAULT_PALETTE);
HANDLE hOldPal = NULL;
if (hPal)
{
hDC = ::GetDC(NULL);
hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}
// 获取该调色板下新的像素值
::GetDIBits(hDC, hBitmap, 0, (UINT)bm.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + dwPaletteSize, (BITMAPINFO*)lpbi, DIB_RGB_COLORS);
//恢复调色板
if (hOldPal)
{
SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
::ReleaseDC(NULL, hDC);
}
//位图文件头结构
BITMAPFILEHEADER bmfHdr;
// "BM"
bmfHdr.bfType = 0x4D42;
// 设置位图文件头
DWORD dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
//创建位图文件
HANDLE hFile = CreateFile(_T("D:\\\\a.bmp"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
DWORD dwWritten;
// 写入位图文件头
WriteFile(hFile, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图文件其余内容
WriteFile(hFile, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
//清除
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(hFile);
}
可以封装到一个类中,现在是临时写的路径
以上是关于ObjectARX实现CAD截图的主要内容,如果未能解决你的问题,请参考以下文章