找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2050|回复: 1

[飞鸟集] 简介钩子技术在AutoCAD中的应用

[复制链接]

已领礼包: 8121个

财富等级: 富甲天下

发表于 2013-5-7 22:24:06 | 显示全部楼层 |阅读模式

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

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

×
很久没摸arx了,不久看到了一篇介绍钩子技术在 AutoCAD中应用的文章,不敢独享,特此奉献给大家。

钩子技术是很有用的一种技术,它如同给函数挂上一个钩子(我们自己的函数),让它在执行前先执行我们挂的钩子(我们挂接的函数),从而达到拦截事件和函数调用等的目的。在autocad中,利用钩子技术可以为我们做很多事情:如建立快捷键(不希望更改已有菜单),等待或者触发特定消息(如鼠标,键盘),可以获得比反应器更强大的功能,等等。

objectARX提供了几种向autocad注册钩子函数的ARX API函数,见下面:

acedRegisterFilterWinMsg,注册一个钩子函数
acedRemoveFilterWinMsg,注销一个钩子函数
acedRegisterWatchWinMsg, 监测钩子函数
acedRemoveWatchWinMsg, 移除监测函数

其具体用法各位不妨参考帮助文件。

下面函数提供一个例程,该例程定义了一个快捷命令 Ctrl+I,当用户按下快捷键时候,autocad 将执行appload命令。


我这里采用了向导方式创建了一个新工程Hook

C1.jpg

采不采用MFC对这个程序没有影响.

C2.jpg


在acrxEntryPoint.cpp 中开头添加如下代码:

  1. #include <aced.h>               //仅因为版本较低,所以加了这两个
  2. #include <rxmfcapi.h>           //对于高版本无须此两个
复制代码
并申明函数:




  1. //------------------------------------------------------------------------------------------------
  2. //函数原型及其全局变量申明
  3. void sendCommandToAutoCAD(HWND hWndAcad,CString cmd);   //向AutoCAD窗口发送字符串命令(cmd)
  4. void watchCtrlI(const MSG * pMsg);        //钩子监测函数
  5. void Accelerator(void);              //快捷键注册函数
  6. static BOOL filterCtrlKeyDone = FALSE;                 
  7. //------------------------------------------------------------------------------------------------

复制代码
函数定义


  1. void  Accelerator(void)
  2. {
  3. if(filterCtrlKeyDone == TRUE)
  4. {
  5.   acutPrintf(_T("Hook has already been registered!\n")); //如果钩子已经注册,则返回
  6.   return;
  7. }
  8. if(acedRegisterWatchWinMsg(watchCtrlI) == FALSE)
  9.   acedPrompt(_T("Hook can't be registered!\n"));          //无法注册钩子
  10. else
  11. {
  12.   acedPrompt(_T("Shortcut Ctrl+I has been defined!\n"));  //快捷命令Ctrl + I 已经定义
  13.   filterCtrlKeyDone = TRUE;
  14. }
  15. return;
  16. }
  17. //钩子监测函数,监测Ctrl+I键盘消息
  18. void watchCtrlI(const MSG *pMsg)
  19. {
  20. if (pMsg->message == WM_CHAR && pMsg->wParam == 9)   //发生键盘Ctrl + I消息
  21. {
  22.   sendCommandToAutoCAD(adsw_acadMainWnd(), _T("appload\n"));
  23.                 //这里可以是你自己定义的任何函数
  24. }
  25. return;
  26. }
  27. //向AutoCAD窗口发送字符串命令(cmd)
  28. void sendCommandToAutoCAD(HWND hWndAcad,CString cmd)
  29. {
  30. if(! hWndAcad)
  31.   return;
  32. COPYDATASTRUCT cmdMsg;
  33. cmdMsg.dwData = (DWORD)1;
  34. cmdMsg.cbData = (DWORD)_tcslen(cmd) + 1;
  35. cmdMsg.lpData = cmd.GetBuffer(cmd.GetLength() + 1);
  36. SendMessage(hWndAcad,WM_COPYDATA,(WPARAM)hWndAcad, (LPARAM)& cmdMsg);
  37. return;
  38. }
复制代码
修改一下初始化入口On_kInitAppMsg和卸载函数On_kUnloadAppMsg

  1. virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
  2.   // TODO: Load dependencies here
  3.   // You *must* call On_kInitAppMsg here
  4.   AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;

  5.   // TODO: Add your initialization code here
  6.   //我在这里添加到了初始化,如果你感觉不好的话,可以定义到命令组里
  7.   Accelerator();

  8.   return (retCode) ;
  9. }
  10. virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
  11.   // TODO: Add your code here
  12.   // You *must* call On_kUnloadAppMsg here
  13.   AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;
  14.   // TODO: Unload dependencies here

  15.   //卸载arx程序前卸载钩子函数
  16.   if(filterCtrlKeyDone == TRUE)
  17.   {
  18.    acedRemoveWatchWinMsg(watchCtrlI);
  19.    acutPrintf(_T("\nHook has been removed!\n"));
  20.   }

  21.   return (retCode) ;
  22. }
复制代码
编译后,形成arx,加载hook.arx,然后当你用快捷键的时候,你就会发现弹出appload对话框了。
最终效果如下图:



如果你感觉到代码不好读或者有出入,见我下面的附件:
C4.jpg
在vs2002 + arx2006 + autocad2006 编译成功并运行正确。

我这个例子很简单,希望大家讨论。并在此感谢原创者。
这个利用钩子技术在autocad 中定义快捷命令的思路,具有较大的启发意义。因为,对于在autocad 平台上开发cad系统来说,如果直接与autocad建立底层联系(如等待或者触发特定的消息),利用钩子技术是很必要的。







Hook.rar

32.06 KB, 下载次数: 24, 下载积分: D豆 -1 , 活跃度 1

售价: 5 D豆  [记录]

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2013-5-10 17:26:16 | 显示全部楼层
不可多得的学习资料,谢谢分享。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-8 08:49 , Processed in 0.218462 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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