乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 68|回复: 5

使用实体夹具-按空格键/enter键取消

[复制链接]

85

主题

404

帖子

7

银币

中流砥柱

Rank: 25

铜币
751
发表于 2015-5-7 03:35:08 | 显示全部楼层 |阅读模式
我刚刚开始使用BlockJig,它们工作正常,但用户需要按Esc退出while循环。我想在用户点击空格(enter)时取消该命令,这与大多数autocad命令类似。理想情况下,它会对空格/回车做出不同的反应:如果我在旋转夹具中,它会使块保持原始旋转,如果插入块,它会取消命令。一旦我捕获了空格/回车,我就可以计算出这个逻辑
基本上,我有一个do/while循环,在promptStatus正常时执行jig拖动。
我不确定是否需要更改调用jig的do/whole循环,或者它可能在SamplerStatus覆盖中的UserInputControls中?此外,如果我的执行愚蠢/效率低下,我会接受其他评论,我对这一点还是很陌生的
使用do/while循环调用jig:
  1. public static void InsertRotatorBlockTest(ObjectId blockId, Scale3d scale, string layerName = "0", ResultBuffer optionalXData = null)
  2. {
  3.    Database db = Active.Database;
  4.    Transaction tr = Active.Document.TransactionManager.StartTransaction();
  5.    using (tr)
  6.    {
  7.       //Open block table to be sure it exists
  8.       BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  9.       PromptResult pr;
  10.       double rotation = 0;
  11.       do
  12.       {
  13.          // now the jig
  14.          // create the blockref
  15.          Point3d pt = new Point3d(0, 0, 0);
  16.          BlockReference br = new BlockReference(pt, blockId)
  17.          {
  18.             ScaleFactors = scale,
  19.             Layer = layerName,
  20.             Rotation = rotation
  21.          };
  22.          if (optionalXData != null)
  23.          {
  24.             br.XData = optionalXData;
  25.          }
  26.          InsertBlockJig insertJig = new InsertBlockJig(br);
  27.          // insert the blockref into modelspace
  28.          pr = Active.Editor.Drag(insertJig);
  29.          if (pr.Status==PromptStatus.OK)
  30.          {
  31.             // rotate it
  32.             RotatingBlockJig rotateJig = new RotatingBlockJig(br);
  33.             pr = Active.Editor.Drag(rotateJig);
  34.             
  35.             BlockTableRecord curSpace = (BlockTableRecord)tr.GetObject(Active.Database.CurrentSpaceId,
  36.                OpenMode.ForWrite);
  37.             curSpace.AppendEntity(br);
  38.             tr.AddNewlyCreatedDBObject(br, true);
  39.             // Call a function to make the graphics display (otherwise it only shows after commit)
  40.             Active.Document.TransactionManager.QueueForGraphicsFlush();
  41.             rotation = br.Rotation;
  42.          }
  43.       } while (pr.Status != PromptStatus.Cancel &&
  44.             pr.Status != PromptStatus.Error &&
  45.             pr.Status != PromptStatus.Keyword);
  46.       tr.Commit();
  47.    }
  48. }

两个EntityJig类:
  1. class InsertBlockJig : EntityJig
  2. {
  3.    Point3d _mCenterPt, _mActualPoint;
  4.    public InsertBlockJig(Entity ent)
  5.       : base(ent)
  6.    {
  7.       _mCenterPt = ((BlockReference) ent).Position;
  8.    }
  9.    protected override SamplerStatus Sampler(JigPrompts prompts)
  10.    {
  11.       JigPromptPointOptions jigOpts =
  12.         new JigPromptPointOptions();
  13.       jigOpts.UserInputControls =
  14.         (UserInputControls.Accept3dCoordinates
  15.         | UserInputControls.NullResponseAccepted
  16.         | UserInputControls.NoNegativeResponseAccepted);
  17.       jigOpts.Message =
  18.         "\nEnter insert point: ";
  19.       PromptPointResult dres =
  20.         prompts.AcquirePoint(jigOpts);
  21.       if (_mActualPoint == dres.Value)
  22.       {
  23.          return SamplerStatus.NoChange;
  24.       }
  25.       else
  26.       {
  27.          _mActualPoint = dres.Value;
  28.       }
  29.       return SamplerStatus.OK;
  30.    }
  31.    protected override bool Update()
  32.    {
  33.       _mCenterPt = _mActualPoint;
  34.       try
  35.       {
  36.          ((BlockReference)Entity).Position = _mCenterPt;
  37.       }
  38.       catch (Exception)
  39.       {
  40.          return false;
  41.       }
  42.       return true;
  43.    }
  44. }
  45. class RotatingBlockJig : EntityJig
  46. {
  47.    // Fields
  48.    private double _mRotation;
  49.    private BlockReference _br;
  50.    // Constructor
  51.    public RotatingBlockJig(BlockReference br)
  52.       : base(br)
  53.    {
  54.       _mRotation = br.Rotation;
  55.       _br = br;
  56.    }
  57.    // Overrides
  58.    protected override bool Update()
  59.    {
  60.       (Entity as BlockReference).Rotation = _mRotation;
  61.       return true;
  62.    }
  63.    protected override SamplerStatus Sampler(JigPrompts prompts)
  64.    {
  65.       JigPromptAngleOptions prAngleOpts = new JigPromptAngleOptions("\n Rotation: ");
  66.       prAngleOpts.BasePoint = _br.Position;
  67.       prAngleOpts.UseBasePoint = true;
  68.       prAngleOpts.Cursor=CursorType.RubberBand;
  69.       PromptDoubleResult prRotResult = prompts.AcquireAngle(prAngleOpts);
  70.       if (prRotResult.Status == PromptStatus.Cancel) return SamplerStatus.Cancel;
  71.       // Return no change if no rotation, to prevent flashing
  72.       if (prRotResult.Value.Equals(_mRotation))
  73.       {
  74.          return SamplerStatus.NoChange;
  75.       }
  76.       else
  77.       {
  78.          _mRotation = prRotResult.Value;
  79.          return SamplerStatus.OK;
  80.       }
  81.       return SamplerStatus.OK;
  82.    }
  83. }

