AutoCADecshop二次开发020wbsVS2010配置问题

学习AutoCAD二次开发已经有一段时间了,磕磕碰碰,十分的艰辛枯燥。但回想一下还是会有些小激动,嘿嘿!最近这段时间一直都有这么个想法,就是将我学习CAD二次开发的过程用文字的方式记录下来,形成系列,并定期更新。主要内容就是记录自己每天学习过程中所碰见的问题和感悟,并总结今天所学到的内容。目的一是激励自己坚持下去,看着自己一步一步的提高,多有成就感。还有就是和大家积极沟通,希望能够指正我的错误,减少我的弯路。再者就是望能给后面学习的人一点点借鉴经验,好吧其实还有点装B的心里。废话不多说就进入今天的正题:?&使用工具:Visual Studio 2013和AutoCAD2010?&学习工具:《AutoCAD VBA和VB.NET开发基础和实例教程》C#版、《深入浅出AutoCAD.NET二次开发》、《AutoCAD .net开发人员手册》和网络(目前)?&操作系统:Win10 64位?&开发语言:C#?&软件设置:&&&&&& 1.打开Visual Studio 2013,新建一个【类库】项目;&&&&&& 2.在软件右侧【解决方案资源管理器】(如果没有,在【视图】中选择第一个选项即可)的项目内找到&引用&,右击选择【添加引用】,然后选择【浏览】选项卡,接着找到CAD安装目录下的acdbmgd.dll和acmgd.dll这两个文件,【确定】;&&&&&& 3.在&引用&中找到刚引用的两个文件acdbmgd.dll和acmgd.dll,右击选择属性,将他们【复制本地】的值设为&False&,双击即可更改。顾名思义,如果【复制本地】的值为&True&时,会将这两个文件复制到当前所创建项目下,会导致AutoCAD运行时发生未知错误(其实我也没试过),在【解决方案资源管理器】里可以包含多个类库文件,每个类库里也可以添加多个类文件(.cs)。每次添加新的【类库】时,都要引用acdbmgd.dll和acmgd.dll这两个文件。&&&&&& 4.右击类库名,选择属性,将【应用程序】中&目标框架&里面的内容改为&.NET Framework 3.5&,将【生成】中&目标平台&改为&X64&(这个是根据操作系统来选择的,X86是32位,X64则为64位,貌似不改也可以)。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& AutoCAD .NET与Visual Studio版本对应关系
AutoCAD版本
Visual Studio版本
(R18.0-R18.1)
VS2008 SP1
2012(R18.2)
2013(R19.0)
VS2010 SP1
&&&&& 5.添加命名空间,目的是为了方便调用命名空间中的集成函数,刚看到这得时候也不是很理解,但到后面的具体实例,亲自动手实验了下,就明白了。前几天刚看了教学视频,其中有一句话对我影响很大,他是说不要心疼电脑的键盘,学习编程就要不断的敲击键盘,当你敲坏一个键盘的时候,你就入门了,当你敲得代码有10G的时侯,你就出师了。下面是常用的几个命名空间:Autodesk.AutoCAD.DatabaseS命名空间中的类包括直线、圆、圆弧等,以及层、线型和样式等。Autodesk.AutoCAD.R命名空间中的类提供了系统级别的功能,比如常用的CommandMethod属性。(其实我也没理解)Autodesk.AutoCAD.ApplicationS命名空间中的类用来定义和注册新的AutoCAD命令。Autodesk.AutoCAD.EditorI命名空间提供了与用户交互有关的类,比如提示用户输入等。通过这句话就能理解出命名空间的作用。Autodesk.AutoCAD.C命名空间提供了与颜色有关的类。Autodesk.AutoCAD.G命名空间中的类被用来执行2D和3D的几何操作。&&& 6.要能使能在AutoCAD中能调用命令的方法(比如画直线的命令&L&),执行代码,就需要在类代码开头加入CommandMethod属性。
public class Class1
[CommandMethod("HW")]
public void HW()
&&& 7.打开AutoCAD,输入NETLOAD,浏览项目目录...项目名称\bin\debug文件夹下的dll文件,然后输入相应命令即可。
感谢:《AutoCAD VBA和VB.NET开发基础和实例教程》C#版的作者才鸟,其中大部分知识都是学习这本书上的,再次感谢。我学的时候并没有挨着学习,而是根据具体例子来跳跃学习,具体实例会在今后的日记中说明。
阅读(...) 评论()相关热词搜索:
延伸阅读:
[VS2010]()
[VS2010]()
[VS2010]()
[VS2010]()
[AutoCAD]()
[AutoCAD]()
[AutoCAD]()
[ObjectArx]()
[ObjectArx]()
[ObjectArx]()
[ObjectArx]()
频道总排行
频道本月排行
朱彤说,2011年利比亚东部的万人万里大撤离,可能比电影还要惊心...
一个当时在马耳他等着回美帝的鹰酱写的。作为亲历者,他写的还算...
美国方面测定出,在算上了转换效率、发电效率等一系列能量损失后...
联通和移动的差距在哪里?
“地震云理论”能在民间收获信任,也源于大众的心理需求。
小区里净水机把自来水中本身有的矿物质拿掉了
孩子已超过1 5米,所以不能买儿童票,但是未满16岁,没有身份证...
&娘子&和&相公&这两个词确实存在,但是并非哪个时代的人都会...
文中首先解释了加密解密的一些基础知识和概念,然后通过一个加密...
我们把Kerberos Authentication进行最大限度的简化:整个过程涉...  1、如果要在Winform中打开DWG图形文件,这个Form必须用Application.ShowModelessDialog方式显示,不然会报错(执行环境无效)。
  2、在非模态窗口中修改实体时,需要将图层锁定,否则会报错;模态窗口则无此情况。
  3、写块克隆:WblockCloneObjects第二个参数为块表记录模型空间的ObjectID,此方法会将一个对象集(实体集)完全克隆到另一个DWG文件中,包括图层名、图层设置、坐标位置、扩展数据等。
  4、在CAD中用后台打开方式打开DWG图形文件,并进行修改后,要用SaveAs保存,用Save会出错。
  5、使用模态窗口时,如果需要与CAD主窗体进行交互,则用using (EditorUserInteraction edUI = ed.StartUserInteraction(this));使用非模态窗口时,会出现焦点切换问题&(如:当在非模态窗口中点击按钮后要去CAD中选择一个实体,但是应用程序的焦点还在非模态窗口中,此时需要在CAD主窗口中点击一下让CAD获取焦点,才能正常进行实体选取),此时可以用WinAPI中的SetFocus将焦点移到CAD主窗口即可:
