cad.net 选择集问题

保留关键字

无论是cad.arx还是cad.net的开发人员都需要注意交互的保留关键字.
N S W E是东南西北四个方位,s是南方270度,在设置关键字的时候必须避开这四个关键字.
这个设置在早期的R14也有:

在使用选择集的时候,设置关键字不可以用a,它会是all的首字母,更多的参考一下飞诗的lisp选择集屏蔽关键字.

选择集预选

动图演示

img

本次测试

测试环境: Acad2008
这个bug是这样的,在预选状态时候执行命令,会导致该命令去重设一次选择集,
而没有预选则十分正常

错误代码

[CommandMethod("tta", CommandFlags.Modal | CommandFlags.UsePickSet | CommandFlags.Redraw)]
public static void tta()
{
    Editor ed = Acap.DocumentManager.MdiActiveDocument.Editor;    
    var psr = ed.GetSelection();
    if (psr.Status != PromptStatus.OK)
        return;
    //重构了一个选择集,为什么预选的时候,要等到再次点鼠标才能成功显示呢?
    ed.SetImpliedSelection(psr.Value.GetObjectIds()); 
    //ed.Regen();
}

如果最后加一句:ed.Regen();是可以成功的,但是,这不应该啊.

因为其中的奥妙在于,预选的获取不应该利用 ed.GetSelection(pso, filter); 而是应该利用 ed.SelectImplied();

正确代码

[CommandMethod("tta", CommandFlags.Modal | CommandFlags.UsePickSet | CommandFlags.Redraw)]
public static void tta()
{
    Editor ed = Acap.DocumentManager.MdiActiveDocument.Editor;
    var psr = ed.SelectImplied();//预选
    if (psr.Status != PromptStatus.OK) //数量0也是不ok
        psr = ed.GetSelection(pso, filter);//手选
    if (psr.Status != PromptStatus.OK)
        return;
    ed.SetImpliedSelection(psr.Value.GetObjectIds()); //重构了一个选择集
}

原因为什么会这样呢?
因为手选的 ed.GetSelection() 直接读取了选择集缓冲区,没有很好的处理预选状态..
导致了引起了选择的内部错误,是函数单一职责的封装问题.

相关阅读

acedSSSetFirst选择集夹点亮显实例

com选择集的例子

    /// <summary>
    /// 输出WMF<br/>
    /// </summary>
    /// <param name="editor">命令行对象</param>
    /// <param name="saveFile">保存文件</param>
    /// <param name="ids">选择集的对象,为null时候手选</param>
    /// <exception cref="ArgumentNullException"></exception>
    public static void ExportWMF(this Editor editor, string saveFile, ObjectId[]? ids = null)
    {
        if (string.IsNullOrEmpty(saveFile))
            throw new ArgumentNullException(nameof(saveFile));
        if (File.Exists(saveFile))
            throw new FileFormatException("文件重复:" + saveFile);

        var dm = Acap.DocumentManager;
        if (dm.Count == 0)
            return;

        // 剔除后缀
        int dot = saveFile.LastIndexOf('.');
        if (dot != -1)
        {
            // 因为文件名可以有.所以后缀点必须是最后\的后面
            int s = saveFile.LastIndexOf('\\');
            if (s < dot)
                saveFile = saveFile.Substring(0, dot);
        }

        // ActiveSelectionSet:
        // 第一次执行会触发选择,
        // 再次重复命令执行的时候,它会无法再选择
        // 因此此处选择一次,此时必然有当前选择集,它就直接获取当前选择集
        if (ids == null || ids.Length == 0)
        {
            var psr = editor.SelectImplied();// 预选
            if (psr.Status != PromptStatus.OK)
                psr = editor.GetSelection();// 手选
            if (psr.Status != PromptStatus.OK)
                return;
        }
#if zcad
        var com = Acap.ZcadApplication;
#else
        var com = Acap.AcadApplication;
#endif
        var doc = com.GetProperty("ActiveDocument");
        var wmfSet = doc.GetProperty("ActiveSelectionSet");
        doc.Invoke("Export", saveFile, "wmf", wmfSet); // JPGOUT,PNGOUT
        wmfSet.Invoke("Delete");
    }

关键字回调

kean博客ssget关键字回调

关键字回调时候会重新进入选择集,此时需要再空格才能退出.
如何立即退出?
arx在关键字上面发送cad命令\003,

net可以引发异常退出,自己构造一个异常.
net发送命令它会经过命令模式,进行重入,不好,还是触发异常好

(完)

posted @ 2019-01-05 15:13  惊惊  阅读(661)  评论(0编辑  收藏  举报