本帖以下内容被隐藏保护;需要你回复后,才能看到!

游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

24

主题

204

帖子

6

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
300
发表于 2015-5-7 07:48:52 | 显示全部楼层
在JigPrompOptions中,可以设置JigProppOptions。UserInputControls与UserInputContracts。InitialBlankTerminatesInput标志。
回复

使用道具 举报

85

主题

404

帖子

7

银币

中流砥柱

Rank: 25

铜币
751
发表于 2015-5-7 14:03:12 | 显示全部楼层
谢谢你,M.C .我希望事情能简单些。
我是否需要设置其他内容与之搭配?我实现了

  1. prAngleOpts.UserInputControls = UserInputControls.InitialBlankTerminatesInput;

  1. jigOpts.UserInputControls =
  2.                  (UserInputControls.Accept3dCoordinates
  3.                  | UserInputControls.NullResponseAccepted
  4.                  | UserInputControls.NoNegativeResponseAccepted
  5.                  | UserInputControls.InitialBlankTerminatesInput);

而且行为不会改变。
在尝试阅读UserInputControls的过程中,我在这篇文章中指出,也许可以使用消息过滤器。对于如此基本的东西来说,消息过滤器似乎是一个笨拙的解决方案。
在更元的层面上,我可以在哪里阅读这方面的资料?我将帮助文件安装到了VS2013中,但就我目前所知,它并没有太大的帮助。甚至autocad的objectbrowser也很少。搜索开发者指南很少会放弃任何有用的东西。我记得以前在COM帮助文件中找到过各种有用的用法示例。
回复

使用道具 举报

4

主题

219

帖子

4

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
238
发表于 2015-5-7 17:00:25 | 显示全部楼层
您可能需要查看JigPromptOptions.Keywords.在您的情况下,您只能添加1个关键字,例如“取消”,并将其设置为默认值。然后测试PromptResult.Status不仅PromptStatus.Cancel和/或PromptStatus.Keyword.
回复

使用道具 举报

85

主题

404

帖子

7

银币

中流砥柱

Rank: 25

铜币
751
发表于 2015-5-19 00:35:34 | 显示全部楼层
我最终采用的解决方案是应用IMessageFilter,如下所示:
  
Filter:

  1.         public class SpaceRightClickFilter : WinForms.IMessageFilter
  2.         {
  3.             public bool canceled = false;
  4.             public bool PreFilterMessage(ref WinForms.Message m)
  5.             {
  6.                 int WM_RIGHTCLICK = 0x0205;
  7.                 int WM_KEYDOWN = 0x0100;
  8.                 Keys kc = (Keys) (int) m.WParam & Keys.KeyCode;
  9.                 // check for space press or right click
  10.                 if ((m.Msg == WM_KEYDOWN && (kc==Keys.Space)) || m.Msg==WM_RIGHTCLICK)
  11.                 {
  12.                     canceled = true;
  13.                 }
  14.                 // never falter
  15.                 return false;
  16.             }
  17.         }

用法:
  1.                     InsertBlockJig insertJig = new InsertBlockJig(br);
  2.                     // insert the blockref into modelspace
  3.                     insertPrompt = Active.Editor.Drag(insertJig);
  4.                     // Add a message filter to the window
  5.                     SpaceRightClickFilter cancelInsertFilter = new SpaceRightClickFilter();
  6.                     System.Windows.Forms.Application.AddMessageFilter(cancelInsertFilter);
  7.                     if (insertPrompt.Status == PromptStatus.OK && !cancelInsertFilter.canceled)
  8.                     {
  9.                         // get rid of insert filter
  10.                         System.Windows.Forms.Application.RemoveMessageFilter(cancelInsertFilter);
  11.                         // Do some cool stuff where space/rightclick doesn't cancel
  12.                         // ...
  13.                     else
  14.                     {
  15.                         canceled = true;
  16.                     }
  17.                     // Clean up; remove the filter
  18.                     System.Windows.Forms.Application.RemoveMessageFilter(cancelInsertFilter);

回复

使用道具 举报

3

主题

7

帖子

1

银币

初来乍到

Rank: 1

铜币
19
发表于 2015-5-22 11:47:22 | 显示全部楼层
您还需要设置或<strong>UserInputControls.AcceptOtherInputString
。否则,您不能输入空白,并且不会发生取消。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-2-5 02:44 , Processed in 0.203961 second(s), 64 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表