[DllImport("user32.dll", EntryPoint = "SetFocus")]
public static extern int SetFocus(IntPtr hWnd);
  调用:
SetFocus(Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Window.Handle);
  要注意的是:需要配合窗体的MouseEnter、MouseLeave事件使用,但效果并不太理想,如果鼠标移动较快的时候,事件来不及触发。暂时还没有找到其他更好的方法,C++中可以接收一个KeepFocus消息,来监视和设置程序焦点,使焦点转换更灵活,C#中也可以收到CAD发来的这个消息,但是这个消息的Msg值不是固定的,C++中使用的时候不需要管这个值,因为是由CAD已经提供了,所以可以准确地方监听这个消息;但是在C#中CAD并没有提供这个Msg值,所以并不能使用监听Windows消息的方法来实现焦点的切换功能。
  6、AutoCAD.NET获取CAD当前图层代码:
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database.C
  7、AutoCAD 注册表项在32位与64系统中的不同
  AutoCAD注册表信息读取,如获取电脑上已安装的所有CAD版本、安装路径等注册表信息。在32位Windows系统中,这些信息保存在:HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD 中;而64位Windows系统中,32位的CAD软件信息保存在&HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Autodesk\AutoCAD 中,64位CAD软件信息保存在&HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD 中。
  在64位系统中,安装的CAD版本可能是32位,也可能是64位。如果在32位的CAD中调用我们的DLL,此DLL读取&HKEY_LOCAL_MACHINE\SOFTWARE 时,实际读到的是&HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node;如果在64位的CAD中调用我们的DLL,则此时DLL读取 HKEY_LOCAL_MACHINE\SOFTWARE 时,会得到真正的HKEY_LOCAL_MACHINE\SOFTWARE 对象。
  上述情况是因为,为了做到64位系统兼容32位程序,同时又为了防止注册表项冲突,所以32位应用程序在64位Windows系统中操作&HKEY_LOCAL_MACHINE\SOFTWARE 键时会被自动转到&HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node。(具体说明可见:)
  这种问题的解决方法参考:
  较通用的WINAPI方法
  适用.NET 4.0的新方法:
  但是还有一点要注意:在CAD二次开发中,由于我们的DLL最终是要被CAD调用的,所以我们程序集的位数是由CAD的位数来决定的。
  8、修改命令快捷键并立即生效
  在CAD中点击:工具-》自定义-》编辑程序参数(acad.pgp),在打开的文件中找到&Command alias format&,在其下方可以看到命令别名定义列表,定义的格式为:&别名,*命令&,每行只能定义一个,定义完成之后,重启CAD即可生效。如果不想重启CAD,还有两种方式可以让你的定义生效:
  1)、在命令文本中输入reinit,回车,在弹窗中选中&PGP文件&,然后确定,如下图:
  2)、在命令文本中输入re-init,回车,然后输入16,再回车即可。
  第二种方法应该可以在程序中进行实现,不知道AutoCAD.NET中有没有提供现成的方法,不过可以用sendcommand实现。这样可以为用户提供快捷键的自定义功能,并且在用户定义完之后,可以立即生效。acad.pgp文件位置在:CAD安装目录\UserDataCache\Support中,是一个隐藏文件。
  9、eInvalidOpenState错误问题
  当在事务A中调用GetObject方法获取了对象E,在事务A结束之后,如果在另一个事务B中调用E的UpgradeOpen时,会出现错误提示:eInvalidOpenState,这时候需要在事务B中用GetObject根据E.ObjectId重新获取E才行。
  10、eWasNotOpenForWrite错误问题
  同问题情况类似,在事务A中调用GetObject方法获取了对象E,在事务A结束之后,如果在另一个事务B中调用E的DowngradeOpen方法,则会出现错误提示:eWasNotOpenForWrite,这时候需要在事务B中用GetObject根据E.ObjectId重新获取E。
  11、SelectionFilter 根据XData扩展数据过滤选择集问题
  使用根据对象的扩展数据XData进行过滤选择时,如果过滤条件仅为DxfCode.ExtendedDataRegAppName(即注册的应用程序名)时,可以过滤所有类型的对象,但是如果要用DxfCode.ExtendedDataAsciiString、DxfCode.ExtendedDataInteger16等具体数据内容进行过滤时,则仅能选取到部分类型的对象,如:Line、PolyLine、Ellipse、Region,而像DBText、MText、Circle等类型的实体则会被忽略掉。
  12、SelectionFilter过滤选择单行文本对象问题
  用SelectionFilter过滤选择文本时,切记单行文本必须写成TypedValue((int)DxfCode.Start,"Text"),要写成"Text",而不是"DBText"。
  13、用Hatch填充时的问题
  用Hatch填充Region时,如果面域对象是由多个面域合并而来,会填充失败,此时可以调用Region对象的Explode方法将Region炸散,得到多个Region,然后将这些Region一一填充。
  对于Hatch.AppendLoop第二个参数:ObjectIdCollection 类型,传入的是一个或多个实体对象的ID,这些实体必须满足以下几个条件:
  1)、如果只传入一个对象,那么这个对象必须是一个非&回&字型闭合对象,如闭合的pline、单个的Region、Circle、Ellipse等;如果传入的对象是回字型,即中间是空心的,那么将会报错,填充将失败。
  2)、如果传入的是多个对象,那么这些对象必须正好可以首尾相接地组成一个闭合图形,且没有富余的对象,这样才能成功填充;如果组成的图形不能闭合,或者闭合后还剩余一些无用处的线、弧等,又或者组成了多个闭合图形,那么将会报错,填充将失败。
  14、嵌套事务问题
  使用嵌套事务时,好像如果外层的事务不提交,即使里面的事务提交了,最终也会失效,不知道这种说法对不对,因为今天我在里层的事务里创建了一个Hatch并且提交了事务,在代码里看Hatch已经完全创建成功了,但是外层的事务没有提交,结果执行结束后在CAD中完全找不到Hatch的影子。
  15、Autodesk.AutoCAD.DatabaseServices.DataTable 扩展数据表使用时要注意
  当对象实体的扩展字典中还没有这个表时,DBDictionary.SetAt 和&Transaction.AddNewlyCreatedDBObject 将扩展数据表添加到实体对象,但是修改时就不能再这样了,只需要获取DataTable对象,然后用 DataTable.SetCellAt 方法修改数据表的值,最后提交事务即可。(注:向实体扩展字典中添加DataTable时,必须将DataTable添加到BlockTableRecord中,不然在保存CAD图纸的时候,会保存失败)。
  16、PaletteSet停靠。
  PaletteSet可以用程序控制其最小尺寸,停靠位置,可停靠位置,按钮、菜单显示等,但是用程序指定其停靠位置时,每个面板只能占据单独一列或一行,不能做到让多个面板上下同列多行停靠,或左右同行多列停靠。
  PaletteSet有两个重载函数,一般都用第一个,即在声明PaletteSet时只传一个name参数。第二个重载有两个参数,一个是name参数,一个是guid参数,CAD会以这个guid为标识,记录此面板的位置、大小等信息,这样在下一次,加载这个面板的时候,如果不指定面板的Dock属性,则会自动使用上次保存的设置来管理面板的停靠位置和大小等。即:第一次在CAD里加载此面板时,可以给面板指定一个默认的停靠位置,此时用户可以随意拖动面板重新指定停靠位置,当用户关闭CAD时,这个面板的停靠设置会被CAD保存下来,下一次加载的时候,如果不再给此面板指定Dock属性,则会自动使用上次保存的设置信息进行停靠,要实现这一点,最好用PaletteSet的Add和Save事件进行配合(具体实现,)。
  但是,这种实现方式,会有一个问题:如果在声明PaletteSet时指定了传了name参数,CAD会自动创建一个和这个name一样的启动命令,就像每次打开CAD时的&COMMANDLINE&命令一样,每次CAD启动时都会执行,但是我们创建PaletteSet的方法并不一定会声明成为一个命令,而且就算声明成命令,这个命令也不一定和PaletteSet的name参数一样,这样在CAD启动时,就会提示&未知命令&,令人很不爽,解决方法有三种:
  1、将创建PaletteSet的方法声明为一个命令,且命令要和PaletteSet的name参数保持一致,而且你的dll要随CAD自动启动(可以用注册表方法实现),但是这种方法太过狭隘,并不好。
  2、在声明PaletteSet的时候,name参数只传一个空字符串,PaletteSet实例化之后,再为PaletteSet指定Text属性指定面板的名称即可,这样CAD启动时,就不会自动执行命令了。
  3、CAD保存面板停靠信息时,是保存在特殊文件夹Application &Data中的,即C#中的Environment.SpecialFolder.ApplicationData文件夹,比如我在XP系统中用32位CAD 2008测试,保存路径为:C:\Documents and Settings\Administrator\Application Data\Autodesk\AutoCAD \chs\Support\Profiles\FixedProfile.aws,这是一个xml文件。
  如果声明PaletteSet的时候指定了第二个guid参数,CAD会在FixedProfile.aws文件ToolsInfo节点中添加一个Tool节点,用来保存面板信息,同时会在StartupInfo中也添加一个Tool节点,指定启动命令,这个启动命令和PaletteSet的name参数一样,就算在声明PaletteSet的时候传的是一个空字符串,CAD也会在StartupInfo节点下添加一个Command=""的启动命令,CAD启动时,应该是会把空命令忽略,所以使用第二个解决方法,CAD在启动时不会执行面板对应的启动命令,如果你对此有强迫症,不希望CAD保存启动命令节点的话,那么你可以自行将其删除,方法如下:
  在声明PaletteSet的时候,可以随意指定name属性,或干脆留空,这个不再有影响;实现CAD提供的IExtensionApplication接口,此的接口中的Terminate会在你的DLL被卸载时(即CAD被关闭时)执行,我们可以在这个方法内,打开当前CAD对应的FixedProfile.aws文件,然后把StartupInfo节点下面板对应的启动命令删除,此命令和之前声明PaletteSet的时候指定的name参数一样,删除之后,保存FixedProfile.aws文件即可。
  17、Application.ShowModelessDialog在不同版本CAD的调用不同
  在CAD2010之前,这个方法有三个重载:
