使用钩子(Hook)实现Revit API中 PickObjects 完成按钮的触发

简介: 使用钩子(Hook)实现Revit API中 PickObjects 完成按钮的触发

在实际的Revit 二次开发项目中,经常需要与Revit 模型元素进行交互,那么除了借助于过滤器来获取对应元素之外,直接拾取元素(PickObjects 函数)也是常见的一种方式。然而在多选操作中,如果不是熟手,很容易找不到多选完成的按钮(其位置见图1,确实显得不起眼)。20200310161356167.png

图1

在Windows中,提供一种Hook机制,中文里常常被译作“钩子”或者“挂钩”,可以把Hook理解为Windows操作系统消息处理机制的一个平台;应用程序可以通过设置Hook对某个进程或窗口进行监视,即:对特定事件“挂钩”;一旦预定义特定事件发生,Windows操作系统即会向钩子hook发送通知消息,这时,应用程序可进行响应。


接下来我们来使用钩子自动实现点击多选操作中“完成”的按钮!


Step 1

首先我们在NuGet 中安装如图的工具包(MouseKeyHook);

20200310142423267.png


 Step 2

安装各种钩子;

    public static class WindowsHelper
    {
        [DllImport("user32.dll", CharSet = CharSet.None, ExactSpelling = false)]
        public static extern bool EnumChildWindows(IntPtr hwndParent, CallBack lpEnumFunc, IntPtr lParam);
        public delegate bool CallBack(IntPtr hwnd, int lParam);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpText, int nCount);
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
        [DllImport("user32.dll", EntryPoint = "SendMessageA")]
        public static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam);
    }


Step 3

注册鼠标和键盘监视事件,作者添加了一个右键的鼠标事件和一个空格的键盘事件;

        public void Subscribe()
        {
            // Note: for the application hook, use the Hook.AppEvents() instead
            m_GlobalHook = Hook.GlobalEvents();
            m_GlobalHook.KeyUp += GlobalHookKeyUpExt;
            m_GlobalHook.MouseUpExt += GlobalHookMouseUpExt;
        }
        private void GlobalHookMouseUpExt(object sender, MouseEventExtArgs e)
        {
            if (e.Button == MouseButtons.Right) { CompleteMultiSelection(); }
        }
        private void GlobalHookKeyUpExt(object sender, KeyEventArgs e)
        {
            // 32 represent Space
            if (e.KeyValue == 32) { CompleteMultiSelection(); }
        }

Step 4

获取Revit 主窗体下的所有句柄,找到“完成”按钮并发送Click消息;

        private void CompleteMultiSelection()
        {
            var rvtWindow = Autodesk.Windows.ComponentManager.ApplicationWindow;
            var list = new List<IntPtr>();
            var flag = WindowsHelper.EnumChildWindows(rvtWindow,
                       (hwnd, l) =>
                       {
                           StringBuilder windowText = new StringBuilder(200);
                           WindowsHelper.GetWindowText(hwnd, windowText, windowText.Capacity);
                           StringBuilder className = new StringBuilder(200);
                           WindowsHelper.GetClassName(hwnd, className, className.Capacity);
                           if ((windowText.ToString().Equals("完成", StringComparison.Ordinal) ||
                          windowText.ToString().Equals("Finish", StringComparison.Ordinal)) &&
                          className.ToString().Contains("Button"))
                           {
                               list.Add(hwnd);
                               return false;
                           }
                           return true;
                       }, new IntPtr(0));
            var complete = list.FirstOrDefault();
            WindowsHelper.SendMessage(complete, 245, 0, 0);
        }

Step 5

注销监视事件。

        public void Unsubscribe()
        {
            m_GlobalHook.MouseUpExt -= GlobalHookMouseUpExt;
            m_GlobalHook.KeyUp -= GlobalHookKeyUpExt;
            //It is recommened to dispose it
            m_GlobalHook.Dispose();
        }

Step 6

功能测试!


image.png


问题

运行钩子程序之后,图2的区域的按钮失效,无法关闭当前窗口,也无法实现ViewCube功能!

经多次尝试,需右击Revit模型显示区域,点击“取消”,即可恢复操作!


2020031016484678.png


参考资料:

钩子让PickObjects功力大增—BIMCoder梁老师

Revit二次开发番外篇之改变PickObjects完成按钮的触发

各个键盘按键KeyValue值


相关文章
|
7月前
|
安全 API
触发式邮件邮箱API发送邮件的步骤
触发式邮件邮箱API是自动化邮件发送的高效工具,如AokSend、Mailgun和蜂邮EDM等提供此类服务。主要步骤包括:选择服务提供商、注册获取API密钥、配置触发事件(如用户注册或下单)、编写邮件模板及调用API发送邮件。使用时注意遵循服务提供商规则,保证安全可靠性。
|
1月前
|
安全 API UED
WebSocket API 中的 close 事件是如何触发的?
【10月更文挑战第26天】close事件的触发涵盖了从正常的连接关闭到各种异常情况导致的连接中断等多种场景。通过监听close事件,开发人员可以在连接关闭时进行相应的处理,如清理资源、更新界面状态或尝试重新连接等,以确保应用程序的稳定性和良好的用户体验。
|
3月前
|
API
本地hook API MessageBoxA的masm32源代码[07-10更新]
本地hook API MessageBoxA的masm32源代码[07-10更新]
|
3月前
|
JSON API 数据格式
1api触发gitlab流水线
1api触发gitlab流水线
|
4月前
|
监控 API 数据安全/隐私保护
​邮件API触发式接口分析?邮件API接口好评榜
邮件API在企业通信和营销中至关重要,通过自动化邮件发送流程提升效率与客户满意度。本文解析邮件API触发式接口,即基于特定事件(如用户注册、购买产品)自动发送邮件的技术,能显著加快企业响应速度并增强用户体验。推荐市场上的优秀邮件API产品,包括SendGrid、Mailgun、Amazon SES、Postmark及新兴的AOKSend,它们各具特色,如高发送率、详细分析工具、灵活配置、强大的日志功能及用户友好的API接口,帮助企业根据不同需求选择最合适的邮件API解决方案。
|
6月前
|
自然语言处理 安全 API
触发邮件接口有哪些?邮件API文档
**触发邮件接口**如AokSend、Mailgun、Amazon SES、Postmark和Sendinblue是自动化企业通信的关键。这些接口在特定事件时自动发送邮件,提高效率和客户体验。例如,AokSend提供详细的API文档,支持事件触发、模板管理和多语言集成;Mailgun以灵活性著称;Amazon SES适合大规模发送;Postmark专注于事务邮件;Sendinblue则提供邮件、短信和营销自动化功能。每种服务都有示例代码展示如何使用API发送邮件。选择合适的接口能提升企业通信效率和客户满意度。
|
6月前
|
API 开发工具
企业微信SDK接口API调用-触发推送企业微信微信好友
企业微信SDK接口API调用-触发推送企业微信微信好友
|
6月前
|
Java Linux API
微信API:探究Android平台下Hook技术的比较与应用场景分析
微信API:探究Android平台下Hook技术的比较与应用场景分析
|
6月前
|
API 开发工具
企业微信api接口调用-触发企业微信推送会话列表
企业微信api接口调用-触发企业微信推送会话列表
|
6月前
|
API 开发工具
企业微信api接口调用-触发推送企业微信联系人列表
企业微信api接口调用-触发推送企业微信联系人列表