AutoCAD的二次开发主要涉及以下内容:(1)编写各种用户自定义函数并形成若干LISP、ARX、VLX或ADS文件,以及一些DCL文件。(2)建立符合自己要求的菜单文件,一般可在AutoCAD原菜单文件内添加自己的内容,对于AutoCAD2000版本还可增加部分菜单文件,然后经交互方式加入到系统中去。(3)在系统的ACAD.LSP或类似文件中加入某些内容以便进行各种初始化操作,如在启动时立即装入一些文件等。(4)通过系统对话框设置某些路径。这些操作在程序开发成功后向其它AutoCAD系统上安装应用,特别是需要大批安装时,需要进行很多文件检索、内容增删、子目录创建、文件拷贝、系统设置等繁琐工作,如能令上述工作全部自动进行,使整个二次开发程序在无人干预的情况下嵌入系统,将大大提高工作效率。为此笔者用VC++开发了一套自动安装程序,使原本需要五、六分钟的人工操作在十几秒内即可自动完成。

  一、 基本思路

  整个安装程序遵循以下思路:

  1) 首先获得所在机器AutoCAD2000系统的安装路径;

  2) 寻找菜单文件AutoCAD2000supportacad.mnu,打开文件并将要添加的内容加至末尾;

  3) 寻找LISP文件AutoCAD2000supportacad2000doc.lsp,打开文件并将要添加的内容加至末尾;

  4) 创建一个预先命名的子目录,将所有二次开发形成的各类文件拷入;

  5) 给出信息框,告知安装成功,如有问题则告知安装失败。

  需要指出的是,在添入acad2000doc.lsp的内容中须有如下语句:

  (command“_menu”(strcat (getvar "menuname") ".mnu")),目的是为了强制执行菜单文件装入命令,将改动后的acad.mnu文件编译后装入。

  另外,在添入acad2000doc.lsp的内容中还有一赋值语句,将准备创建的包含所有二次开发生成文件的子目录全路径名赋予一全局变量,以供二次开发程序在需要时调用,从而避免了在AutoCAD环境下交互设定路径的麻烦。

  二、 实现方式及关键函数

  为获得AutoCAD2000的安装路径,需要利用WINDOWS系统注册表的有关功能。

  首先通过RegOpenKey函数打开注册表:

  HKEY hKey;

  LONGret=RegOpenKey( HKEY_LOCAL_MACHINE, "SoftwareAutodeskAutoCADR14.0ACAD-1:804", &hKey);

  其中第一参数HKEY_LOCAL-MACHINE为注册表中预定义的主键句柄,第二参数为注册表中HKEY_LOCAL_MACHINE下的子键内容,第三参数hKey将返回一子键句柄,用于接下来的键值查询。若该函数运行成功,将返回一长整型数ERROR_SUCCESS。

  接下来利用RegQueryValueEx函数进行键值查询:

  DWORD dwType=REG_SZ;

  BYTE szData[100];

  DWORD dwSize=sizeof(szData);

  If (ret=ERROR_SUCCESS)

  ret=RegQueryValueEx(hKey, "AcadLocation", 0, &dwType, szData, &dwSize);

  其中第一参数hKey为由RegOpenKey函数获得的欲查询的子键句柄;第二参数“AcadLocation”为欲查询的键值名;第三参数为保留项,要求添0;第四参数为键值数据类型;第六参数为键值缓冲器容量;最关键的是第五参数szData,欲查询的键值结果将由其带回,该键值即为所需要的AutoCAD2000的安装路径。

  以上涉及到的有关注册表中主键、子键、键值名、及键值的关系可通过下列方法由WINDOWS系列注册表查出:单击“开始”――“运行”――添入“regedit”――“确定”――“HKEY_LOCAL_MACHINE”――“Software”――“Autodesk”――“Autocad”――“R15.0”――“ACAD-1:804”――“AcadLocation”――“e:autocad2000”。其中的键值名“AcadLocation”所对应的键值为“e:autocad2000”,就是AutoCAD2000的安装路径,在不同的机器上可能内容不同。

  键值查询函数若运行成功,将返回长整型数ERROR_SUCCESS。

  下面可利用szData带回的路径名与已知路径名组合成全路径从而打开菜单文件acad.mnu添加内容:

  char szRootName[100]=supportacad.mnu;

  if (ret=ERROR_SUCCESS)

  1strcat((char*) szData, szRootName);

  现在szData中装有acad.mnu的全路径,以下操作将打开该文件并添入内容:

  HANDLE hfile=CreateFile((char*) szData, GENERIC_READ|GENERIC_WRITE, 0,

  NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

  If(hfile!=INVALID_HANDLE_VALUE)

  {

  if (0xFFFFFFFF!=SetFilePointer(hfile, 0, NULL, FILE_END))

  {

  char szBuf[1000]="

  ***POP12

  **CAM

  [&CAM]

  [->基本参数]

  [卡盘原点]^c^cchuck_datam

  [换刀原点] ^c^ctool_datam

  [<-毛坯参数] ^c^cstock

  [工步设计] ^c^csteps

  [仿真加工] ^c^csimulation

  [代码生成] ^c^cgen_code

  [代码存盘] ^c^ccode_save

  [工艺存盘] ^c^csave_inf

  [工艺装入] ^c^cload_inf

  [->刀具管理]

  《创建新刀》 ^c^ccreate_new_tool

  [<-刀库增删] ^c^ctool_manage

  ";

  DWORD dwWrite=0;

  BRet=WriteFile(hfile, szBuf, Lstrlen(szBuf), &dwWrite, NULL);

  If (!bRet) Printerror();

  }

  CloseHandle(hfile);

  }

  上述操作中用CreateFile函数打开文件,SetFilePointer函数将指针移至文件末尾,字符串数组szBuf中装有欲添加的内容,以WriteFile函数写入,PrintError为自编的错误处理函数。

  以同样的方法可以找到acad2000doc.lsp文件并添入内容。

  以下操作将创建一个名为“C:hkcam”的子目录,并将事先准备好的本程序所在目录下的所有文件拷贝进去:

  Cstring nam1, nam2;

  BOOL bCreate=CreateDirectory("C:hkcam", NULL);//创建子目录

  CfileFind finder; //创建类对象


  BOOL b Working=finder.FindFile("*.*");//利用类函数搜索所有文件

  While(b Working)//循环搜索及文件拷贝

  {

  b Working=finder.FindNextFile();

  nam1= finder.GetFileName();//获得文件名

  nam2= " c:hkcam";

  nam2=nam2+nam1;//组成全路径

  BOOL bCopy=CopyFile(nam1, nam2, FALSE);//文件拷贝

  }

  所有操作成功后,以信息框告知:

  MessageBox( NULL,“安装成功,请按OK钮继续”,“安装结果”,MB_OK);

  整个程序以MFC静态链接库创建。上述所有内容可以写入一个源文件内,这里称其为Append.cpp。为使最终执行文件尽可能小,应删去程序框架中所有不需要的内容。为此,源文件中只保留Append.cpp,Append.rc,及StdAfx.cpp几项;而头文件中只有Append.h,Resource.h,及StdAfx.h几项。所定义的唯一派生类为class CappendApp:public CwinApp,置于Append.h之内。

  三、结束语

  在VC++环境下利用有关WINDOWS系统注册表操作函数获得AutoCAD系统的安装路径,从而找出并改写AutoCAD有关文件;创建子目录并拷入各种二次开发形成文件,由此实现了AutoCAD二次开发程序与AutoCAD系统的自动衔接与嵌入。文中程序已由实践验证,完全可用于AutoCAD二次开发程序的自动安装。