不卡视频在线观看_三级网站视频在线观看_91精品网站_国产综合一区二区

完善主體資料,免費贈送VIP會員!
* 主體類型
* 企業名稱
* 信用代碼
* 所在行業
* 企業規模
* 所在職位
* 姓名
* 所在行業
* 學歷
* 工作性質
請先選擇行業
您還可以選擇以下福利:
行業福利,領完即止!

下載app免費領取會員

NULL

ad.jpg

Revit二次開發教程:Revit API Hook 之 攔截鼠標雙擊元素事件

發布于:2019-06-22 17:55:56

網友投稿

更多

HOOK(鉤子,掛鉤)是一種實現Windows平臺下類似于中斷的機制。HOOK機制允許應用程序攔截并處理Windows消息或指定事件,當指定的消息發出后,HOOK程序就可以在消息到達目標窗口之前將其捕獲,從而得到對消息的控制權,進而可以對該消息進行處理或修改,加入我們所需的功能。鉤子按使用范圍分,可分為線程鉤子和系統鉤子,其中,系統鉤子具有相當大的功能,幾乎可以實現對所有Windows消息的攔截、處理和監控。這項技術涉及到兩個重要的API,一個是SetWindowsHookEx,安裝鉤子;另一個是UnHookWindowsHookEx,卸載鉤子。


本文使用的HOOK API技術,是指截獲系統或進程對某個API函數的調用,使得API的執行流程轉向我們指定的代碼段,從而實現我們所需的功能。Windows下的每個進程均擁有自己的地址空間,并且進程只能調用其地址空間內的函數,因此HOOK API尤為關鍵的一步是,設法將自己的代碼段注入到目標進程中,才能進一步實現對該進程調用的API進行攔截。然而微軟并沒有提供HOOK API的調用接口,這就需要開發者自己編程實現。

 一般來說,HOOK API由兩個組成部分,即實現HOOK API的DLL文件,和啟動注入的主調程序。本文采用HOOK API 技術對剪切板相關的API 函數進行攔截,從而實現對剪切板內容的監控功能,同樣使用該技術實現進程防終止功能。其中DLL文件支持HOOK API的實現,而主調客戶端程序將在初始化時把帶有HOOK API功能的DLL隨著鼠標鉤子的加載注入到目標進程中,這里的鼠標鉤子屬于系統鉤子。

下面介紹在Revit中,如何應用Hook對鼠標雙擊元素事件進行攔截。


第一步,先封裝HookBase抽象類,因所有Hook的都具有注冊、卸載邏輯,且注冊、卸載大同小易。如下

