天天看点

ObjectArx初学者必读

AutoCAD是国内使用比较广泛的CAD绘图软件包, 其R13(R14)版本运行于Windows95平台, 除了更高的执行效率、更友好的用户界面外,功能也有显著的增强,越来越多的工程设计人员开始使用。AutoCAD提供了很强的二次开发语言支持,如AutoLISP,ADS(AutoCAD Development System, 即AutoCAD开发系统,采用C语言编制开发程序), AutoCAD R13版本不仅支持ADS EXE程序,还支持ARX(AutoCAD Runtime eXtension)程序。ARX采用C/C++语言编制,为32位动态连接库(DLL), 在命令执行时动态调用,和ADS EXE程序相比, 可以节约系统的资源,提高运行效率。ARX程序在AutoCAD R13中应用广泛, AutoCAD系统许多模块也采用ARX编制。本文将介绍使用Microsoft Visual C++ 5.0编制ARX程序的方法。

1.采用DOS命令行编译ARX程序

  AutoCAD R13 ARX程序只支持32位Visual C++编译程序, AutoCAD软件提供的编译批处理文件和MAK文件在/R13/COM/ADSRX/SAMPLE目录下, 文件名分别为MKARX.BAT和MKARX.MAK, 这两个文件是为 VC++ 2.1, 2.2编写的, 如果使用VC++ 5.0需要对文件MKARX.BAT进行修改:

  SET MSVCPATH=C:/DevStudio/VC :: VC++5.0的安装路径

  SET ARXPATH=C/R13/COM/ADSRX :: AutoCAD ADSRX的路径

  SET ADSNC=C/R13/COM/ADS :: AutoCAD ADS的路径

  ::SET PATH=%msvcpath%

在VC路径设置语句前加’::’将其屏蔽, 在执行MKARX.BAT批处理命令前先执行VC++ 5.0的环境变量设置批处理命令C:/DevStudio/VC/BIN/VCVARS32.BAT。

  采用DOS命令行编译ARX时C语言源程序采用的扩展名为CC, 以区别普通的C或C++程序, 可以修改文件MKARX.MAK中的"EXT = CC "语句, 将源程序扩展名重新定义。

  对MKARX.BAT修改后,在DOS命令行执行命令

    MKARX 文件名(C语言源程序,不需要扩展名)

就可以编译连接ARX程序了。

2.采用集成编译环境IDE编制ARX程序

  可以在VC++ 5.0的集成编译环境IDE中定制ARX工程文件,然后编译连接,其过程和普通的Win32动态连接库的建立方法相同,不同的是设置必要的编译参数。

 1). 建立工程文件

  从下拉菜单“File”中选择“New”,在出现的对话框中选择“Project”,在列表框中选择“Win32 Dynamic-Link Library”,在“Project Name”编辑框中输入ARX工程文件名,并检查“Location”编辑框中的路径是否正确。如果一切正确,选择“Ok”建立新的工程文件。

  在工程文件中增加文件。从下拉菜单“Project”中选择“Add To Project”中的“Files...”,依次加入源程序文件(.CPP,注意在使用IDE编制ARX程序时,源程序的扩展名应使用C或CPP,而不能使用CC),定义文件(.DEF),资源文件(.RC)和库文件(.LIB)。ARX程序应包含ARX的两个库文件: ACAD.LIB和RXAPI.LIB,文件在目录/R13/COM/ADSRX/LIB中。

 2). 设置编译环境

  从下拉菜单“Project”中选择“Settings...”设置编译环境。在出现的设置对话框中,应该在“Settings for:”中选择设置对“Win32 Debud”和“Win32 Release”均有效。

  选择“C/C++”Tab按钮, 在“Category”中选择“General”,在定义“Preprocessor Definitions”中增加“,RADPACK,ACRXAPP”。 在“Category”中选择“Preprocessor”,在附加的包含文件路径“Additional Include Directories”中增加ADS和ARX的包含文件路径,如 “c:/r13/com/ads;c:/r13/com/adsrx/inc” 。

  选择“Link”Tab按钮, 在“Category”中选择“General”,在输出文件名“Output File Name”中输入ARX文件名并以ARX作为扩展名,否则连接后的文件名将以DLL为扩展名,在AutoCAD中调用不方便。在“Category”中选择“Output”,在基地址“Base Address”中输入“0X1C000000”, 在“Entry-Point Symbol”中输入“[email protected]”,定义库的入口函数。

  至此, 编译环境设置完毕, 选择“Ok”退出设置。

 3). 建立ARX程序

  从下拉菜单“Build”中选择“Build XXX”,开始编译连接ARX程序。如果在连接中出现变量重复定义的错误, 可以将当前活动配置改为“Win32 Release” 后再建立。改动方法为:

  从下拉菜单“Build”中选择“Set Active Configuration...”, 在设置对话框中选择“Win32 Release”后确认。

