找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 537|回复: 0

[教学] 【钩子(hook)应用(三)】禁止非命令状态拉窗口

[复制链接]

已领礼包: 51个

财富等级: 招财进宝

发表于 2018-1-23 00:20:58 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 Lispboy 于 2018-1-23 00:28 编辑

Issue
Is there a way to prevent AutoCAD from starting a selection box when a command
is not active in ObjectARX?

问题:ObjectARX中,有没有办法在AutoCAD没有命令激活时候,阻止启动选择框?


Solution
The problem in the context where there is not an active command is that AutoCAD
can do a box selection operation (this is what should be avoided) or a pick set
selection if an entity is under the mouse pointer. At the time you see the
message, AutoCAD has not yet "seen" the message, therefore, you need to
determine in which context you are. The solution to that problem is the
following:

If the AutoCAD CMDACTIVE variable is equal to 0, then post the WM_LBUTTONDOWN
message again to AutoCAD using the same parameters (but be carefull about the
endless loop).

This method does not "break" anything in AutoCAD and the box selection is
disabled and at the other corner, AutoCAD prompts are automatically fed by the
second WM_LBUTTONDOWN message.

解答:在AUTOCAD命令未激活情况下,单选实体允许,但窗口选择禁止,这个时候,你可以看到消息,而不让AUTOCAD看见,因此解决方法如下:
如果系统变量CMDACTIVE=0,你继续用相同的消息参数POST给AUTOCAD一个鼠标左键按下的消息,让AUTOCAD以为它已经拉出窗口鼠标单击结束了。需要注意的是要避免无限循环。

解决的ARX代码如下:

  1. void watch (const MSG *pMsg) {
  2.     static BOOL bStopLoop =FALSE ;
  3.     struct resbuf result ;
  4.     if ( acedGetAcadDwgView ()->GetSafeHwnd () == pMsg->hwnd && pMsg->message == WM_LBUTTONDOWN ) {
  5.         ads_getvar (L"CMDACTIVE", &result) ;
  6.         if ( result.resval.rint == 0 ) {
  7.             if ( !bStopLoop ) {
  8.                 acedGetAcadDwgView ()->PostMessage (WM_LBUTTONDOWN, pMsg->wParam, pMsg->lParam) ;
  9.                 bStopLoop =TRUE ;
  10.             } else {
  11.                 bStopLoop =FALSE ;
  12.             }
  13.         }
  14.     }
  15. }


Use 'acedRegisterWatchWinMsg (watch);' to register the callback function in
AutoCAD and 'acedRemoveWatchWinMsg (watch);' to unregister it.

好了,上面是ARX的解决方案,下面我们用LISP实现它。


HOOK禁止拉窗口.gif

  1. (defun c:tt ()
  2.   (defun _hook (hwnd msg wparam lparam ti pos)
  3.     (cond
  4.       ((= msg WM_LBUTTONDOWN);监视鼠标左键按下消息
  5.        (setq result (getvar "cmdactive"));;cmdactive=0时候,禁止拉窗口
  6.        (if (= result 0)
  7.          (progn
  8.            (if (not bStopLoop)
  9.              (progn
  10.                (alert "\n别按啦,禁止你了!!!")
  11.                (xdrx_hook_postmessage WM_LBUTTONDOWN wparam lparam);;post给AUTOCAD第二个鼠标左键按下的消息
  12.                     (setq bStopLoop t);;避免无限循环
  13.              )
  14.              (progn (setq bStopLoop nil))
  15.            )
  16.          )
  17.        )
  18.       )
  19.     )
  20.   )
  21.   (xdrx_begin)
  22.   (xd::hook:register "_hook" t "禁止非命令状态窗选hook")
  23.   (xdrx_end)
  24.   (princ)
  25. )


论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-4-26 16:48 , Processed in 0.415463 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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