public abstract class HookBase : IHook

    {

        private static Dictionary<int, IHook> m_Hooks;

        private IntPtr m_ProcessId;

        private int m_ThreadId;

        private HookType m_HookType;

        private HookProc m_HookProc; 

        protected internal int m_HookId; 

        static HookBase(){

            m_Hooks = new Dictionary<int, IHook>();

        } 

        private HookBase(HookType hookType){

            m_HookType = hookType;

            m_HookProc = HookProc;

        } 

        protected HookBase(IntPtr processId, HookType hookType):this(hookType){

            m_ProcessId = processId;

            if (m_ProcessId == IntPtr.Zero)

            {

                m_ProcessId = HookHelper.GetCurrentProcessId();

            }

        } 

        protected HookBase(int threadId, HookType hookType):this(hookType){

            m_ThreadId = threadId;

            if (m_ThreadId == 0)

            {

                m_ThreadId = HookHelper.GetCurrentThreadId();

            }

        } 

        public void Install(){

            if (m_ThreadId != 0)

            {

                m_HookId = HookHelper.SetWindowsHookEx(m_HookType, m_HookProc, IntPtr.Zero, m_ThreadId);

            }

            else

            {

                if (m_ProcessId == IntPtr.Zero)

                {

                    return;

                }

                m_HookId = HookHelper.SetWindowsHookEx(m_HookType, m_HookProc, m_ProcessId,0);

            }


            if (m_HookId == 0)

            {

                return;

            }


            if (!m_Hooks.ContainsKey(m_HookId))

            {

                m_Hooks.Add(m_HookId, this);

            }

        } 

        public void Uninstall()

        {

            if (m_HookId == 0)

            {

                return;

            }


            var flag = HookHelper.UnhookWindowsHookEx(m_HookId);

            if (flag)

            {

                if (m_Hooks.Remove(m_HookId))

                {

                    m_HookId = 0;

                }

            }

        } 

        protected abstract int HookProc(int nCode, IntPtr wParam, IntPtr lParam);


第二步 ,因鼠標Hook分為線程鼠標Hook以及全局鼠標Hook兩種,僅注冊方式有點區別。為使用方便,將其封裝為事件注冊方式。如下

public abstract class MouseHookBase : HookBase

    {

        protected MouseHookBase(IntPtr processId)

            : base(processId, HookType.WH_MOUSE_LL)

        {


        }


        protected MouseHookBase(int threadId)

            : base(threadId, HookType.WH_MOUSE)

        {


        }

        public event HookHandler<MouseEventArgs> MouseDoubleClick;

        public event HookHandler<MouseEventArgs> MouseMove;

        public event HookHandler<MouseEventArgs> MouseDown;

        public event HookHandler<MouseEventArgs> MouseUp;


        protected override int HookProc(int nCode, IntPtr wParam, IntPtr lParam)

        {

            if (nCode < 0)

            {

                return HookHelper.CallNextHookEx(m_HookId, nCode, wParam, lParam);

            }


            var mouseMsg = (MouseMessage)wParam.ToInt32();

            var mouseHookStruct = lParam.ToStruct<MOUSEHOOKSTRUCT>();


            var button = this.GetMouseButtons(mouseMsg);


            switch (mouseMsg)

            {

                case MouseMessage.WM_LBUTTONDOWN:

                case MouseMessage.WM_RBUTTONDOWN:

                case MouseMessage.WM_MBUTTONDOWN:


                    return this.OnRaiseMouseDown(button, 1, mouseHookStruct.pt.X, mouseHookStruct.pt.Y, mouseHookStruct.mouseData);


                case MouseMessage.WM_LBUTTONUP:

                case MouseMessage.WM_MBUTTONUP:

                case MouseMessage.WM_RBUTTONUP:


                    return this.OnRaiseMouseUp(button, 1, mouseHookStruct.pt.X, mouseHookStruct.pt.Y, mouseHookStruct.mouseData);


                case MouseMessage.WM_LBUTTONDBLCLK:

                case MouseMessage.WM_RBUTTONDBLCLK:

                case MouseMessage.WM_MBUTTONDBLCLK:


                    return this.OnRaiseMouseDoubleClick(button, 2, mouseHookStruct.pt.X, mouseHookStruct.pt.Y, mouseHookStruct.mouseData);


                case MouseMessage.WM_MOUSEMOVE:


                    return this.OnRaiseMouseMove(MouseButtons.None, 0, mouseHookStruct.pt.X, mouseHookStruct.pt.Y, mouseHookStruct.mouseData);

                default:

                    return HookHelper.CallNextHookEx(m_HookId, nCode, wParam, lParam);

            }

        }


        private MouseButtons GetMouseButtons(MouseMessage mouseMsg)

        {

            MouseButtons result = MouseButtons.None;

            switch (mouseMsg)

            {

                case MouseMessage.WM_LBUTTONDBLCLK:

                case MouseMessage.WM_LBUTTONDOWN:

                case MouseMessage.WM_LBUTTONUP:

                    result = MouseButtons.Left;

                    break;

                case MouseMessage.WM_MBUTTONDBLCLK:

                case MouseMessage.WM_MBUTTONDOWN:

                case MouseMessage.WM_MBUTTONUP:

                    result = MouseButtons.Middle;

                    break;

                case MouseMessage.WM_RBUTTONDBLCLK:

                case MouseMessage.WM_RBUTTONDOWN:

                case MouseMessage.WM_RBUTTONUP:

                    result = MouseButtons.Right;

                    break;

            }

            return result;

        }


        private int OnRaiseMouseDoubleClick(MouseButtons button, int clicks, int x, int y, intdelta)

        {

            if (this.MouseDoubleClick != null)

            {

                return this.MouseDoubleClick(this, new MouseEventArgs(button, clicks, x, y, delta));

            }

            return 0;

        }


        private int OnRaiseMouseDown(MouseButtons button, int clicks, int x, int y, int delta)

        {

            if (this.MouseDown != null)

            {

                return this.MouseDown(this, new MouseEventArgs(button, clicks, x, y, delta));

            }

            return 0;

        }


        private int OnRaiseMouseUp(MouseButtons button, int clicks, int x, int y, int delta)

        {

            if (this.MouseUp != null)

            {

                return this.MouseUp(this, new MouseEventArgs(button, clicks, x, y, delta));

            }

            return 0;

        }


        private int OnRaiseMouseMove(MouseButtons button, int clicks, int x, int y, int delta)

        {

            if (this.MouseMove != null)

            {

                return this.MouseMove(this, new MouseEventArgs(button, clicks, x, y, delta));

            }

            return 0;

        }

}

第三步,依次實現線程鼠標Hook以及全局鼠標Hook.

 public class MouseHook : MouseHookBase{

        public MouseHook(int threadId = 0)

            : base(threadId)

        { 

        }

    }

    public class GlobalMouseHook : MouseHookBase

    {

        public GlobalMouseHook(IntPtr processId)

            : base(processId)

        { 

        }

 }

第四步,有了鼠標Hook,我們如果在Revit內使用并且攔截鼠標雙擊元素事件呢?我們繼續封裝一個元素監控類 ,如下:

public class ElementMonitor

    {

        private static ElementMonitor m_Instance;

        private MouseHook m_MouseHook;

        private bool m_IsMonitor;

        private UIApplication m_UIApplication;


        private ElementMonitor(UIApplication uiApp)

        {

            m_Instance = this;

            m_UIApplication = uiApp;


            m_MouseHook = new MouseHook();

            m_MouseHook.Install();


            m_MouseHook.MouseDoubleClick += OnRaiseMouseDoubleClick;

        }


        /// <summary>

        /// 靜態實例,可在入口類判斷此實例是否為null,防止重復注冊.

        /// </summary>

        public static ElementMonitor Instance

        {

            get

            {

                return m_Instance;

            }

        }


        /// <summary>

        /// 當鼠標雙擊元素時觸發此事件.

        /// </summary>

        public event HookHandler<DoubleClickElementEventArgs> DoubleClickElement;


        /// <summary>

        /// 注冊元素監控,并指定是否立即監控.

        /// </summary>

        public static void Register(UIApplication uiApp, bool immediatelyMonitor = true)

        {

            if (uiApp == null)

            {

                throw new ArgumentNullException(nameof(uiApp));

            }


            new ElementMonitor(uiApp)

            {

                m_IsMonitor = immediatelyMonitor

            };

        }


        /// <summary>

        /// 注冊元素監控,并指定是否立即監控.

        /// </summary>

        public static void Register(UIControlledApplication uiControllApp, bool immediatelyMonitor = true)

        {

            if (uiControllApp == null)

            {

                throw new ArgumentNullException(nameof(uiControllApp));

            }


            var flag = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod;


            var uiApp = (UIApplication)uiControllApp.GetType().InvokeMember("getUIApplication", flag, Type.DefaultBinder, uiControllApp, null);


            Register(uiApp, immediatelyMonitor);

        }


        /// <summary>

        /// 返回1,則攔截鼠標消息,返回0則傳遞給真正消息接收者.

        /// </summary>

        private int OnRaiseMouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)

        {

            if (!m_IsMonitor || e.Button != MouseButtons.Left || e.Clicks != 2)

            {

                return 0;

            }


            var uiDoc = m_UIApplication.ActiveUIDocument;


            if (uiDoc == null)

            {

                return 0;

            }


            var elemIds = uiDoc.Selection.GetElementIds();


            if (elemIds.Count == 1)

            {

                var elem = uiDoc.Document.GetElement(elemIds.First());


                if (elem == null)

                {

                    return 0;

                } 

                if (this.DoubleClickElement == null)

                {

                    return 0;

                } 

                return this.DoubleClickElement(this, new DoubleClickElementEventArgs(elem));

            }


            return 0;

        }

    }