3. ARX源程序的组成

 1). 定义文件(.DEF)

  ARX程序由C/C++源程序文件和定义文件(.DEF)组成, 也允许包含资源文件(.RC),但ARX程序并不要求必须包含RC文件(注意和R12 WINADS的区别)。定义文件中包含了ARX程序的名称及调用的外部函数,每一个ARX程序必须有定义文件。定义文件的内容如下:

  LIBRARY EX.ARX ;ARX程序名称

  DESCRIPTION 'Autodesk Arx ADS Program' ;ARX程序描述

  EXPORTS ;引用的外部函数, 以下三项内容必须有

   acrxEntryPoint

   _SetacrxPtp

   acrxGetApiVersion 

2). C/C++源程序

  ARX源程序和ADS源程序的结构相同, 只是增加了包含文件和改变了程序的入口函数。在源程序中应包括ARX和ADS的包含文件:

  #include "rxdefs.h"

  #include "adslib.h"

使用以下代码替换ADS源程序的入口函数main:

  extern "C" {

    AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg,void * pkt);

  }

  AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* ptr)

  {

   switch(msg) {

    case AcRx::kInitAppMsg:

     acrxUnlockApplication(ptr);

     break;

    case AcRx::kInvkSubrMsg:

     dofun();

     break;

    case AcRx::kLoadADSMsg:

     funcload();

     break;

    case AcRx::kUnloadADSMsg:

     funcunload();

     ads_printf("Unloading.");

     break;

    case AcRx::kUnloadAppMsg:

     default: break;

    }

   return AcRx::kRetOK;

  }

  以上代码可以在/R13/COM/ADSRX/SAMPLE目录中的ARX示例程序(如FACT.CC)中找到。

4.在ARX程序中使用Windows资源

  在ARX程序中使用Windows(包括Windows 95)资源,可以减少开发工作量,提供更友好的工作界面。特别是和AutoCAD对话框DCL相比,Windows对话框具有编制方便、执行效率高而文件数少、丰富灵活的控制方法等优点。但在AutoCAD R13提供的帮助文件和示例程序中,都未提到在ARX程序中使用Windows对话框的方法,下面介绍笔者摸索出来的方法。

 1). 包含Windows头文件

  在源程序中必须包含Windows头文件WINDOWS.H。但要注意, 由于ADS头文件ADS.H(由ADSLIB.H调用)和WINUSER.H中都定义了X,Y而且定义不同, 为了避免编译错误, 必须先包含WINDOWS.H, 后包含ARX的头文件, 即包含头文件的顺序为:

  #include //先包含WINDOWS.H

  #include "rxdefs.h" //后包含ARX的头文件

  #include "adslib.h"

 2). 建立对话框处理过程

  ARX程序中的对话框处理过程和Windows程序中的对话框过程相同,其代码为:

  //对话框处理示例

  LRESULT WINAPI ExDlg(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)

  {

   switch(msg) {

    case WM_INITDIALOG:

     return(FALSE);

    case WM_COMMAND:

     switch(LOWORD(wParam)) {

      case 101:

       EndDialog(hDlg,FALSE); return(FALSE); }

   }

   return(FALSE);

  }

  注意WIN32和16位Windows程序中处理WM_COMMAND消息的区别。

 3). 建立对话框过程

  在Windows程序中创建一个对话框过程通常调用函数DialogBox,其函数原型为:

  int DialogBox(hInstance,lpTempName,hWndParent,lpDlgFunc)

  各参数的含义如下:

  hInstance 模块的实例句柄

  lpTempName 对话框名称,在资源文件中定义

  hWndParent 拥有对话框的父窗口句柄

  lpDlgFunc 对话框处理过程函数

  从DialogBox的参数中可以看出, 对话框名称和处理函数已经具备,可以直接引用,父窗口句柄可以设置为NULL, 关键在于模块实例句柄的确定(实例句柄不能设置为NULL, 否则对话框不会显示)。在常规的WIN32动态连接库(DLL)设计中,可以选取DLL的句柄作为实例句柄,该句柄可以从DLL的入口函数DllMain中获得。但是对于ARX程序, 其入口函数由AutoCAD定义,并且在定义文件中没有完整的类的说明, 所以实例句柄不能直接从入口函数中获取。

  经过笔者摸索, 我发现可以采取以下方法获取实例句柄, 即通过获取ARX程序模块的实例句柄作为创建对话框的实例句柄。具体实现代码如下:

  HANDLE hInst; //定义实例句柄变量

  BOOL rc; //对话框执行返回结果

  ... ...

  hInst=GetModuleHandle("EX.ARX"); //获取ARX模块的句柄, 将其中

  //的EX.ARX设置为当前ARX程序名

  rc=DialogBox(hInst,"EX",NULL,(DLGPROC)ExDlg); //创建对话框

  ..... //其他处理过程

  使用以上方法编制的ARX程序在AutoCAD中运行正常。

继续阅读