| 
积分31441明经币 个注册时间2007-4-24在线时间 小时威望 金钱 个贡献 激情  
 | 
 
| 本帖最后由 gzxl 于 2025-10-27 22:30 编辑 
 
 
 
 源码就是下面所贴的,应该齐全
 
 补上 FileNavDlgCmd 类
 
 
 鼠标钩子
 
  #if _MSC_VER <= 1900
BOOL filterMouse(MSG *pMsg)
#else
bool filterMouse(MSG *pMsg)
#endif
{
    if (pMsg->message == WM_MBUTTONDOWN ||  // 按下鼠标中键
        pMsg->message == WM_MOUSEWHEEL)     // 鼠标滚轮
    {
        // 当前活动文档
        AcApDocument* pDoc = acDocManager->mdiActiveDocument();
        const ACHAR* fileName = pDoc->fileName();
        CString strActiveFileName = fileName;
        // a="c:\\kele8\\shootman2\\vision\\123.exe" => "123"
        strActiveFileName = GetFileTitleFromFileName(strActiveFileName, FALSE);
        // 当前视图中心点、左下角、右上角坐标
        AcGePoint3d ptLB;
        AcGePoint3d ptRT;
        AcGePoint3d ptCenter;
        CViewUtil::GetViewWindow(ptLB, ptRT);
        ptCenter.x = (ptLB.x + ptRT.x) * 0.5;
        ptCenter.y = (ptLB.y + ptRT.y) * 0.5;
        // 赋值
        DocVars.docData().g_ptCenter = ptCenter;
        DocVars.docData().g_ptLeftBottom = ptLB;
        DocVars.docData().g_ptRightTop = ptRT;
        DocVars.docData().g_strActiveFileName = strActiveFileName;
        DocVars.docData().g_bZoomView = true;
    }
    else if (pMsg->message == WM_MBUTTONUP) // 释放鼠标中键
    {
        StartSynView(); // 开始同步两个文档
        DocVars.docData().g_bZoomView = false;
    }
#if _MSC_VER <= 1900
    return FALSE;
#else
    return false;
#endif
}
 两文档视图中心点、左下角、右上角坐标同步
 
  void StartSynView()
{
    // 鼠标中键、滚轮
    if (!DocVars.docData().g_bZoomView)
        return;
    // 视图左下角、右上角坐标(用户坐标系) 
    AcGePoint3d ptLB;
    AcGePoint3d ptRT;
    if (!CViewUtil::GetViewWindow(ptLB, ptRT))
        return;
    // 视图中心点
    AcGePoint3d ptCenter;
    ptCenter.x = (ptLB.x + ptRT.x) * 0.5;
    ptCenter.y = (ptLB.y + ptRT.y) * 0.5;
    ptCenter.z = 0.0;
    if (CViewUtil::IsEqual(ptCenter, DocVars.docData().g_ptCenter))
        return;
    // 当前活动文档名称
    CString strActiveFileName = DocVars.docData().g_strActiveFileName;
    // 遍历文档
    AcApDocumentIterator *pIter = NULL;
    pIter = acDocManager->newAcApDocumentIterator();
    for (; !pIter->done(); pIter->step())
    {
        AcApDocument *pDoc = pIter->document();
        const ACHAR* fileName = pDoc->fileName();
        CString strFileName = fileName;
        // a="c:\\kele8\\shootman2\\vision\\123.exe" => "123"
        strFileName = GetFileTitleFromFileName(strFileName, FALSE);
        if (_tcsicmp(strActiveFileName, strFileName) != 0)
        {
            acDocManager->activateDocument(pDoc);
            DocVars.docData().g_ptCenter = ptCenter;
            DocVars.docData().g_ptLeftBottom = ptLB;
            DocVars.docData().g_ptRightTop = ptRT;
            DocVars.docData().g_strActiveFileName = strFileName;
            acDocManager->sendStringToExecute(pDoc, _T("MyZoom\n"), true, false, false);
        }
    }
    delete pIter;
    pIter = NULL;
}
 字符串处理
 
  /*
a="c:\\kele8\\shootman2\\vision\\123.exe";
b=this->GetFileTitleFromFileName(a,TRUE);
c=this->GetFileTitleFromFileName(a,FALSE);
AfxMessageBox(b); = 123.exe
AfxMessageBox(c); = 123
*/
CString GetFileTitleFromFileName(CString FileName, BOOL Ext)
{
    int Where;
    Where = FileName.ReverseFind('\\');
    if (Where == -1)
        Where = FileName.ReverseFind('/');
    CString FileTitle = FileName.Right(FileName.GetLength() - 1 - Where);
    if (!Ext)
    {
        int Which = FileTitle.ReverseFind('.');
        if (Which != -1)
            FileTitle = FileTitle.Left(Which);
    }
    return FileTitle;
}
 修改视图
 
 复制代码static void MyGroupMyZoom()
{
    AcGePoint3d ptCenter = DocVars.docData().g_ptCenter;
    AcGePoint3d ptLB = DocVars.docData().g_ptLeftBottom;
    AcGePoint3d ptRT = DocVars.docData().g_ptRightTop;
    CViewUtil::SetCenter(ptCenter);
    CViewUtil::Set(ptLB, ptRT);
}
复制代码AcGePoint2d CViewUtil::ToPoint2d(const AcGePoint3d &point3d)
{
    return AcGePoint2d(point3d.x, point3d.y);
}
AcGePoint3d CViewUtil::WcsToDcsPoint(const AcGePoint3d &point)
{
    // 转换成世界坐标
    AcGePoint3d pt;
    struct resbuf rbFrom, rbTo;
    rbFrom.restype = RTSHORT;
    rbFrom.resval.rint = 0; // from WCS
    rbTo.restype = RTSHORT;
    rbTo.resval.rint = 2; // to DCS
    acedTrans(asDblArray(point), &rbFrom, &rbTo, Adesk::kFalse, asDblArray(pt));
    return pt;
}
// 获得当前的视图设置
void CViewUtil::GetCurrentView(AcDbViewTableRecord &view)
{
    struct resbuf rb;
    struct resbuf wcs, ucs, dcs; // 转换坐标时使用的坐标系统标记
    wcs.restype = RTSHORT;
    wcs.resval.rint = 0;
    ucs.restype = RTSHORT;
    ucs.resval.rint = 1;
    dcs.restype = RTSHORT;
    dcs.resval.rint = 2;
    // 获得当前视口的"查看"模式
    acedGetVar(_T("VIEWMODE"), &rb);
    view.setPerspectiveEnabled((rb.resval.rint & 1) != 0);
    view.setFrontClipEnabled((rb.resval.rint & 2) != 0);
    view.setBackClipEnabled((rb.resval.rint & 4) != 0);
    view.setFrontClipAtEye((rb.resval.rint & 16) == 0);
    // 当前视口中视图的中心点(UCS坐标)
    acedGetVar(_T("VIEWCTR"), &rb);
    acedTrans(rb.resval.rpoint, &ucs, &dcs, 0, rb.resval.rpoint);
    view.setCenterPoint(AcGePoint2d(rb.resval.rpoint[X], rb.resval.rpoint[Y]));
    // 当前视口透视图中的镜头焦距长度(单位为毫米)
    acedGetVar(_T("LENSLENGTH"), &rb);
    view.setLensLength(rb.resval.rreal);
    // 当前视口中目标点的位置(以 UCS 坐标表示)
    acedGetVar(_T("TARGET"), &rb);
    acedTrans(rb.resval.rpoint, &ucs, &wcs, 0, rb.resval.rpoint);
    view.setTarget(AcGePoint3d(rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]));
    // 当前视口的观察方向(UCS)
    acedGetVar(_T("VIEWDIR"), &rb);
    acedTrans(rb.resval.rpoint, &ucs, &wcs, 1, rb.resval.rpoint);
    view.setViewDirection(AcGeVector3d(rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]));
    // 当前视口的视图高度(图形单位)
    acedGetVar(_T("VIEWSIZE"), &rb);
    view.setHeight(rb.resval.rreal);
    double height = rb.resval.rreal;
    // 以像素为单位的当前视口的大小(X 和 Y 值)
    acedGetVar(_T("SCREENSIZE"), &rb);
    view.setWidth(rb.resval.rpoint[X] / rb.resval.rpoint[Y] * height);
    // 当前视口的视图扭转角
    acedGetVar(_T("VIEWTWIST"), &rb);
    view.setViewTwist(rb.resval.rreal);
    // 将模型选项卡或最后一个布局选项卡置为当前
    acedGetVar(_T("TILEMODE"), &rb);
    int tileMode = rb.resval.rint;
    // 设置当前视口的标识码
    acedGetVar(_T("CVPORT"), &rb);
    int cvport = rb.resval.rint;
    // 是否是模型空间的视图
    bool paperspace = ((tileMode == 0) && (cvport == 1)) ? true : false;
    view.setIsPaperspaceView(paperspace);
    if (!paperspace)
    {
        // 当前视口中前向剪裁平面到目标平面的偏移量
        acedGetVar(_T("FRONTZ"), &rb);
        view.setFrontClipDistance(rb.resval.rreal);
        // 获得当前视口后向剪裁平面到目标平面的偏移值
        acedGetVar(_T("BACKZ"), &rb);
        view.setBackClipDistance(rb.resval.rreal);
    }
    else
    {
        view.setFrontClipDistance(0.0);
        view.setBackClipDistance(0.0);
    }
}
// 给定显示范围的最大、最小角点坐标和缩放比例,修改视图
void CViewUtil::Set(const AcGePoint3d &ptMin, const AcGePoint3d &ptMax, double scale)
{
    AcDbViewTableRecord view;
    GetCurrentView(view);
    // 将参数的两个点从世界坐标系转换到显示坐标系
    AcGePoint3d ptMinDcs = WcsToDcsPoint(ptMin);
    AcGePoint3d ptMaxDcs = WcsToDcsPoint(ptMax);
    // 设置视图的中心点
    view.setCenterPoint(AcGePoint2d((ptMinDcs.x + ptMaxDcs.x) / 2, (ptMinDcs.y + ptMaxDcs.y) / 2));
    // 设置视图的高度和宽度
    view.setHeight(fabs(ptMinDcs.y - ptMaxDcs.y) * scale);
    view.setWidth(fabs(ptMinDcs.x - ptMaxDcs.x) * scale);
    // 将视图对象设置为当前视图
    acedSetCurrentView(&view, NULL);
}
// 将视图移动到给定的中心点
void CViewUtil::SetCenter(const AcGePoint3d ¢er)
{
    AcDbViewTableRecord view;
    GetCurrentView(view);
    // 将参数的点从世界坐标系转换到显示坐标系
    AcGePoint3d centerDcs = WcsToDcsPoint(center);
    // 设置视图的中心点
    view.setCenterPoint(ToPoint2d(centerDcs));
    // 将视图对象设置为当前视图
    acedSetCurrentView(&view, NULL);
}
// 获取系统变量
// strName ----------- 设置对象
// ptPoint ----------- 返回值
BOOL CViewUtil::GetSysVar(CString strName, AcGePoint3d &ptPoint)
{
    BOOL bRet = FALSE;
    struct resbuf rb;
    ptPoint.set(0.0, 0.0, 0.0);
    if (acedGetVar(strName, &rb) == RTNORM)
    {
        ASSERT(rb.restype == RT3DPOINT);
        ptPoint.set(rb.resval.rpoint[X],
            rb.resval.rpoint[Y],
            rb.resval.rpoint[Z]);
        bRet = TRUE;
    }
    return bRet;
}
// 获取系统变量
// strName ----------- 设置对象
// dVal -------------- 返回值
BOOL CViewUtil::GetSysVar(CString strName, double &dVal)
{
    BOOL bRet = FALSE;
    struct resbuf rb;
    dVal = 0.0;
    if (acedGetVar(strName, &rb) == RTNORM)
    {
        ASSERT(rb.restype == RTREAL);
        dVal = rb.resval.rreal;
        bRet = TRUE;
    }
    return bRet;
}
// 得到视图窗口大小(用户坐标系)  
// ptPointLB  当前视图左下角坐标
// ptPointRT  当前视图右上角坐标
BOOL CViewUtil::GetViewWindow(AcGePoint3d &ptPointLB, AcGePoint3d &ptPointRT)
{
    double dViewWidth = 0.0;            // 视图宽度
    double dViewHeight = 0.0;           // 视图高度
    AcGePoint3d ptCenter;               // 视图中心点
    AcGePoint3d ptPoint;
    // 得到参数
    if (!GetSysVar("VIEWCTR", ptCenter))  //(用户坐标系)  
    {
        return FALSE;
    }
    if (!GetSysVar("VIEWSIZE", dViewHeight))
    {
        return FALSE;
    }
    if (!GetSysVar("SCREENSIZE", ptPoint))
    {
        return FALSE;
    }
    dViewWidth = (ptPoint.x / ptPoint.y)*dViewHeight;
    // 计算视图窗口大小  
    ptPointLB.x = ptCenter.x - dViewWidth / 2;
    ptPointLB.y = ptCenter.y - dViewHeight / 2;
    ptPointLB.z = 0.0;
    ptPointRT.x = ptCenter.x + dViewWidth / 2;
    ptPointRT.y = ptCenter.y + dViewHeight / 2;
    ptPointRT.z = 0.0;
    return TRUE;
}
 测试
 
  vector<CString> fileNames;
