[求助]GetCurrentView()的执行中断?
本帖最后由 作者 于 2009-10-8 16:08:23 编辑 <br /><br /> <p>向高手求助!这个函数用于获得当前视图,在VS2005+<br/>CAD2007通过了编译,执行下面ZoomScale自定义命令时却引发中断,</p><p>这是什么原因?.</p><p>static AcDbViewTableRecord GetCurrentView()<br/>{<br/> AcDbViewTableRecord view; <br/> struct resbuf rb; <br/> struct resbuf wcs, ucs, dcs; // 转换坐标时使用的坐标系统标记 <br/> wcs.restype = RTSHORT; <br/> wcs.resval.rint = 0; <br/> ucs.restype = RTSHORT; <br/> ucs.resval.rint = 1; <br/> dcs.restype = RTSHORT; <br/> dcs.resval.rint = 2; <br/> <br/> // 获得当前视口的“查看”模式 <br/> acedGetVar(_T("VIEWMODE"), &rb); <br/> view.setPerspectiveEnabled(rb.resval.rint & 1); <br/> view.setFrontClipEnabled(rb.resval.rint & 2); <br/> view.setBackClipEnabled(rb.resval.rint & 4); <br/> view.setFrontClipAtEye(!(rb.resval.rint & 16)); <br/> // 当前视口中视图的中心点(UCS坐标) <br/> acedGetVar(_T("VIEWCTR"), &rb); <br/> acedTrans(rb.resval.rpoint, &ucs, &dcs, 0, rb.resval.rpoint); <br/> view.setCenterPoint(AcGePoint2d(rb.resval.rpoint,rb.resval.rpoint)); <br/> // 当前视口透视图中的镜头焦距长度(单位为毫米) <br/> acedGetVar(_T("LENSLENGTH"), &rb); <br/> view.setLensLength(rb.resval.rreal); <br/> <br/> // 当前视口中目标点的位置(以 UCS 坐标表示) <br/> acedGetVar(_T("TARGET"), &rb); <br/> acedTrans(rb.resval.rpoint, &ucs, &wcs, 0, rb.resval.rpoint); <br/> view.setTarget(AcGePoint3d(rb.resval.rpoint,rb.resval.rpoint, rb.resval.rpoint));<br/> // 当前视口的观察方向(UCS) <br/> acedGetVar(_T("VIEWDIR"), &rb); <br/> acedTrans(rb.resval.rpoint, &ucs, &wcs, 1, rb.resval.rpoint); <br/> view.setViewDirection(AcGeVector3d(rb.resval.rpoint, rb.resval.rpoint, rb.resval.rpoint)); <br/> <br/> // 当前视口的视图高度(图形单位) <br/> acedGetVar(_T("VIEWSIZE"), &rb); <br/> view.setHeight(rb.resval.rreal); <br/> double height = rb.resval.rreal; <br/> // 以像素为单位的当前视口的大小(X 和 Y 值) <br/> acedGetVar(_T("SCREENSIZE"), &rb); <br/> view.setWidth(rb.resval.rpoint / rb.resval.rpoint * height); <br/> <br/> // 当前视口的视图扭转角 <br/> acedGetVar(_T("VIEWTWIST"), &rb); <br/> view.setViewTwist(rb.resval.rreal); <br/> <br/> // 将模型选项卡或最后一个布局选项卡置为当前 <br/> acedGetVar(_T("TILEMODE"), &rb); <br/> int tileMode = rb.resval.rint; <br/> // 设置当前视口的标识码 <br/> acedGetVar(_T("CVPORT"), &rb); <br/> int cvport = rb.resval.rint;<br/> // 是否是模型空间的视图 <br/> bool paperspace = ((tileMode == 0) && (cvport == 1)) ? true : false; <br/> view.setIsPaperspaceView(paperspace); <br/> <br/> if (!paperspace) <br/> { <br/> // 当前视口中前向剪裁平面到目标平面的偏移量 <br/> acedGetVar(_T("FRONTZ"), &rb); <br/> view.setFrontClipDistance(rb.resval.rreal); <br/> <br/> // 获得当前视口后向剪裁平面到目标平面的偏移值 <br/> acedGetVar(_T("BACKZ"), &rb); <br/> view.setBackClipDistance(rb.resval.rreal); <br/> } <br/> else <br/> { <br/> view.setFrontClipDistance(0.0); <br/> view.setBackClipDistance(0.0); <br/> } <br/> <br/> return view; <br/>}<br/><br/> static void CHAP4ZoomScale(void)//自定义的比例缩放命令,调用了GetCurrentView<br/> {<br/> // Add your code for command CHAP4.ZoomScale here<br/> // 提示用户输入缩放的比例因子 <br/> ads_real scale; <br/> if (acedGetReal(L"\n输入缩放比例因子:", &scale) != RTNORM) <br/> return; <br/> <br/> // 获得当前视图 <br/> AcDbViewTableRecord view = GetCurrentView();</p><p> // 修改视图 <br/> view.setWidth(view.width() / scale); <br/> view.setHeight(view.height() / scale);<br/> // 更新视图 <br/> acedSetCurrentView(&view, NULL); <br/> }<br/></p> <p>加上一句</p><p>acdbHostApplicationServices()->workingDatabase()->updateExt(TRUE);</p> <p>可是加在什么位置呢,我试了好几个地方,还是一样的中断:</p><p>致命错误:Unhandled Access Voliation Reading 0x0004 Exception at 64576927h</p><p>还劳烦楼上相告,谢谢</p><p></p> acedSetCurrentView(&view, NULL); <br/>acdbHostApplicationServices()->workingDatabase()->updateExt(TRUE); 谢谢楼上关注,我又试了一下,让人郁闷的是还是失败了——难道是设置有问题? <p>根据2点缩放窗口的代码,与你比例因素缩放一个道理,可以参考下。</p><p>void Zoom(AcGePoint3d pt1, AcGePoint3d pt2)<br/>{<br/> AcDbViewTableRecord view; <br/> struct resbuf rb; <br/> struct resbuf wcs, dcs, ccs; // ads_trans coord system flags <br/> ads_point vpDir; <br/> ads_point wmin, wmax; // min and max corners of the zoom window <br/> ads_point wdcsmax, wdcsmin; // windows corners in device coords <br/> AcGeVector3d viewDir; <br/> AcGePoint2d cenPt; </p><p> ads_real lenslength,viewtwist,frontz,backz; </p><p> ads_point target; </p><p> int viewmode,tilemode,cvport; </p><p> // Get window to zoom to: </p><p> ads_point pt3 = {pt1.x,pt1.y,pt1.z}, pt4 = {pt2.x,pt2.y,pt2.z}; </p><p><br/> // sort window corners to upper right and lower left <br/> <br/> if (pt3 >= pt4) <br/> { <br/> wmax = pt3; <br/> wmin = pt4; <br/> } <br/> else <br/> { <br/> wmax = pt4; <br/> wmin = pt3; <br/> } </p><p> if (pt3 >= pt4) <br/> { <br/> wmax = pt3; <br/> wmin = pt4; <br/> } <br/> else <br/> { <br/> wmax = pt4; <br/> wmin = pt3; <br/> } </p><p> wmax = 0.0; <br/> wmin = 0.0; </p><p> wcs.restype = RTSHORT; // WORLD coord system flag <br/> wcs.resval.rint = 0; <br/> ccs.restype = RTSHORT; // CURRENT coord system flag <br/> ccs.resval.rint = 1; <br/> dcs.restype = RTSHORT; // DEVICE coord system flag <br/> dcs.resval.rint = 2; </p><p> // Get the 'VPOINT' direction vector <br/> ads_getvar("VIEWDIR", &rb); <br/> ads_trans(rb.resval.rpoint, &ccs, &wcs, 0, vpDir); <br/> viewDir.set(vpDir, vpDir, vpDir); </p><p> // convert upper right window corner to DCS <br/> ads_trans(wmax, &ccs, &dcs, 0, wdcsmax); </p><p> // convert lower left window corner to DCS <br/> ads_trans(wmin, &ccs, &dcs, 0, wdcsmin); <br/> <br/> // calculate and set view center point <br/> cenPt.set(wdcsmin + ((wdcsmax - wdcsmin) / 2.0), <br/> wdcsmin + ((wdcsmax - wdcsmin) / 2.0) ); <br/> view.setCenterPoint(cenPt); </p><p> // set view height and width and direction <br/> view.setHeight(fabs(wdcsmax - wdcsmin)); <br/> view.setWidth(fabs(wdcsmax - wdcsmin)); <br/> view.setViewDirection(viewDir); </p><p> // get and set other properties <br/> ads_getvar("LENSLENGTH", &rb); <br/> lenslength = rb.resval.rreal; <br/> view.setLensLength(lenslength); </p><p> ads_getvar("VIEWTWIST", &rb); <br/> viewtwist = rb.resval.rreal; <br/> view.setViewTwist(viewtwist); </p><p> ads_getvar("FRONTZ", &rb); <br/> frontz = rb.resval.rreal; </p><p> ads_getvar("BACKZ", &rb); <br/> backz = rb.resval.rreal; </p><p> ads_getvar("VIEWMODE", &rb); <br/> viewmode = rb.resval.rint; </p><p> view.setPerspectiveEnabled(viewmode & 1); <br/> view.setFrontClipEnabled(viewmode & 2); <br/> view.setBackClipEnabled(viewmode & 4); <br/> view.setFrontClipAtEye(!(viewmode & 16)); </p><p> ads_getvar("TILEMODE", &rb); <br/> tilemode = rb.resval.rint; <br/> ads_getvar("CVPORT", &rb); <br/> cvport = rb.resval.rint; </p><p> // Paperspace flag <br/> Adesk::Boolean paperspace = <br/> ((tilemode == 0) && (cvport == 1)) ? Adesk::kTrue : Adesk::kFalse; <br/> view.setIsPaperspaceView(paperspace); </p><p> if (Adesk::kFalse == paperspace) <br/> { <br/> view.setFrontClipDistance(frontz); <br/> view.setBackClipDistance(backz); <br/> } <br/> else <br/> { <br/> view.setFrontClipDistance(0.0); <br/> view.setBackClipDistance(0.0); <br/> } <br/> <br/> ads_getvar("TARGET", &rb); <br/> ads_trans(rb.resval.rpoint, &ccs, &wcs, 0, target); <br/> view.setTarget(AcGePoint3d(target, target, target)); </p><p> // update view <br/> acedSetCurrentView( &view, NULL ); <br/>}<br/></p> <p>嗯,可以,谢谢梦幻神话</p> 顶顶顶顶顶顶 我也遇到了这个问题,梦幻神话 的方法是在同一个函数中解决了问题,我是将view做了全局变更解决的,应该是一个意思,想不明白的就是view值为什么不能传递,甚至连传址都不行。 不错的资料, 谢谢楼主分享啊。
页:
[1]