第五步,調用測試,如下

[Transaction(TransactionMode.Manual)]

    public class MouseHookTest : IExternalCommand

    {

        Result IExternalCommand.Execute(ExternalCommandData commandData, ref string message, ElementSet elements)

        {

            if (ElementMonitor.Instance == null)

            {

                ElementMonitor.Register(commandData.Application);

            }


            ElementMonitor.Instance.DoubleClickElement += OnRaiseDoubleClickElement;


            return Result.Succeeded;

        }


        private int OnRaiseDoubleClickElement(object sender, DoubleClickElementEventArgs e)

        {

            if (e.Element == null)

            {

                return 0;

            }


            System.Windows.Forms.MessageBox.Show(string.Format("雙擊擊元素Id: {0}", e.Element.Id)); 

            return 1;


        }

    }



本文版權歸腿腿教學網及原創作者所有,未經授權,謝絕轉載。

未標題-1.jpg

上一篇:Revit二次開發教程:Revit族參數可見性設置

下一篇:Revit二次開發教程:注冊Revit插件

60acb4e0ef112.png
不卡视频在线观看_三级网站视频在线观看_91精品网站_国产综合一区二区

      9000px;">

          蜜臀99久久精品久久久久久软件| 一区二区高清视频在线观看| 蜜臀久久99精品久久久久宅男 | 91麻豆精品国产综合久久久久久| 国产一区二区在线观看视频| av成人老司机| 日韩午夜激情av| 亚洲精品欧美专区| 国产成人亚洲综合a∨婷婷| 91官网在线免费观看| 日韩欧美国产1| 亚洲一区二区三区小说| 成人午夜精品在线| 日韩一区二区视频| 亚洲午夜电影在线观看| 国产二区国产一区在线观看| 91精品国产综合久久久蜜臀图片 | 日韩av一级片| 日本伦理一区二区| 国产精品福利一区二区三区| 黄色成人免费在线| 91精品国产色综合久久不卡电影| 欧美久久久久久久久中文字幕| 欧美性欧美巨大黑白大战| 国产色综合久久| 极品美女销魂一区二区三区 | 亚洲国产你懂的| 97精品视频在线观看自产线路二| 色8久久精品久久久久久蜜 | 成人福利在线看| 精品国产91洋老外米糕| 亚洲第一在线综合网站| 在线亚洲精品福利网址导航| 国产精品国产馆在线真实露脸| 日韩欧美电影一区| 天天操天天干天天综合网| 久久新电视剧免费观看| 欧美丝袜丝交足nylons图片| 国产精品自产自拍| 一级精品视频在线观看宜春院| 波多野结衣中文字幕一区| 亚洲午夜电影在线观看| 久久久久国产成人精品亚洲午夜| 久久国产综合精品| 日韩毛片一二三区| 久久综合av免费| 欧美中文字幕一二三区视频| 国产精品资源在线看| 日韩精品自拍偷拍| 丝袜脚交一区二区| 日韩欧美在线不卡| 国产主播一区二区| 国产精品久久国产精麻豆99网站 | 麻豆91免费看| 久久久国产精品不卡| 国产91露脸合集magnet| 国产精品久久看| 色婷婷综合久久| 日韩高清中文字幕一区| 精品免费国产一区二区三区四区| 亚洲色图19p| 欧美精品久久一区二区三区| 国内精品久久久久影院色| 综合网在线视频| 欧美肥妇bbw| 国产大片一区二区| 亚洲女子a中天字幕| 日韩一区二区三区免费观看| 国产精品亚洲专一区二区三区 | 国产一区二区在线视频| 日本一区二区三区dvd视频在线| 日本网站在线观看一区二区三区| av一区二区久久| 日韩制服丝袜av| 国产精品欧美一级免费| 欧美日韩精品一二三区| 成人网在线播放| 午夜av一区二区三区| 国产清纯白嫩初高生在线观看91| 奇米一区二区三区av| 国产精品成人免费在线| 日韩欧美资源站| 97精品国产露脸对白| 美女在线视频一区| 亚洲日本在线a| 国产欧美一区二区精品秋霞影院 | 在线欧美小视频| 老司机免费视频一区二区| 亚洲色图色小说| 久久久不卡网国产精品二区| 69p69国产精品| 不卡电影一区二区三区| 国产资源在线一区| 日韩av一区二区三区四区| 555夜色666亚洲国产免| 91麻豆精品国产91久久久资源速度| 精品影院一区二区久久久| 久久国产精品色| 国产乱色国产精品免费视频| 高清在线观看日韩| 高清不卡在线观看| 色综合 综合色| 在线成人午夜影院| 欧美xxx久久| 国产精品久久久久一区二区三区| 欧美成人aa大片| 亚洲国产高清在线观看视频| 亚洲综合激情网| 日韩经典一区二区| 91一区二区在线观看| 色婷婷激情一区二区三区| 久久99国产精品久久| 国产精品不卡在线观看| 国产亚洲精品超碰| 国产女人18水真多18精品一级做| av一区二区久久| 99re热这里只有精品视频| av亚洲精华国产精华精华| 成人福利视频网站| 不卡视频免费播放| 99视频一区二区| 色综合天天综合网国产成人综合天| 亚洲一区二区高清| 亚洲成在人线免费| 亚洲国产综合人成综合网站| 无码av中文一区二区三区桃花岛| 久久久亚洲综合| 亚洲国产精品t66y| 亚洲美女淫视频| 亚洲一区视频在线观看视频| 性欧美疯狂xxxxbbbb| 日本中文字幕一区二区有限公司| 国产精品久久久久天堂| 亚洲久草在线视频| 午夜视黄欧洲亚洲| 久久爱www久久做| 久久国产生活片100| 国产成人激情av| 一本到不卡免费一区二区| 精品婷婷伊人一区三区三| 欧美一区二区三区免费观看视频| 99国产欧美久久久精品| 欧美视频在线一区二区三区| 欧美一级久久久| 国产精品女主播av| 亚洲免费av观看| 久久99九九99精品| 色综合色综合色综合| 91精品国产高清一区二区三区蜜臀| 色av一区二区| 精品久久久久一区二区国产| 国产精品久久久久久久久晋中| 日韩一区二区影院| 日韩毛片精品高清免费| 亚洲高清视频中文字幕| 国产一区二区久久| 在线免费观看日本欧美| 国产色91在线| 天天综合网天天综合色| 99久久国产综合精品色伊| 精品国一区二区三区| 亚洲美女一区二区三区| 国产精品1024| 欧美久久婷婷综合色| 亚洲欧洲在线观看av| 狠狠久久亚洲欧美| 欧美这里有精品| 国产精品久久久久久久浪潮网站| 欧洲视频一区二区| 国产精品成人免费精品自在线观看| 亚洲免费在线播放| 在线观看免费视频综合| 亚洲国产精品综合小说图片区| 久久疯狂做爰流白浆xx| 日韩亚洲欧美成人一区| 日韩综合一区二区| 欧美大片国产精品| 国产盗摄一区二区| 国产精品白丝在线| 欧美午夜精品久久久久久超碰| 日本一区二区三区dvd视频在线| 亚洲成av人在线观看| 欧美三级乱人伦电影| 日韩精品电影一区亚洲| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 色综合天天综合网天天看片| 久久亚洲精品国产精品紫薇| 蜜臀99久久精品久久久久久软件| 日本va欧美va精品| 欧美日韩一区二区三区免费看 | 日本欧美在线观看| 欧洲精品中文字幕| 亚洲激情综合网| 色乱码一区二区三区88| 国产精品久久三区| 成人精品视频网站| 中文字幕第一区| av中文一区二区三区| 国产精品久久久久久一区二区三区| 亚洲精品国产一区二区精华液|