public static void ShowModelessDialog(Form formToShow);
public static void ShowModelessDialog(IWin32Window owner, Form formToShow);
public static void ShowModelessDialog(IWin32Window owner, Form formToShow, bool persistSizeAndPosition);
  而在CAD2010中,这个方法有五个重载:
public static void ShowModelessDialog(Form formToShow);
public static void ShowModelessDialog(IntPtr owner, Form formToShow);
public static void ShowModelessDialog(IWin32Window owner, Form formToShow);
public static void ShowModelessDialog(IntPtr owner, Form formToShow, bool persistSizeAndPosition);
public static void ShowModelessDialog(IWin32Window owner, Form formToShow, bool persistSizeAndPosition);
  然而,在CAD2010中,第三和第五个重载并没有什么用,因为CAD2010的窗体对象(Application.MainWindow,即Autodesk.AutoCAD.Windows.Window类)不再实现IWin32Window接口,所以第一个参数没办法传了,只能使用第一、二、四个重载方法。这是我目前的研究结果,不知道第三、第五个重载方法在CAD2010中还有没有其他使用方式。
  另外,上面的ShowModelessDialog是针对Winform窗体的,而CAD2010的窗体却都是WPF的,于是在CAD2010中又提供了一个新接口方法:ShowModelessWindow,这个方法也是有五个重载:
