本实例主要是讲Hook技术在CAD中的使用方法。
Hook技术就是所谓钩子技术,在CAD的二次开发过程中,有很多的情况,是需要使用钩子技术的(尽管CAD已经提供了强大的反应器技术),由于CAD也是基于MFC开发的应用程序,我们也可以像HOOK其它应用程序一样的方法来HOOKCAD,但有些时候,一些消息不知道怎么回事,会HOOK不到。比如:按下SHIFT键。 不管怎么样,CAD还是把HOOKCAD消息的处理方法封装了一下。很好用,主要有以下几种:
// Define callback function for apps that want windows messages
typedef void (* AcedWatchWinMsgFn)(const MSG*); //定义监视消息的函数指针
typedef BOOL (* AcedFilterWinMsgFn)(MSG*); //定义过滤消息的函数指针
typedef void (* AcedOnIdleMsgFn) (); //定义监视CAD空闲时间的函数指针
// Windows messages hooks
/* Register a filter message hook into AutoCAD's Windows message loop.
* The message passed to your application can be changed and can be blocked out.
* If the function returns TRUE, the message WON'T be passed to other hook
* functions or AutoCAD at all. The message is terminated.
* Returns TRUE if successfully registers the hook. Otherwise FALSE.
*/
以上的意思大概是,在CAD的WINDOWS 消息循环中定义一个hook,你可以在其中处理这个消息,这个处理函数是必须有返回值的,返回TRUE,这个消息不会传递给其它的HOOK和CAD了,这个消息就中止了,如果返回FALSE,这个消息将可以被任何其它的HOOK和CAD处理。
不过个人做了一个实验,返回TRUE时,CAD好像还是可以对这个消息进行一个处理。这个地方还有待研究。
BOOL acedRegisterFilterWinMsg(const AcedFilterWinMsgFn pfn);
/* acedRemoveFilterWinMsg
* Takes a message hook function pointer and remove it
* Returns TRUE if successfully registers the hook. Otherwise FALSE.
*/
很简单,移除上面注册的过滤函数
BOOL acedRemoveFilterWinMsg(const AcedFilterWinMsgFn pfn);
/* acedRegisterWatchWinMsg
* Register a hook function into AutoCAD message loop.
* The function can only look up AutoCAD's Windows message.
* It can't change or block message.
* Returns TRUE if successfully registers the hook. Otherwise FALSE.
*/
以上的意思大概是,在CAD的WINDOWS 消息循环中定义一个hook,你可以在其中查看CAD的任何消息,但不能中止其消息的传递,当然,你可以监控到一些消息后,做一些你自己要做的事,但不会中断消息的传递。
BOOL acedRegisterWatchWinMsg(const AcedWatchWinMsgFn pfn);
/* acedRemoveWatchWinMsg
* Takes a message hook function pointer and remove it
* Returns TRUE if successfully registers the hook. Otherwise FALSE.
*
*/
很简单,移除上面注册的监控函数
BOOL acedRemoveWatchWinMsg(const AcedWatchWinMsgFn pfn);
/* acedRegisterOnIdleWinMsg
* Register a hook function to be notified when AutoCAD is on idle
* Returns TRUE if successfully registers the hook. Otherwise FALSE.
*/
以上的意思大概是,在CAD的WINDOWS 消息循环中定义一个hook,当CAD的空闲时间时,就会激活这个定义的HOOK,然后你就可以做一些处理了。
BOOL acedRegisterOnIdleWinMsg(const AcedOnIdleMsgFn pfn);
/* acedRemoveOnIdleWinMsg
* Takes a message on idle hook function pointer and remove it
* Returns TRUE if successfully registers the hook. Otherwise FALSE.
*
*/
简单,移除上面注册的监控空闲时间函数
BOOL acedRemoveOnIdleWinMsg(const AcedOnIdleMsgFn pfn);
在CAD二次开发中,HOOK技术应该还是很有用的,比如,最近,我在做一个在CAD中定义右键菜单的功能。以前已经做过一个右键菜单,用CONTEXTMENU,但不能把CAD本身的菜单给干掉,早几天看到BENTLY公司在CAD平台上做的开发,他们的右键菜单完全没有CAD的影子,所以,我下定决心,要尝试着把CAD的右键给干掉,有人说,可以自己定义CUI文件搞定,但我们的软件是要兼容低版本的CAD,所以不能用这种方法,想了想,HOOK的方法可能适合,自己试了试,感觉还行。以下是自己写的核心代码。
//pick the current selectset
BOOL HasEntityBeSelected()
{
// 如果AutoCAD关闭,则不执行任何任务。
//
if (!acdbHostApplicationServices()->workingDatabase())
return FALSE;
// 取得刚打开的实体
//
ads_name sset;
int err = acedSSGet(_T("I"), NULL, NULL, NULL, sset);
if (err != RTNORM)
{
/*acutPrintf(_T("n获取选择集错误n"));*/
return FALSE;
}
/*actrTransactionManager->startTransaction();*/
long length;
acedSSLength(sset, &length);
acedSSFree(sset);
if( length > 0 )
{
return TRUE;
}
else
{
return FALSE;
}
}
//catch the message
int CatchRClick(MSG* msg)
{
CView* pView = acedGetAcadDwgView();//获得程序主框架指针
HWND hActiveWnd = ::GetActiveWindow();
BOOL bInView = TRUE;
CPoint pt;
::GetCursorPos(&pt);
CRect rect;
::GetWindowRect( hActiveWnd , rect );
if( pt.x > rect.left &&
pt.x < rect.right &&
pt.y > rect.top &&
pt.y < rect.bottom )
{
bInView = FALSE;
}
CWnd* pMainWnd = acedGetAcadWinApp()->m_pMainWnd;
HWND hMainWnd = pMainWnd->m_hWnd;
if( hActiveWnd && hActiveWnd == hMainWnd )
{
bInView = TRUE;
}
if( msg->message == WM_RBUTTONDOWN && bInView )
{
CMenu* pMenu = NULL;
if( HasEntityBeSelected() )
{
if( pObject )
{
pMenu = pObject->GetMainMenu(); //弹出选中了实体的右键菜单
}
}
else
{
if( pDefault )
{
pMenu = pObject->GetMainMenu();//弹出未选中了实体的右键菜单
}
}
CPoint pt;
::GetCursorPos(&pt);
CRect rect;
::GetWindowRect(pView ->m_hWnd, rect );
if( pt.x > rect.left &&
pt.x < rect.right &&
pt.y > rect.top &&
pt.y < rect.bottom )
{
pMenu->TrackPopupMenu(TPM_LEFTALIGN,pt.x,pt.y, pView);//单击右键菜单时弹出菜单指针
return 1;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
// Init this application. Register your
// commands, reactors...
void InitApplication(void *pkt)
{
// NOTE: DO NOT edit the following lines.
//{{AFX_ARX_INIT
//}}AFX_ARX_INIT
// TODO: add your initialization functions
pDefault = new DefaultContextMenu(_hdllInstance);
pObject = new ObjectContextMenu(_hdllInstance);
acedRegisterFilterWinMsg( CatchRClick );
}
// Unload this application. Unregister all objects
// registered in InitApplication.
void UnloadApplication()
{
// NOTE: DO NOT edit the following lines.
//{{AFX_ARX_EXIT
//}}AFX_ARX_EXIT
// TODO: clean up your application
If( pDefault )
delete pDefault;
if( pObject )
delete pObject;
acedRegisterFilterWinMsg( CatchRClick );
}
相关文章
- 2021-09-08BIM技术丛书Revit软件应用系列Autodesk Revit族详解 [
- 2021-09-08全国专业技术人员计算机应用能力考试用书 AutoCAD2004
- 2021-08-30从零开始AutoCAD 2014中文版机械制图基础培训教程 [李
- 2021-08-30从零开始AutoCAD 2014中文版建筑制图基础培训教程 [朱
- 2021-08-30电气CAD实例教程AutoCAD 2010中文版 [左昉 等编著] 20
- 2021-08-30高等院校艺术设计案例教程中文版AutoCAD 建筑设计案例
- 2021-08-29环境艺术制图AutoCAD [徐幼光 编著] 2013年PDF下载
- 2021-08-29机械AutoCAD 项目教程 第3版 [缪希伟 主编] 2012年PDF
- 2021-08-29机械制图与AutoCAD [李志明 主编] 2014年PDF下载
- 2021-08-29机械制图与AutoCAD [陶素连,周钦河 主编] 2013年PDF下