找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1548|回复: 0

CAD控件: 命令执行原理

[复制链接]
发表于 2015-3-18 15:42:14 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
软件名称:梦,想,,CAD,,控件。。
1.        说明:        3
2.        COM接口的命令执行        3
1.1、 比如C#语言:        4
1.2、 比如JS语言        5
1.3、 在工具条定义文件中执行用户命令        6
1.4、 在菜单条中执行用户命令        6
1.5、 为命令注册一个命令名称,方便命令输入和调用        7
1.6、 调用控件自带命令        7
1.7、 在命令执行中,再调用另一个命令        8
3.        VC接口的命令执行        10

1.说明:
在控件中,所有与用户交到的操作函数,都必须放在命令执行事件中调用。
因为与用户交互操作时,控件会启动一个临时的windows消息循环,这样执行交互函数时,会临时等待用户操作,在事件退出时,控件就有机会控制临时信息消息循环的退出处理。
比如在等待用户交到操作过程中,如果用户点击了窗口上关闭按钮结束程序,或点击了另一个按钮,又重新执行一个命令,这些都需要控件在事件结束时自动处理,防止出错。

2.COM接口的命令执行
DoCommand说明:
该函数开始执行控件的一个用户自定义命令,参数是命令的id,这个id值可以随便取值,它是用来标识该命令,多个命令之间,id值不能重复
前面的DoCommand的调用后,程序将会跳转命令执行事件函数中。
命令调用过程流程图:


比如C#语言:
开始执行一个命令:
在界面上放一个按钮“打开DWG”
给按钮增加点击事件如下:
  private void button6_Click(object sender, EventArgs e)
         {
             axMxDrawX1.DoCommand(6);
         }

axMxDrawX1.DoCommand调用后就会跳到命令事件中,给窗口增加控件命令执行事件,并加代码,如下:
    private void axMxDrawX1_ImplementCommandEvent(object sender, AxMxDrawXLib._DMxDrawXEvents_ImplementCommandEventEvent e)
         {

if (e.iCommandId == 6)
                     {
                 // 打开文件.
                 OpenFileDialog ofd = new OpenFileDialog();
                 ofd.Filter = "dwg 文件(*.dwg)|*.dwg";

                 if(ofd.ShowDialog() ==  DialogResult.OK)
                 {
                     axMxDrawX1.OpenDwgFile(ofd.FileName);
                 }
                     }
                 }


比如JS语言
开始执行一个命令:
在界面上放一个按钮“打开DWG”,如下:
< input type="button" value="写扩展数据">

DoCmd代码如下:调用DoCommand执行用户命令,DoCommand调用后就会跳到命令事件中
function DoCmd(iCmd) {
     mxOcx.DoCommand(iCmd);
}


添加命令事件:
document.getElementById("MxDrawXCtrl").ImplementCommandEventFun = DoCommandEventFunc;


命令事件函数实现:

function DoCommandEventFunc(iCmd)
{
      if (iCmd == 11) {
         WriteXData();
     }
}


写扩展数据函数实现:

function WriteXData() {
     var selEnt = mxOcx.NewComObject("IMxDrawUiPrEntity");

     selEnt.message = "选择要写扩展数据的对象";
     if (selEnt.go() != 1)
         return;

     var ent = selEnt.Entity();
     if (ent == null)
         return;

     if (ent.SetxDataString("ExDataName", 0, "ExDataValue")) {
         alert("写扩展数据成功");
     }
     else {
         alert("写扩展数据失败");
     }
}


在工具条定义文件中执行用户命令
工具条定义文件中一行代表一个工具条上的按钮,如果用户想点击工具条上的按钮,按钮执行命令事件,如下定义工具条:

("保存dwg文件" "保存dwg文件" "SaveDwg" "IDB_SAVEDWG_BITMAP"  "" "MxDraw.dll" "15")

上面,定义了一个打开dwg文件按钮,点击这个按钮,相当于执行DoCommand(15)

在菜单条中执行用户命令
菜单条定义文件中一行代表一个菜单命令,如果用户想点击菜单,执行命令事件,如下定义菜单条定义文件:
"打开(&O)" "Mx_OpenMxg" "IDB_OPENMXG_BITMAP" "" "" "15"
上面,定义了一个打开文件菜单,点击这个菜单项,相当于执行DoCommand(15)

为命令注册一个命令名称,方便命令输入和调用
调用RegistUserCustomCommand函数注册命令名称,chm中的帮助如下:

例如: VB调用代码
        MxDrawX1.RegistUserCustomCommand " MyTest11", 15
