highflybir 发表于 2013-8-2 18:40:20

【DynamicLisp的高级应用】-- 定时器事件

本帖最后由 highflybir 于 2013-8-2 21:11 编辑

定时器时间是利用API里面的timer,用来在CAD中设置定时器,使得某一事件在一定间隔时间内触发。

有很多用途: 譬如有些CAD的系统变量如果发生了变化,通过反应器不能监视,用定时器就可以达到目的。
另外,你也可以用来做做动画,或者模拟多线程,这都是可以的。

=====================================================================
相关的定时器函数有两个:                                                         
---------------------------------------------------------------------
名称:HFB_SetLispTimer                                              
功能:在CAD中增加定时器事件,可以间隔一定时间触发事件。            
方法:(HFB_SetLispTimerCallbackElapse)                  
参数:Callback-- 回调函数名称,为字符串                           
       elapse-- 间隔时间,毫秒单位,为正整数                     
       hwnd    -- 窗口句柄。缺省时为当前文档。设置为0时是全局定时事件
返回:成功返回定时器ID, 否则返回nil.                              
---------------------------------------------------------------------
名称:HFB_KillLispTimer                                           
功能:关闭CAD中的定时器事件。                                       
方法:(HFB_KillLispTimer ID)                                       
参数:ID      -- 定时器ID,为正整数                                 
返回:成功返回T, 否则返回nil.                                       
---------------------------------------------------------------------
说明:定时器设置的回调函数里不应与CAD的交互,否则可能出现意外.      
       关闭文档或者程序,或者卸载程序之前别忘记关闭相关定时器事件。
       定时器事件可以用来监视系统变量等,也可以达到反应器效果。
---------------------------------------------------------------------   
回调函数: 回调函数含有四个参数, 参数说明:                                  hwnd    -- 窗口句柄                                          
       nMsg    -- 窗口消息                                          
       nTimerID-- 定时器事件ID                                       
       dwTime-- 事件时间                                          
=====================================================================

下面的例子在图中增加了4个定时器事件。
一个为监视视窗中心的变化,一个监视视窗高度的变化,一个使一个圆不断变大。
这三个都是文档级的定时器。另外还有一个全局定时器,10秒钟提醒一下,然后关闭。

代码如下:

(defun C:SetTimer(/ oldsize oldctr obj ent cen rad t1 t2 t3 t4)

;;视高改变监视函数
(defun TimerCallback1 (hWnd nMsg nTimerid dwTime / newsize)
    (setq newsize (getvar 'viewsize))
    (if (not (equal newsize (vl-bb-ref 'oldsize) 1e-6))
      (progn
      (princ "\n视高发生改变,现在是: ")
      (princ newsize)
      (vl-bb-set 'oldsize newsize)
      )
    )
)

;;视中心改变监视函数
(defun TimerCallback2 (hWnd nMsg nTimerid dwTime / newctr)
    (setq newctr (getvar 'viewctr))
    (if (not (equal newctr (vl-bb-ref 'oldctr) 1e-6))
      (progn
      (princ "\n视中心发生改变,现在是: ")
      (princ newctr)
      (vl-bb-set 'oldctr newctr)
      )
    )
)

;;改变圆的半径,圆不断变大。
(defun TimerCallback3 (hWnd nMsg nTimerid dwTime / obj)
    (if (setq obj (vl-bb-ref 'obj))
      (if (vlax-erased-p obj)
      (hfb_killlisptimer (vl-bb-ref 't3))
      (progn
          (vla-put-radius obj (+ (vla-get-radius obj) 1))
          (redraw (vlax-vla-object->ename obj))
      )
      )
    )
)

;;全局的监视事件
(defun TimerCallback4 (hWnd nMsg nTimerid dwTime)
    (alert "10秒提醒一次")
    (HFB_KillLispTimer (vl-bb-ref 't4))                                  ;提醒后就关闭定时器
)

;;获得变量数值并存储
(setq oldsize (getvar 'viewsize))
(setq oldctr (getvar 'oldctr))
(vl-bb-set 'oldsize oldsize)
(vl-bb-set 'oldctr oldctr)

(initget 1)
(setq cen (getpoint "\n输入圆心:"))
(initget 1)
(setq rad (getdist cen "\n输入半径:"))
(setq ent (Ent:make_circle cen rad))
(setq obj (vlax-ename->vla-object ent))

(HFB_KillLispTimer)
(setq t1 (HFB_SetLispTimer "TimerCallback1" 50 ))                        ;50毫秒
(setq t2 (HFB_SetLispTimer "TimerCallback2" 50 ))                        ;50毫秒
(setq t3 (HFB_SetLispTimer "TimerCallback3" 50 ))                        ;50毫秒
(setq t4 (HFB_SetLispTimer "TimerCallback4" 10000 0))               ;10秒提醒一次
(vl-bb-set 'obj obj)
(vl-bb-set 't1 t1)
(vl-bb-set 't2 t2)
(vl-bb-set 't3 t3)
(vl-bb-set 't4 t4)

(princ)
)

(defun Ent:make_circle (cen rad)
(entmakex (list '(0 . "CIRCLE") (cons 10 cen) (cons 40 rad)))
)

(defun C:killTimer()
(HFB_KillLispTimer)
(princ)
)

highflybir 发表于 2013-8-2 18:42:06

设置定时器命令是:settimer
关闭定时器命令是:killtimer
关于DynamicLisp,请参见:
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=90447&page=1&extra=#pid604291

sicky111 发表于 2013-8-2 23:45:38

LISP能做到这样,真的好强哦。

清风明月名字 发表于 2013-8-3 12:44:07

highflybir 发表于 2013-8-2 18:42 static/image/common/back.gif
设置定时器命令是:settimer
关闭定时器命令是:killtimer
关于DynamicLisp,请参见:


运行时说没有这个函数:HFB_KILLLISPTIMER

命令: SetTimer
输入圆心:
输入半径:; 错误: no function definition: HFB_KILLLISPTIMER

linshiyin2 发表于 2013-8-4 22:21:51

学习了

自贡黄明儒 发表于 2013-8-11 08:50:33

H版就是强,顶了!

linjian257 发表于 2014-8-4 13:51:32

这个好强,学习了

taoyi0727 发表于 2018-12-14 16:01:59

前几个月不知道这个什么东西
现在回过来看 不的不说这东西霸道

nuan1989 发表于 2024-6-15 15:17:30

DynamicLisp , 是不是出新版cad就用不了了, 得等你编译
页: [1]
查看完整版本: 【DynamicLisp的高级应用】-- 定时器事件