1、ObjectARX 开发环境的创建与开发实例 Hello World(VS2005+AutoCad2008+ObjectArx2008) 在一个做 CAD 二次开发的公司做 Web 开发,感觉可提升的空间很小。有必要研究一下公司的产品开发,以利发展。一、首先安装好 vs05 与 cad2008安装 cad 的时候也没有什么特别,加载到虚拟光驱,安装过程中有个错误提示,不影响继续。二、安装 ObjectArx2008 直接打开解压缩到某个目录即可。比如 C:ObjectARX 2008然后打开 C:ObjectARX 2008utilsObjARXWiz 目录,运行 ArxWizards.msi
2、这样在新建 C+项目的时候会出现 ObjectARX 项目,如图三、包含文件工具-选项-项目和解决方案-VC+目录,如图所示:包含文件(添加图中前两个目录即可)库文件(添加图中前两个目录即可)四、新建 ObjectARX 项目,完成后添加 MFC 支持,如图所示:然后直接点 finish打开 acrxEntryPoint.cpp 点击左上角的 a按钮,然后新建一个命令。如图:只需要修改 Internation Name 与 Localized Name 为 testcmd 即可添加完成后,会在 acrxEntryPoint.cpp 中自动添加一句如下的代码:然后添加一句 AfxMessageB
3、ox(_T(“this is a test command.“);五、加载与运行在项目中 win32debug 目录下,把 ArxProject2.arx 复制到桌面,注意先生成一下。打开 cad08 输入命令:ap 打开加载对话框。找到.arx 文件即可加载。如图:然后输入自己的命令 testcmd 就能运行了。如图:公司高手如云,希望能在 CAD 二次开发方面有些发展。转行也行,呵呵。凡事以大气象去面对,优秀是一种习惯。 CAD 二次开发学习笔记一(画一条直接) ARX 内部是不需要调用 cad 命令的。调用 ARX 函数或对象就可以象 CAD 一样绘制、编辑实体。在 AutoCAD 中画
4、直接的命令是line0,01000,100通过 ObjectARX 画,新建一个命令 cmd1 代码如下:代码 / - ArxProject2.cmd1 commandstatic void ArxProject2cmd1(void)/ Add your code for command ArxProject2._MyCommand1 hereacutPrintf(_T(“Hello World“);/在内存上创建一个新的 AcDbLine 对象AcGePoint3d ptStart(0,0,0);AcGePoint3d ptEnd(10000,10000,0);AcDbLine *pLine
5、 = new AcDbLine(ptStart,ptEnd);/*基于 AutoCAD 内部的实现机制,必须在堆上创建对象。acdbHostApplicationServices()-workingDatabase()获得指向当前活动的图形数据库的指针。*/获得指向块表的指针AcDbBlockTable *pBlockTable;acdbHostApplicationServices()-workingDatabase()-getBlockTable(pBlockTable,AcDb:kForRead);/获得指向特定的块表记录(模型空间) 的指针AcDbBlockTableRecord *p
6、BlockTableRecord;pBlockTable-getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb:kForWrite);/将 AcDbLine 类的对象添加到块表记录中AcDbObjectId lineId;pBlockTableRecord-appendAcDbEntity(lineId,pLine);/关闭图形数据库的各种对象pBlockTable-close();pBlockTableRecord-close();pLine-close();ap 加载然后 cmd1 运行。凡事以大气象去面对,优秀是一种习惯。 CAD 二次开发学习笔记二
7、(创建一个对话框) 打开资源视图-右击-添加资源-Dialog双击对话框,弹出 MFC 类向导,输入类名 FirstClass,确定,创建对话框类。FirstClass.h 与 FirstClass.cpp需要在 FirstClass.h 中包含#include “Resource.h“代码如下:大气象 #pragma once/ FirstClass 对话框#include “Resource.h“/这里包含资源头文件class FirstClass : public CDialogDECLARE_DYNAMIC(FirstClass)public:FirstClass(CWnd* pPar
8、ent = NULL); / 标准构造函数virtual FirstClass();/ 对话框数据enum IDD = IDD_DIALOG1 ;protected:virtual void DoDataExchange(CDataExchange* pDX); / DDX/DDV 支持DECLARE_MESSAGE_MAP();新建一个 cad 命令,在 acrxEntryPoint.cpp 添加如下代码:大气象 static void ArxProject2cmd2(void)/ Add your code for command ArxProject2.cmd2 here/*cad 维护
9、的有自己的资源空间,我们添加对话框的时候,使用的是自己的资源空间,这个相当于通知 cad 准备下可能要开新的资源空间。这两个混一块一般没问题,但是如果出问题,就非常难找了,所以一般在命令中直接调用对话框中时,都要加上。*/CAcModuleResourceOverride myResources;FirstClass Dlg;Dlg.DoModal();记得包含对话框头文件#include “FirstClass.h“然后 ap 加载 cmd2 运行凡事以大气象去面对,优秀是一种习惯。 CAD 二次开发学习笔记三(封装添加实体到数据库函数 ) 学会查看 ObjectARX 帮助文档。AcGe
10、开头图形计算。AcDb 图形数据库。在 acrxEntryPoint.cpp 添加如下代码: 大气象 /将实体添加到数据库/cad 中的实体最终都要添加到数据库中才能被显示(图纸其实是一个数据库格式的),所以它的作用就是添加实体到数据库中static Acad:ErrorStatus AddToDb(AcDbEntity* ent, AcDbObjectIdAcDbBlockTable* pBlockTable;AcDbBlockTableRecord* pSpaceRecord;if (es = acdbHostApplicationServices()-workingDatabase()-
11、getBlockTable(pBlockTable, AcDb:kForRead)!= Acad:eOk) return es;if (es = pBlockTable-getAt(ACDB_MODEL_SPACE, pSpaceRecord,AcDb:kForWrite) != Acad:eOk) return es;if (es = pBlockTable-close() != Acad:eOk) return es;if (es = pSpaceRecord-appendAcDbEntity(objId, ent) != Acad:eOk) return es;return pSpace
12、Record-close();public:/ - ArxProject2.cmd3 command (do not rename)static void ArxProject2cmd3(void)/ Add your code for command ArxProject2.cmd3 hereAcGePoint3d ptStart(0,0,0);AcDbCircle *pCircle=new AcDbCircle();pCircle-setCenter(ptStart);pCircle-setRadius(1000);/也可以这样定义圆/AcDbCircle *pCircle=new AcD
13、bCircle(ptStart,AcGeVector3d(0,0,1),100);AcDbObjectId circleId;/调用画实体函数if(AddToDb(pCircle,circleId)!=Acad:eOk)/传入指针,传出 idAfxMessageBox( _T(“加入实体到数据库失败! “);pCircle-close();凡事以大气象去面对,优秀是一种习惯。 CAD 二次开发学习笔记四(得到选中的实体,修改实体,如等分线段 ) AcGeVector3d 是点阵的集合,通过等分点的差集得到。新的点可以通过点与点阵相差得到。大气象 public:/ - ArxProject2.p
14、artLine command (do not rename)static void ArxProject2partLine(void)/ Add your code for command ArxProject2.partLine hereads_name entName;ads_point pt;acedEntSel( _T(“n 选择:“),entName,pt);/得到选中的实体AcDbObjectId ObjId;/得到实体 IDif( acdbGetObjectId(ObjId,entName) != Acad:eOk )/如果没有选中的实体则返回acutPrintf( _T(“n
15、no“);return;AcDbEntity* pEnt;/得到实体if( acdbOpenObject(pEnt,ObjId,AcDb:kForRead) = Acad:eOk)acutPrintf( _T(“nok“);AcDbLine* pLine = (AcDbLine* )pEnt;/强制转换AcGePoint3d ptStart = pLine-startPoint();/得到起点AcGePoint3d ptEnd = pLine-endPoint();pEnt-close();/根据点和线的方向生成点组,绘制线段int nPart = 5;/五等分AcGeVector3d Vec
16、t = (ptEnd - ptStart)/nPart;/矩阵,点与点的差集平分可得到for (int n=0; nerase();pEnt-close();/将实体添加到数据库/cad 中的实体最终都要添加到数据库中才能被显示(图纸其实是一个数据库格式的),所以它的作用就是添加实体到数据库中static Acad:ErrorStatus AddToDb(AcDbEntity* ent, AcDbObjectIdAcDbBlockTable* pBlockTable;AcDbBlockTableRecord* pSpaceRecord;if (es = acdbHostApplicationS
17、ervices()-workingDatabase()-getBlockTable(pBlockTable, AcDb:kForRead)!= Acad:eOk) return es;if (es = pBlockTable-getAt(ACDB_MODEL_SPACE, pSpaceRecord,AcDb:kForWrite) != Acad:eOk) return es;if (es = pBlockTable-close() != Acad:eOk) return es;if (es = pSpaceRecord-appendAcDbEntity(objId, ent) != Acad:
18、eOk) return es;return pSpaceRecord-close();private:/画线函数static void MakeLine(AcGePoint3d ptStart,AcGePoint3d ptEnd,AcDbObjectId lineId)AcDbLine *pLine = new AcDbLine(ptStart,ptEnd);if(AddToDb(pLine,lineId)!=Acad:eOk)/传入指针,传出 idAfxMessageBox( _T(“加入实体到数据库失败! “);pLine-close();另外是几个 CAD 用法:1.移动命令的使用输入
19、m 然后选择线段,或者线段的端点,就出现移动的辅助线。2.ap 可以加载也可以卸载,选中要卸载的。凡事以大气象去面对,优秀是一种习惯。 CAD 二次开发学习笔记五(在 ObjectARX 中使用 MFC) 要实现的功能是:执行 ArxModal 命令,弹出如图所示对话框选择点,则得到点坐标,选择角度则得到角度值。步骤一:新建基于 MFC 的 ObjectArx 项目,参考:http:/ ID 修改为 IDD_ARX_MODAL(右击资源视图中的对话框打开属性面板,可以修改 ID)设计如图界面,ID 如下:IDC_BUTTON_POINTIDC_BUTTON_ANGLEIDC_EDIT_XPTI
20、DC_EDIT_YPTIDC_EDIT_ZPTIDC_EDIT_ANGLE选择两个 Button 把 Owner Draw 设置为 True完成界面。步骤二:打开类视图,右击项目-添加类(这里不是右击对话框添加类)这张图有点小错误,这里 Dialog ID:IDD_ARX_MODAL Class name:CArxDialog在类视图中右击 CArxDialog 类添加变量这样会在头文件中生成源文件中生成根据这个规律添加其他变量大气象 private:CAcUiPickButton m_btnAngle;CAcUiPickButton m_btnPoint;CAcUiNumericEdit m
21、_editXpt;CAcUiNumericEdit m_editYpt;CAcUiNumericEdit m_editZpt;CAcUiAngleEdit m_editAngle;void CArxDialog:DoDataExchange (CDataExchange *pDX) CAcUiDialog:DoDataExchange (pDX) ;DDX_Control(pDX, IDC_BUTTON_ANGLE, m_btnAngle);DDX_Control(pDX, IDC_BUTTON_POINT, m_btnPoint);DDX_Control(pDX, IDC_EDIT_XPT,
22、 m_editXpt);DDX_Control(pDX, IDC_EDIT_YPT, m_editYpt);DDX_Control(pDX, IDC_EDIT_ZPT, m_editZpt);DDX_Control(pDX, IDC_EDIT_ANGLE, m_editAngle);步骤三:为 CArxDialog 添加 InitDialog 消息响应。方法是打开类视图,右击-属性再添加 OnClose()响应函数在头文件中添加几个变量public:CString m_strAngle;CString m_strZPt;CString m_strYPt;CString m_strXPt;在头文
23、件中定义两函数void DisplayPoint();void DisplayAngle();分别为两个按钮添加单击事件,为四个编辑框添加失去焦点事件。步骤四:打开 acrxEntryPoint.cpp 添加#include “ArxDialog.h”运行结果如图源码如下acrxEntryPoint.cpp / (C) Copyright 2002-2005 by Autodesk, Inc. / Permission to use, copy, modify, and distribute this software in/ object code form for any purpose
24、and without fee is hereby granted, / provided that the above copyright notice appears in all copies and / that both that copyright notice and the limited warranty and/ restricted rights notice below appear in all supporting / documentation./ AUTODESK PROVIDES THIS PROGRAM “AS IS“ AND WITH ALL FAULTS
25、. / AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF/ MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. / DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE/ UNINTERRUPTED OR ERROR FREE./ Use, duplication, or disclosure by the U.S. Government is subject to / restrictions
26、 set forth in FAR 52.227-19 (Commercial Computer/ Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)/ (Rights in Technical Data and Computer Software), as applicable./-/- acrxEntryPoint.h/-#include “StdAfx.h“#include “resource.h“#include “ArxDialog.h“/-#define szRDS _RXST(“)/-/- ObjectARX
27、 EntryPointclass CCADMFCApp : public AcRxArxApp public:CCADMFCApp () : AcRxArxApp () virtual AcRx:AppRetCode On_kInitAppMsg (void *pkt) / TODO: Load dependencies here/ You *must* call On_kInitAppMsg hereAcRx:AppRetCode retCode =AcRxArxApp:On_kInitAppMsg (pkt) ;/ TODO: Add your initialization code he
28、rereturn (retCode) ;virtual AcRx:AppRetCode On_kUnloadAppMsg (void *pkt) / TODO: Add your code here/ You *must* call On_kUnloadAppMsg hereAcRx:AppRetCode retCode =AcRxArxApp:On_kUnloadAppMsg (pkt) ;/ TODO: Unload dependencies herereturn (retCode) ;virtual void RegisterServerComponents () / - CADMFC.
29、showDlg command (do not rename)static void CADMFCshowDlg(void)/ Add your code for command CADMFC.showDlg here/防止资源冲突CAcModuleResourceOverride resOverride;/显示 ObjectARX 的模态对话框CArxDialog theDialog;theDialog.DoModal(); ;/-IMPLEMENT_ARX_ENTRYPOINT(CCADMFCApp)ACED_ARXCOMMAND_ENTRY_AUTO(CCADMFCApp, CADMFC
30、, showDlg, MyCommand1, ACRX_CMD_TRANSPARENT, NULL)ArxDialog.h / (C) Copyright 2002-2005 by Autodesk, Inc. / Permission to use, copy, modify, and distribute this software in/ object code form for any purpose and without fee is hereby granted, / provided that the above copyright notice appears in all
31、copies and / that both that copyright notice and the limited warranty and/ restricted rights notice below appear in all supporting / documentation./ AUTODESK PROVIDES THIS PROGRAM “AS IS“ AND WITH ALL FAULTS. / AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF/ MERCHANTABILITY OR FITNESS FOR A
32、 PARTICULAR USE. AUTODESK, INC. / DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE/ UNINTERRUPTED OR ERROR FREE./ Use, duplication, or disclosure by the U.S. Government is subject to / restrictions set forth in FAR 52.227-19 (Commercial Computer/ Software - Restricted Rights) and DFAR 252.
33、227-7013(c)(1)(ii)/ (Rights in Technical Data and Computer Software), as applicable./-/- ArxDialog.h : Declaration of the CArxDialog/-#pragma once/-#include “acui.h“/-class CArxDialog : public CAcUiDialog DECLARE_DYNAMIC (CArxDialog)public:CArxDialog (CWnd *pParent =NULL, HINSTANCE hInstance =NULL)
34、;enum IDD = IDD_ARX_MODAL ;protected:virtual void DoDataExchange (CDataExchange *pDX) ;afx_msg LRESULT OnAcadKeepFocus (WPARAM, LPARAM) ;DECLARE_MESSAGE_MAP()private:CAcUiPickButton m_btnAngle;CAcUiPickButton m_btnPoint;CAcUiNumericEdit m_editXpt;CAcUiNumericEdit m_editYpt;CAcUiNumericEdit m_editZpt
35、;CAcUiAngleEdit m_editAngle;public:virtual BOOL OnInitDialog();afx_msg void OnClose();public:CString m_strAngle;CString m_strZPt;CString m_strYPt;CString m_strXPt;void DisplayPoint();void DisplayAngle();afx_msg void OnBnClickedButtonPoint();afx_msg void OnBnClickedButtonAngle();afx_msg void OnEnKill
36、focusEditXpt();afx_msg void OnEnKillfocusEditYpt();afx_msg void OnEnKillfocusEditZpt();afx_msg void OnEnKillfocusEditAngle(); ;ArxDialog.cpp / (C) Copyright 2002-2005 by Autodesk, Inc. / Permission to use, copy, modify, and distribute this software in/ object code form for any purpose and without fe
37、e is hereby granted, / provided that the above copyright notice appears in all copies and / that both that copyright notice and the limited warranty and/ restricted rights notice below appear in all supporting / documentation./ AUTODESK PROVIDES THIS PROGRAM “AS IS“ AND WITH ALL FAULTS. / AUTODESK S
38、PECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF/ MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. / DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE/ UNINTERRUPTED OR ERROR FREE./ Use, duplication, or disclosure by the U.S. Government is subject to / restrictions set forth in
39、FAR 52.227-19 (Commercial Computer/ Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)/ (Rights in Technical Data and Computer Software), as applicable./-/- ArxDialog.cpp : Implementation of CArxDialog/-#include “StdAfx.h“#include “resource.h“#include “ArxDialog.h“/-IMPLEMENT_DYNAMIC (CAr
40、xDialog, CAcUiDialog)BEGIN_MESSAGE_MAP(CArxDialog, CAcUiDialog)ON_MESSAGE(WM_ACAD_KEEPFOCUS, OnAcadKeepFocus)ON_WM_CLOSE()ON_BN_CLICKED(IDC_BUTTON_POINT, DDX_Control(pDX, IDC_BUTTON_ANGLE, m_btnAngle);DDX_Control(pDX, IDC_BUTTON_POINT, m_btnPoint);DDX_Control(pDX, IDC_EDIT_XPT, m_editXpt);DDX_Contro
41、l(pDX, IDC_EDIT_YPT, m_editYpt);DDX_Control(pDX, IDC_EDIT_ZPT, m_editZpt);DDX_Control(pDX, IDC_EDIT_ANGLE, m_editAngle);/-/- Needed for modeless dialogs to keep focus./- Return FALSE to not keep the focus, return TRUE to keep the focusLRESULT CArxDialog:OnAcadKeepFocus (WPARAM, LPARAM) return (TRUE)
42、 ;BOOL CArxDialog:OnInitDialog()CAcUiDialog:OnInitDialog();/ TODO: 在此添加额外的初始化/设置点的范围m_editXpt.SetRange(-100.0,100.0);m_editYpt.SetRange(-100.0,100.0);m_editZpt.SetRange(-100.0,100.0);/设置角度的输入范围m_editAngle.SetRange(0.0,90.0);/加载默认的位图m_btnPoint.AutoLoad();m_btnAngle.AutoLoad();/设置文本框的默认值m_strAngle = _
43、T(“0.0“);m_strXPt = _T(“0.0“);m_strYPt = _T(“0.0“);m_strZPt = _T(“0.0“);/显示初始点的坐标和角度值DisplayPoint();DisplayAngle();return TRUE; / return TRUE unless you set the focus to a control/ 异常: OCX 属性页应返回 FALSEvoid CArxDialog:DisplayPoint()/在对话框中显示点的坐标m_editXpt.SetWindowText(m_strXPt);m_editXpt.Convert();/更新
44、控件和其关联的成员变量m_editYpt.SetWindowText(m_strYPt);m_editYpt.Convert();m_editZpt.SetWindowText(m_strZPt);m_editZpt.Convert();void CArxDialog:DisplayAngle()m_editAngle.SetWindowText(m_strAngle);m_editAngle.Convert();void CArxDialog:OnClose()/ TODO: 在此添加消息处理程序代码和/或调用默认值/double x=atof(m_strXPt);/错误 1 error C
45、2664: “atof”: 不能将参数 1从“CString” 转换为“const char *”double x=_tstof(m_strXPt);double y=_tstof(m_strYPt);double z=_tstof(m_strZPt);acutPrintf(_T(“n 选择的点坐标为(%.2f,%.2f,%.2f).“),x,y,z);CAcUiDialog:OnClose();void CArxDialog:OnBnClickedButtonPoint()/ TODO: 在此添加控件通知处理程序代码/隐藏对话框把控制权交给 AutoCadBeginEditorCommand();/提示用户输入一个点ads_point pt;if(acedGetPoint(NULL,_T(“n 输入一个点:“),pt)=RTNORM)/如果点有效,继续执行Com