if (CFileNavDlgCmd::FileNavCmd(fileNames))
{
    // 关闭开始页
    int nStartmode = 0;
    resbuf rb;
    int nRes = acedGetVar(_T("STARTMODE"), &rb);
    if (nRes != RTNORM)
        return;
    if (rb.restype == RTSHORT)
        nStartmode = rb.resval.rint;
    rb.rbnext = NULL;
    rb.restype = RTSHORT;
    rb.resval.rint = 0;
    nRes = acedSetVar(_T("STARTMODE"), &rb);
    // 打开 Dwg 文件, 命令标志为 ACRX_CMD_SESSION
    for (size_t i = 0; i < fileNames.size(); i++)
    {
        CString strFile = fileNames;
         if (acDocManager->isApplicationContext())
        {
            acDocManager->appContextOpenDocument((const TCHAR *)strFile);
        }
    }
    // 遍历文档,关闭其他的Dwg文件(比如默认的 Drawing1)
    AcApDocumentIterator *pIter1 = acDocManager->newAcApDocumentIterator();
    for (; !pIter1->done(); pIter1->step())
    {
        AcApDocument *pDoc = pIter1->document();
        acDocManager->activateDocument(pDoc);
        acDocManager->setCurDocument(pDoc, AcAp::kWrite);
        const ACHAR* fileName = pDoc->fileName();
        CString strFileName = fileName;
        CString str1 = GetFileTitleFromFileName(strFileName, FALSE);
        bool bEqual = false;
        for (size_t i = 0; i < fileNames.size(); i++)
        {
            CString str2 = GetFileTitleFromFileName(fileNames, FALSE);
             if (_tcsicmp(str2, str1) == 0)
            {
                bEqual = true;
                break;
            }
        }
        if (!bEqual)
        {
            acDocManager->closeDocument(pDoc);
        }
    }
    delete pIter1;
    // 遍历文档,发送 SYSWINDOWS V 命令(垂直平铺两个文档)
    AcApDocumentIterator *pIter2 = acDocManager->newAcApDocumentIterator();
    for (; !pIter2->done(); pIter2->step())
    {
        AcApDocument *pDoc = pIter2->document();
        acDocManager->activateDocument(pDoc);
        acDocManager->setCurDocument(pDoc, AcAp::kWrite);
        CString cmd = _T("SYSWINDOWS V ");
        acDocManager->sendStringToExecute(curDoc(), cmd, true, false, false);
        break;
    }
    delete pIter2;
    // 注册鼠标消息钩子
    acedRegisterFilterWinMsg(filterMouse);
    // 还原开始页
    rb.rbnext = NULL;
    rb.restype = RTSHORT;
    rb.resval.rint = nStartmode;
    nRes = acedSetVar(_T("STARTMODE"), &rb);
}
 卸载钩子
 
 复制代码        // 移除鼠标消息钩子
        acedRemoveFilterWinMsg(filterMouse);
 
 
 
 
 
 
 | 
 
x本帖子中包含更多资源您需要 登录 才可以下载或查看,没有账号?注册 
  评分
查看全部评分
 |