例如: C#调用代码

        axMxDrawX1.RegistUserCustomCommand("MyTest11",15);
         axMxDrawX1.Focus();
       // 命令 响应代码
        private void axMxDrawX1_ImplementCommandEvent(object sender, AxMxDrawXLib._DMxDrawXEvents_ImplementCommandEventEvent e)
         {
            if (e.iCommandId == 15)
             {
                 MessageBox.Show("用户定义命令执行....");
             }
         }


调用控件自带命令
控件工具条上的按钮,都是控件内部命令实现,点击工具条上的按钮,就会在命令行看到相关命令名称,如:

如果用户想在自己的按钮中,调用画线命令,如下:
axMxDrawX1.SendStringToExecute("Mx_Line");
在命令执行中,再调用另一个命令
控件是不允许命令被重入,也就是说不能同时执行两个命令,比如当前用户正交到绘制直线,当用户点击绘制圆按钮时,绘制直线命令就需要立即退出,并进入绘圆命令。
那么如果用户想要在命令中,调用另一个命令,可以把另一个命令当前一个函数调用,调用如下:
axMxDrawX1.SendStringToExecuteFun("Mx_Line");

命令函数执行完后,可以调用GetEntitysLastCmd函数返回,命令函数新增加的实体,它返一个MxDrawResbuf对象,也就是说,得到一个数组,得到多个新增加的实体。

如下JS代码,调用控件的绘制样条线命令,并得到新绘制样的样条线,然后修改它的线重:

function DrawSpline() {
     mxOcx.Cal("Mx_ShowWeight");

     var param = mxOcx.NewResbuf();
     mxOcx.SendStringToExecuteFun("_DrawSpline", param);
     var retparam = mxOcx.GetEntitysLastCmd();
     if (retparam == null)
         return;

     if (retparam.Count == 0)
         return;

     var spline = retparam.AtObject(0);
     if (spline == null) {
         return;
     }

     spline.Lineweight = 40;

}

用些命令在用时,可以转入参数,调用SendStringToExecuteEx函数:
如:调用阵列命令,并传递参数
MxDrawSelectionSet ss = new MxDrawSelectionSet();
                         MxDrawUtility utility = new MxDrawUtility();
                         utility.Prompt("选择阵列对象:");
                         ss.Select(MCAD_McSelect.mcSelectionSetUserSelect, null, null, null);
                         if (ss.Count == 0)
                             return;
                         MxDrawResbuf param = new MxDrawResbuf();

                         // 10行.
                         param.AddLongEx(10, 1070);

                         // 20列.
                         param.AddLongEx(20, 1070);

                         // 行偏移.
                         param.AddDoubleEx(100, 1040);

                         // 列偏移.
                         param.AddDoubleEx(150, 1040);

                         // 阵列角度.
                         param.AddDoubleEx(15.0, 1040);

                         // 阵列对象个数.
                         param.AddLongEx(ss.Count, 1070);
                         for (int i = 0; i < ss.Count; i++)
                         {
                             MxDrawEntity ent = ss.Item(i);
                             param.AddObjectId(ent.ObjectID);
                         }

                         // 调用阵列命令.
                         axMxDrawX1.SendStringToExecuteEx("Mx_Array", param);

3.VC接口的命令执行
VC2010调用是控件DLL接口,这个调用过程和AutoCAD Arx开发是一样的。

命令函数实现:
.h文件
class CTestCommands
{
static void TextToCurve();
}

.cpp 文件
void CTestCommands::TextToCurve()
{
         ads_name entName;
         ads_point pt;
         if(acedEntSel(_T("选择需要编辑的文字:"),entName,pt) != RTNORM)
         {
                 return;
         }
         AcDbObjectId objId;
         if(acdbGetObjectId(objId,entName) != Acad::eOk)
                 return;

         AcDbObjectPointer<McDbEntity> spText(objId,AcDb::kForWrite);
         if(spText.openStatus() != Acad::eOk)
                 return;


         McDbVoidPtrArray aryCurve ;
         if(!MxDraw::TextToCurves(spText.object(),aryCurve) )
                 return;

         for(int i = 0; i < aryCurve.length();i++)
         {
                 McDbEntity* pEntity = (McDbEntity* )aryCurve[i];

                 MrxDbgUtils::addToCurrentSpaceAndClose(pEntity);
         }
         spText->erase();
}


注册一个命令:
acedRegCmds->addCommand(_T("SysCmd"), _T("TextToCurve"), _T("TextToCurve"), 1, TextToCurve);

执行命令:
在界面上放一个按钮“文本转曲线”,在按钮响应函数中,调用刚才我们注册信息的命令:
acDocManager->sendStringToExecute(MxDraw::GetDatabase(m_hDrawOcx)->GetDocument()
                 ,_T("TextToCurve") );
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-12-22 20:15 , Processed in 0.484932 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表