天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 60|回复: 0

ObjectARX CAD屏幕坐标获取方法

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
  1. void ImageIOThread::getScreenCorners(AcGePoint2d& ptLeftLower, AcGePoint2d& ptRightUpper)
  2. {
  3.         CRect rc;
  4.         CView* pCurView = acedGetAcadDwgView();
  5.         pCurView->GetClientRect(&rc);
  6.         CPoint ptTopLeft = rc.TopLeft();
  7.         CPoint ptBottomRight = rc.BottomRight();
  8.         acedDwgPoint pt1, pt2;
  9.         acedCoordFromPixelToWorld(ptTopLeft, pt1);
  10.         acedCoordFromPixelToWorld(ptBottomRight, pt2);
  11.         ptLeftLower.x = pt1[0];
  12.         ptLeftLower.y = pt2[1];
  13.         ptRightUpper.x = pt2[0];
  14.         ptRightUpper.y = pt1[1];
  15. }
复制代码









最近有个人在群里面提出了一个需求,在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);
    :eleteObject(MemDC);
    ::ReleaseDC(hWnd, hScreenDC);

    HDC hDC = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
    //当前分辨率下每个像素所占字节数
    int iBits = ::GetDeviceCaps(hDC, BITSPIXEL) * ::GetDeviceCaps(hDC, PLANES);
    :eleteDC(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屏幕坐标获取方法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-9-30 04:15 , Processed in 0.160763 second(s), 27 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表