- UID
- 118401
- 积分
- 2156
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2004-3-28
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
很久没摸arx了,不久看到了一篇介绍钩子技术在 AutoCAD中应用的文章,不敢独享,特此奉献给大家。
钩子技术是很有用的一种技术,它如同给函数挂上一个钩子(我们自己的函数),让它在执行前先执行我们挂的钩子(我们挂接的函数),从而达到拦截事件和函数调用等的目的。在autocad中,利用钩子技术可以为我们做很多事情:如建立快捷键(不希望更改已有菜单),等待或者触发特定消息(如鼠标,键盘),可以获得比反应器更强大的功能,等等。
objectARX提供了几种向autocad注册钩子函数的ARX API函数,见下面:
acedRegisterFilterWinMsg,注册一个钩子函数
acedRemoveFilterWinMsg,注销一个钩子函数
acedRegisterWatchWinMsg, 监测钩子函数
acedRemoveWatchWinMsg, 移除监测函数
其具体用法各位不妨参考帮助文件。
下面函数提供一个例程,该例程定义了一个快捷命令 Ctrl+I,当用户按下快捷键时候,autocad 将执行appload命令。
我这里采用了向导方式创建了一个新工程Hook
采不采用MFC对这个程序没有影响.
在acrxEntryPoint.cpp 中开头添加如下代码:
- #include <aced.h> //仅因为版本较低,所以加了这两个
- #include <rxmfcapi.h> //对于高版本无须此两个
复制代码 并申明函数:
- //------------------------------------------------------------------------------------------------
- //函数原型及其全局变量申明
- void sendCommandToAutoCAD(HWND hWndAcad,CString cmd); //向AutoCAD窗口发送字符串命令(cmd)
- void watchCtrlI(const MSG * pMsg); //钩子监测函数
- void Accelerator(void); //快捷键注册函数
- static BOOL filterCtrlKeyDone = FALSE;
- //------------------------------------------------------------------------------------------------
复制代码 函数定义
- void Accelerator(void)
- {
- if(filterCtrlKeyDone == TRUE)
- {
- acutPrintf(_T("Hook has already been registered!\n")); //如果钩子已经注册,则返回
- return;
- }
- if(acedRegisterWatchWinMsg(watchCtrlI) == FALSE)
- acedPrompt(_T("Hook can't be registered!\n")); //无法注册钩子
- else
- {
- acedPrompt(_T("Shortcut Ctrl+I has been defined!\n")); //快捷命令Ctrl + I 已经定义
- filterCtrlKeyDone = TRUE;
- }
- return;
- }
- //钩子监测函数,监测Ctrl+I键盘消息
- void watchCtrlI(const MSG *pMsg)
- {
- if (pMsg->message == WM_CHAR && pMsg->wParam == 9) //发生键盘Ctrl + I消息
- {
- sendCommandToAutoCAD(adsw_acadMainWnd(), _T("appload\n"));
- //这里可以是你自己定义的任何函数
- }
- return;
- }
- //向AutoCAD窗口发送字符串命令(cmd)
- void sendCommandToAutoCAD(HWND hWndAcad,CString cmd)
- {
- if(! hWndAcad)
- return;
- COPYDATASTRUCT cmdMsg;
- cmdMsg.dwData = (DWORD)1;
- cmdMsg.cbData = (DWORD)_tcslen(cmd) + 1;
- cmdMsg.lpData = cmd.GetBuffer(cmd.GetLength() + 1);
- SendMessage(hWndAcad,WM_COPYDATA,(WPARAM)hWndAcad, (LPARAM)& cmdMsg);
- return;
- }
复制代码 修改一下初始化入口On_kInitAppMsg和卸载函数On_kUnloadAppMsg
- virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
- // TODO: Load dependencies here
- // You *must* call On_kInitAppMsg here
- AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;
- // TODO: Add your initialization code here
- //我在这里添加到了初始化,如果你感觉不好的话,可以定义到命令组里
- Accelerator();
- return (retCode) ;
- }
- virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
- // TODO: Add your code here
- // You *must* call On_kUnloadAppMsg here
- AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;
- // TODO: Unload dependencies here
- //卸载arx程序前卸载钩子函数
- if(filterCtrlKeyDone == TRUE)
- {
- acedRemoveWatchWinMsg(watchCtrlI);
- acutPrintf(_T("\nHook has been removed!\n"));
- }
- return (retCode) ;
- }
复制代码 编译后,形成arx,加载hook.arx,然后当你用快捷键的时候,你就会发现弹出appload对话框了。
最终效果如下图:
如果你感觉到代码不好读或者有出入,见我下面的附件:
在vs2002 + arx2006 + autocad2006 编译成功并运行正确。
我这个例子很简单,希望大家讨论。并在此感谢原创者。
这个利用钩子技术在autocad 中定义快捷命令的思路,具有较大的启发意义。因为,对于在autocad 平台上开发cad系统来说,如果直接与autocad建立底层联系(如等待或者触发特定的消息),利用钩子技术是很必要的。
|
-
-
Hook.rar
32.06 KB, 下载次数: 24, 下载积分: D豆 -1 , 活跃度 1
售价: 5 D豆 [记录]
|