明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3867|回复: 9

[求助]GetCurrentView()的执行中断?

[复制链接]
发表于 2009-10-5 15:38:00 | 显示全部楼层 |阅读模式
本帖最后由 作者 于 2009-10-8 16:08:23 编辑

向高手求助!这个函数用于获得当前视图,在VS2005+
CAD2007通过了编译,执行下面ZoomScale自定义命令时却引发中断,

这是什么原因?.

static AcDbViewTableRecord 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);
 view.setFrontClipEnabled(rb.resval.rint & 2);
 view.setBackClipEnabled(rb.resval.rint & 4);
 view.setFrontClipAtEye(!(rb.resval.rint & 16)); 
 // 当前视口中视图的中心点(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);
 }
 
 return view;
}

 static void CHAP4ZoomScale(void)//自定义的比例缩放命令,调用了GetCurrentView
 {
  // Add your code for command CHAP4.ZoomScale here
  // 提示用户输入缩放的比例因子
  ads_real scale;
  if (acedGetReal(L"\n输入缩放比例因子:", &scale) != RTNORM)
  return;
  
  // 获得当前视图
  AcDbViewTableRecord view = GetCurrentView();

  // 修改视图
  view.setWidth(view.width() / scale);
  view.setHeight(view.height() / scale);
  // 更新视图
  acedSetCurrentView(&view, NULL);
 }

发表于 2009-10-7 23:31:00 | 显示全部楼层

加上一句

acdbHostApplicationServices()->workingDatabase()->updateExt(TRUE);

 楼主| 发表于 2009-10-8 15:50:00 | 显示全部楼层

可是加在什么位置呢,我试了好几个地方,还是一样的中断:

致命错误:Unhandled Access Voliation Reading 0x0004 Exception at 64576927h

还劳烦楼上相告,谢谢

发表于 2009-10-10 13:04:00 | 显示全部楼层
  acedSetCurrentView(&view, NULL);
acdbHostApplicationServices()->workingDatabase()->updateExt(TRUE);
 楼主| 发表于 2009-10-11 10:44:00 | 显示全部楼层
谢谢楼上关注,我又试了一下,让人郁闷的是还是失败了——难道是设置有问题?
发表于 2009-10-12 16:35:00 | 显示全部楼层

根据2点缩放窗口的代码,与你比例因素缩放一个道理,可以参考下。

void Zoom(AcGePoint3d pt1, AcGePoint3d pt2)
{
    AcDbViewTableRecord view;
     struct resbuf rb;
     struct resbuf wcs, dcs, ccs;     // ads_trans coord system flags
     ads_point vpDir;
     ads_point wmin, wmax;        // min and max corners of the zoom window
     ads_point wdcsmax, wdcsmin;  // windows corners in device coords
     AcGeVector3d viewDir;
     AcGePoint2d cenPt;

     ads_real lenslength,viewtwist,frontz,backz;

     ads_point target;

     int viewmode,tilemode,cvport;

     // Get window to zoom to:

     ads_point pt3 = {pt1.x,pt1.y,pt1.z}, pt4 = {pt2.x,pt2.y,pt2.z};


     // sort window corners to upper right and lower left
    
     if (pt3[X] >= pt4[X])
     {
        wmax[X] = pt3[X];
        wmin[X] = pt4[X];
     }
     else
     {
        wmax[X] = pt4[X];
        wmin[X] = pt3[X];
     }

     if (pt3[Y] >= pt4[Y])
     {
        wmax[Y] = pt3[Y];
        wmin[Y] = pt4[Y];
     }
     else
     {
        wmax[Y] = pt4[Y];
        wmin[Y] = pt3[Y];
     }

     wmax[Z] = 0.0;
     wmin[Z] = 0.0;

     wcs.restype     = RTSHORT;     // WORLD coord system flag
     wcs.resval.rint = 0;
     ccs.restype     = RTSHORT;     // CURRENT coord system flag
     ccs.resval.rint = 1;
     dcs.restype     = RTSHORT;     // DEVICE coord system flag
     dcs.resval.rint = 2;

     // Get the 'VPOINT' direction vector
     ads_getvar("VIEWDIR", &rb);
     ads_trans(rb.resval.rpoint, &ccs, &wcs, 0, vpDir);
     viewDir.set(vpDir[X], vpDir[Y], vpDir[Z]);

     // convert upper right window corner to DCS
     ads_trans(wmax, &ccs, &dcs, 0, wdcsmax);

     // convert lower left window corner to DCS
     ads_trans(wmin, &ccs, &dcs, 0, wdcsmin);
    
     // calculate and set view center point
     cenPt.set(wdcsmin[X] + ((wdcsmax[X] - wdcsmin[X]) / 2.0),
          wdcsmin[Y] + ((wdcsmax[Y] - wdcsmin[Y]) / 2.0) );
     view.setCenterPoint(cenPt);

     // set view height and width and direction
     view.setHeight(fabs(wdcsmax[Y] - wdcsmin[Y]));
     view.setWidth(fabs(wdcsmax[X] - wdcsmin[X]));
     view.setViewDirection(viewDir);

     // get and set other properties
     ads_getvar("LENSLENGTH", &rb);
     lenslength = rb.resval.rreal;
     view.setLensLength(lenslength);

     ads_getvar("VIEWTWIST", &rb);
     viewtwist = rb.resval.rreal;
     view.setViewTwist(viewtwist);

     ads_getvar("FRONTZ", &rb);
     frontz = rb.resval.rreal;

     ads_getvar("BACKZ", &rb);
     backz = rb.resval.rreal;

     ads_getvar("VIEWMODE", &rb);
     viewmode = rb.resval.rint;

     view.setPerspectiveEnabled(viewmode & 1);
     view.setFrontClipEnabled(viewmode & 2);
     view.setBackClipEnabled(viewmode & 4);
     view.setFrontClipAtEye(!(viewmode & 16));

     ads_getvar("TILEMODE", &rb);
     tilemode = rb.resval.rint;
     ads_getvar("CVPORT", &rb);
     cvport = rb.resval.rint;

     // Paperspace flag
     Adesk::Boolean paperspace =
        ((tilemode == 0) && (cvport == 1)) ? Adesk::kTrue : Adesk::kFalse;
     view.setIsPaperspaceView(paperspace);

     if (Adesk::kFalse == paperspace)
     {
        view.setFrontClipDistance(frontz);
        view.setBackClipDistance(backz);
     }
     else
     {
        view.setFrontClipDistance(0.0);
        view.setBackClipDistance(0.0);
     }
    
     ads_getvar("TARGET", &rb);
     ads_trans(rb.resval.rpoint, &ccs, &wcs, 0, target);
     view.setTarget(AcGePoint3d(target[X], target[Y], target[Z]));

     // update view
     acedSetCurrentView( &view, NULL );
}

 楼主| 发表于 2009-10-14 21:44:00 | 显示全部楼层

嗯,可以,谢谢梦幻神话

发表于 2011-12-13 17:06:16 | 显示全部楼层
顶顶顶顶顶顶
发表于 2016-2-27 22:57:42 | 显示全部楼层
我也遇到了这个问题,梦幻神话 的方法是在同一个函数中解决了问题,我是将view做了全局变更解决的,应该是一个意思,想不明白的就是view值为什么不能传递,甚至连传址都不行。
发表于 2016-10-25 18:36:36 | 显示全部楼层
不错的资料, 谢谢楼主分享啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 04:52 , Processed in 0.172112 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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