public static void ShowModelessWindow(System.Windows.Window formToShow);
public static void ShowModelessWindow(IntPtr owner, System.Windows.Window formToShow);
public static void ShowModelessWindow(System.Windows.Window owner, System.Windows.Window formToShow);
public static void ShowModelessWindow(IntPtr owner, System.Windows.Window formToShow, bool persistSizeAndPosition);
public static void ShowModelessWindow(System.Windows.Window owner, System.Windows.Window formToShow, bool persistSizeAndPosition);
  这个接口方法是用来显示WPF窗体对象的,但是,虽然有五个重载方法,但是应该和ShowModelessDialog一样,只有第一、二、四个方法能正常使用。
  18、不允许所请求的注册表访问权。在win7等64位操作系统中,在CAD调用的C# dll插件中,如果操作注册表(读取、写入等),可能会报这个错误,原因是CAD不是以管理员权限运行的,权限不足,要防止这种情况发生,需要让CAD以管理员身份运行,在CAD的快捷方式或安装目录下的acad.exe上右键,选择&属性&,切换到&兼容性&页面,选中&以管理员身份运行此程序&,这样就不会出现这种情况了。
  另外,对于这种错误,网上还有一种解决方案,是在操作注册表的方法上加上RegistryPermissionAttribute属性标识,如[RegistryPermissionAttribute(SecurityAction.PermitOnly, Read = @"HKEY_LOCAL_MACHINE\SOFTWARE\YourApp")],但是这种情况在CAD开发上好像并不适用,会提示错误。
  19、在使用各种实体对象之后(如DBObject、Entity、Region、Polyline、DBObjectCollection等),尽量主动调用其Dispose方法进行释放,否则当你频繁对一组实体进行重复操作时,可能会引发一些错误,甚至引起CAD的崩溃。比如我碰到的一种情况:/bomb12138/p/4552507.html这里面的第2条。
  20、如果为面域指定了实体颜色,在此面域和其他面域进行了布尔运算之后(面域相加、相减、合并),面域的颜色会变成ByLayer 。
  21、用注册表实现C#DLL或C++ARX随CAD自动加载,可以往以下两个地方添加启动信息:
    1)、HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\RXX.X\ACAD-XXXX:XXX\Applications
    2)、64位系统中的64位CAD 或 32位系统中的CAD:HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\RXX.X\ACAD-XXXX:XXX\Applications
      64位系统中的32位CAD:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Autodesk\AutoCAD\RXX.X\ACAD-XXXX:XXX\Applications
  其中,Current_User项不分32位和64位,而LOCAL_Machine则会分32位和64位,用程序进行注册表读写时需要注意。但是CURRENT_USER注册表信息只对当前登录的系统用户有效,而LOCAL_MACHINE注册表信息则会对系统所有用户都有效。
  C#DLL或C++ARX随CAD启动需要向Applications项中添加一个自己命名的项,然后在该项下添加以下几个值:
DESCRIPTION
程序名称或描述
启动类型(十进制值):
2=随CAD启动加载
4=有命令触发时加载
8=有载入请求时加载
16=从不加载该应用程序
32=显式加载该应该程序
要加载的文件位置
如果是C#DLL,十进制为1,如果是ARX则不添加此项
  LOADCTRLS的值可以单独使用,也可以多个值相加使用,例如:12=4+8=有命令触发时加载或有载入请求时加载。
  另外,如果要使用类型4(有命令触发时加载),除了设置以上几个值之外,还需要在自己创建的应用程序节点下创建新项并注册命令,这样在CAD启动时,不会直接加载DLL或ARX,当注册的命令被触发时,会加载DLL或ARX:
  在自己的应用程序节点下添加&Commands&项,在此项中添加String类型的值,这些值就是注册的命令,例如:
  图中右侧的Fcmd就是我们注册的命令,当启动CAD后,MyAP所指向的程序并不会被直接加载,只有当Fcmd命令被使用的时候,CAD才会加载MyAP程序。
  关于命令注册这个,在官方AutoCAD.NET文档和常见的二次开发书籍中都没有提到,还是无意间从找到的。
  22、用过滤选择进行polyine的时候,类型名必须写成LWPolyline,而要过滤选择polyline2d对象时,类型名要写成polyline。
  23、关于mandEnded事件:正常来说自己定义的命令都应该可以触发CommandEnded事件,但如果你的命令中使用了Application.ShowModelDialog,那么你的命令将不会触发CommandEnded事件,如果把Application.ShowModelDialog换成Form本身的ShowDialog,则可以正常触发CommandEnded事件。
  24、使用VS2010 + AutoCAD2008进行开发时,如果不能调试,可以尝试修改AutoCAD2008安装目录中的acad.exe.config文件:
&configuration&
&!--We always use the latest version of the framework installed on the computer. If you
are having problems then explicitly specify .NET 2.0 by uncommenting the following line.
&supportedRuntime version="v2.0.50727"/&
&supportedRuntime version="v2.0.50727" /&
&/startup&
&/configuration&
&  25、使用SendStringToExecute向CAD发送命令时,如果命令参数中带有路径,这时如果执行有问题,可以尝试使用&/&代替路径中的&\&。
  26、关于在C#中使用P/Invoke方式调用CAD的acedCmd或acedCommand方法发送同步命令,如果这两个接口函数是在自己的自定义命令中调用的,那么可以成功执行,并且是同步的,但如果是在自己的某个窗体程序里调用的,那么可能会执行不成功(接口返回-5001)或者执行成功,但成了异步命令。另外,CAD2013以下版本这两个接口是在acad.exe中的,而从CAD2013开始放到了accore.dll中。
  另外,在CAD中还有一个未公开接口也可以发送同步命令:acedPostCommand,这个命令同样在CAD2013以下版本中是在acad.exe中,从CAD2013开始放到了accore.dll中,另外还有一点不同的是:在CAD2008中它的入口点是&?acedPostCommand@@YAHPB_W@Z&,而从CAD2009开始,它的入口点名称变成了&?acedPostCommand@@YAHPEB_W@Z&,这一点使用的时候需要注意。
  27、AutoCAD2010在打开新图纸时,按ESC键,可能会影响到DocumentManager_DocumentActivated中 CAD操作的执行,具体情况是:
    有一个程序为DocumentManager绑定了DocumentActivated事件,在这个事件中进行图纸扫描,扫描大部分的图形实体。
    在打开测试图纸时,会有一个弹窗:
    此时如何按下ESC来关闭此窗体,那么在窗体关闭之后由于图纸窗口又获取到了焦点,所以会触发DocumentActivated事件,但是之前按的ESC键会影响事件中扫描程序的执行,使程序报错:eUserBreak。
    这个情况只在AutoCAD2010中会出现,在其他版本CAD中测试未发现这种情况,至于在CAD2010中,用了一个简单方法解决了这个问题:创建一个窗体,在创建中放一个定时器,把扫描程序放到定时器中执行,再定义一个公共方法启动定时器,这样在DocumentActivated事件中调用此窗体的公共方法启动定时器进行图纸扫描,这样不不需要弹出窗体就可以完成工作。除了这个方法使用线程或者直接声明定时器也许也能解决这个问题,不过没有进行尝试,不知道行不行得通,等有时间试过之后再更新结果。
  28、当加载的多个DLL或ARX中有同名的自定义命令时,最后在使用时触发的是最后加载的那个程序集中的命令。
  29、如果要创建匿名块(在CAD的块编译器中看不到,但是在BlockTable中可以查找到并可以添加引用显示到图形中,并且不可以手动编辑),只需要在创建BlockTableRecord对象的时候指定其Name为&*U&即可,当把这个BlockTableRecord被成功添加到BlockTable后,会自动会重新分配一个名称,格式为&*U数字&。
  30、关于Database_ObjectModified事件:如果启动了一个事务,且最后没有提交它,那么在这个事务中的所有更改都不生效,且不会触发Database_ObjectModified事件。如果最后提交了这个事务,那么如果在打开对象时是以OpenMode.ForWrite方式打开的,那么不管到底是否对这个对象有更改都会触发Database_ObjectModified事件;而如果在打开对象时是使用的OpenMode.ForRead打开的,后面没有对实体进行修改则不会触发Database_ObjectModified事件,如果后面使用UpgradeOpen升级了读写方式不管到底有没有对实体做出修改,也都会触发Database_ObjectModified事件。
  另外,在此事件内部使用事务时要注意以下两点,否则会弹出崩溃提示:Error handler re-Exiting now
  1.此事件内不能使用嵌套事务。
  2.并且此事件外有其他事务正在被使用时不能再打开新事务。
  31、实体的IntersectWith方法,当参与运算的实体的顶点越多耗时越长,两个实体,当调用此方法的主实体是顶点数较少的那个实体,则耗时会较短,当调用此方法的主实体是顶点数较多的那个实体,则耗时会较长(使用Stopwatch的ElapsedTicks检测)。
  32、在使用Explode接口将实体炸开到一个DBObjectCollection中之后,发现不能直接按从尾到头的顺序去遍历DBObjectCollection,否则会报错(大致意思是说索引超出边界或索引不能为负值),但事实上索引值肯定是没有错的。后来发现,如果将使用正向对DBObjectCollection进行一次遍历,或者按照正向顺序取出DBObjectCollection的前两三个元素(例如DBObject dbo1=dbos[0];DBObject dbo2=dbos[1];先用正向索引读取一下集合的前几个元素),然后再使用倒序方式对DBObjectCollection进行遍历,就不会再提示错误了,这个问题感觉有些不可思议。(在AutoCAD2008中发现的问题,其他版本没有测试)
  33、使用VS调试AutoCAD 版本时,如果出现命中不了断点,且提示&无可用源&,那么可以尝试查看AutoCAD的FIBERWORLD变量的值是否为1,如果是1则可以使用NEXTFIBERWORLD命令将其修改为0,修改完成之后再进行调试即可正常命中断点。()
阅读(...) 评论()

我要回帖

更多关于 二次开发 的文章

 

随机推荐